You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by tr...@apache.org on 2013/08/10 07:53:54 UTC

svn commit: r1512568 [9/39] - in /jackrabbit/commons/filevault/trunk: ./ parent/ vault-cli/ vault-cli/src/ vault-cli/src/main/ vault-cli/src/main/appassembler/ vault-cli/src/main/assembly/ vault-cli/src/main/java/ vault-cli/src/main/java/org/ vault-cli...

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/ItemFilterSet.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/ItemFilterSet.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/ItemFilterSet.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/ItemFilterSet.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.api;
+
+import java.util.List;
+
+import javax.jcr.Item;
+import javax.jcr.RepositoryException;
+
+/**
+ * The item filter set holds a set of item filters each attributes as include
+ * or exclude filter. The evaluation of the set allows included items and
+ * rejects excluded items.
+ * <p/>
+ * Additionally it contains a "root" path for which the filters are evaluated.
+ * if an item has not the node addressed by the root path as ancestor, it is
+ * always excluded.
+ *
+ */
+public class ItemFilterSet extends FilterSet<ItemFilter> {
+
+    /**
+     * The include all item filter set
+     */
+    public static final ItemFilterSet INCLUDE_ALL =
+            (ItemFilterSet) new ItemFilterSet().addInclude(ItemFilter.ALL).seal();
+
+    /**
+     * The exclude all item filter set
+     */
+    public static final ItemFilterSet EXCLUDE_ALL =
+            (ItemFilterSet) new ItemFilterSet().addExclude(ItemFilter.ALL).seal();
+
+
+    /**
+     * Default constructor. initializes the root path to "/"
+     */
+    public ItemFilterSet() {
+        super();
+    }
+
+    /**
+     * Creates a new item filter set and sets the respective root path
+     * @param root path
+     */
+    public ItemFilterSet(String root) {
+        super(root);
+    }
+
+    /**
+     * Evaluates the filters if this set does {@link #covers(String) cover} the
+     * given item. otherwise <code>false</code> is returned.
+     * The result of the evaluation is the polarity of the last matched item.
+     * If no filter matches it returns <code>true</code>
+     * if the first filter is an exclude filter or if no filter is defined;
+     * <code>false</code> if the first filter is an include filter.
+     *
+     * @param item the item to check
+     * @param depth the depth to check
+     * @return <code>true</code> if this set matches the item
+     * @throws RepositoryException if an error occurs.
+     */
+    public boolean contains(Item item, int depth) throws RepositoryException {
+        return contains(item, null, depth);
+    }
+    /**
+     * Evaluates the filters if this set does {@link #covers(String) cover} the
+     * given item. otherwise <code>false</code> is returned.
+     * The result of the evaluation is the polarity of the last matched item.
+     * If no filter matches it returns <code>true</code>
+     * if the first filter is an exclude filter or if no filter is defined;
+     * <code>false</code> if the first filter is an include filter.
+     *
+     * @param item the item to check
+     * @param path of the item or <code>null</code>
+     * @param depth the depth to check
+     * @return <code>true</code> if this set matches the item
+     * @throws RepositoryException if an error occurs.
+     */
+    public boolean contains(Item item, String path, int depth) throws RepositoryException {
+        if (path == null) {
+            path = item.getPath();
+        }
+        if (!covers(path)) {
+            return false;
+        }
+        List<Entry<ItemFilter>> entries = getEntries();
+        if (entries.isEmpty()) {
+            return true;
+        } else {
+            boolean result = !entries.get(0).include;
+            for (Entry<ItemFilter> entry: entries) {
+                if (entry.filter.matches(item, depth)) {
+                    result = entry.include;
+                }
+            }
+            return result;
+        }
+    }
+
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/NodeNameList.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/NodeNameList.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/NodeNameList.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/NodeNameList.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.api;
+
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.ListIterator;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <code>SiblingNames</code>...
+ */
+public class NodeNameList {
+
+    /**
+     * default logger
+     */
+    private static final Logger log = LoggerFactory.getLogger(NodeNameList.class);
+
+    private final LinkedHashSet<String> names = new LinkedHashSet<String>();
+
+    public void addName(String name) {
+        names.add(name);
+    }
+
+    public boolean contains(String name) {
+        return names.contains(name);
+    }
+
+    public LinkedHashSet<String> getNames() {
+        return names;
+    }
+
+    public boolean needsReorder(Node parent) throws RepositoryException {
+        // could perform more comprehensive check
+        return names.size() > 1 && parent.getPrimaryNodeType().hasOrderableChildNodes();
+    }
+
+    public boolean restoreOrder(Node parent) throws RepositoryException {
+        // assume needsReorder check is performed
+        // quick check if node is checked out
+        if (!parent.isCheckedOut()) {
+            log.warn("Unable to restore order of a checked-in node: " + parent.getPath());
+            return false;
+        }
+        int size = names.size();
+        String last = null;
+        ArrayList<String> list = new ArrayList<String>(names);
+        ListIterator<String> iter = list.listIterator(size);
+        while (iter.hasPrevious()) {
+            String prev = iter.previous();
+            if (parent.hasNode(prev)) {
+                log.debug("ordering {} before {}", prev, last);
+                try {
+                    parent.orderBefore(prev, last);
+                } catch (Exception e) {
+                    // probably an error in jcr2spi
+                    String path = parent.getPath() + "/" + prev;
+                    log.warn("Ignoring unexpected error during reorder of {}: {}", path, e.toString());
+                }
+                last = prev;
+            }
+        }
+        return true;
+    }
+
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/NodeTypesCollector.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/NodeTypesCollector.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/NodeTypesCollector.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/NodeTypesCollector.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.api;
+
+import java.util.Set;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+/**
+ * <code>NodeTypesCollector</code>...
+ */
+public interface NodeTypesCollector {
+
+    /**
+     * Returns the node types used in the aggregates (so far).
+     * @return node types
+     */
+    Set<String> getNodeTypes();
+
+    /**
+     * Add the primary and mixin node types of that node to the internal set
+     * of used node types.
+     * @param node the node
+     * @throws RepositoryException if an error occurs
+     */
+    void addNodeTypes(Node node) throws RepositoryException;
+
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/PathFilter.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/PathFilter.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/PathFilter.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/PathFilter.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.api;
+
+/**
+ * The item filter is used to include or exclude a set of paths.
+ * It is usually part of a {@link PathFilterSet}.
+ *
+ */
+public interface PathFilter extends Filter {
+
+    /**
+     * The "Catch all" item filter.
+     */
+    public static final PathFilter ALL = new PathFilter() {
+
+        /**
+         * Returns always <code>true</code>
+         */
+        public boolean matches(String path) {
+            return true;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void dump(DumpContext ctx, boolean isLast) {
+            ctx.println(isLast, "ALL");
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public boolean isAbsolute() {
+            return true;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public PathFilter translate(PathMapping mapping) {
+            return this;
+        }
+    };
+
+    /**
+     * The "Miss all" item filter.
+     */
+    public static final PathFilter NONE = new PathFilter() {
+
+        /**
+         * Returns always <code>false</code>
+         */
+        public boolean matches(String path) {
+            return false;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void dump(DumpContext ctx, boolean isLast) {
+            ctx.println(isLast, "NONE");
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public boolean isAbsolute() {
+            return true;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public PathFilter translate(PathMapping mapping) {
+            return this;
+        }
+    };
+
+    /**
+     * Checks if the given path matches this filters criteria.
+     *
+     * @param path the path to check
+     * @return <code>true</code> if this filter matches the criteria;
+     *         <code>false</code> otherwise.
+     */
+    boolean matches(String path);
+
+    /**
+     * Checks if the pattern is absolute, i.e. does not start with a wildcard.
+     * @return <code>true</code> if pattern is absolute
+     */
+    boolean isAbsolute();
+
+    /**
+     * Translates this path filter with the given mapping. Note that only absolute filters can be translated.
+     * @param mapping the mapping to apply
+     * @return the new filter
+     * @since 2.4.10
+     */
+    PathFilter translate(PathMapping mapping);
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/PathFilterSet.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/PathFilterSet.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/PathFilterSet.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/PathFilterSet.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.api;
+
+import java.util.List;
+
+/**
+ * The path filter set holds a set of path filters each attributes as include
+ * or exclude filter. The evaluation of the set allows included paths and
+ * rejects excluded paths.
+ * <p/>
+ * Additionally it contains a "root" path for which the filters are evaluated.
+ * if an item has not the node addressed by the root path as ancestor, it is
+ * always excluded.
+ *
+ */
+public class PathFilterSet extends FilterSet<PathFilter> {
+
+    /**
+     * The include all item filter set
+     */
+    public static final PathFilterSet INCLUDE_ALL =
+            (PathFilterSet) new PathFilterSet().addInclude(PathFilter.ALL).seal();
+
+    /**
+     * The exclude all item filter set
+     */
+    public static final PathFilterSet EXCLUDE_ALL =
+            (PathFilterSet) new PathFilterSet().addExclude(PathFilter.ALL).seal();
+
+
+    /**
+     * specifies if only relative patters are included in this filter ser
+     */
+    private boolean onlyRelativePatterns;
+
+    /**
+     * Default constructor. initializes the root path to "/"
+     */
+    public PathFilterSet() {
+        super();
+    }
+
+    /**
+     * Creates a new path filter set and sets the respective root path
+     * @param root path
+     */
+    public PathFilterSet(String root) {
+        super(root);
+    }
+
+    /**
+     * Evaluates the filters if this set does {@link #covers(String) cover} the
+     * given item. otherwise <code>false</code> is returned.
+     * The result of the evaluation is the polarity of the last matched path.
+     * If no filter matches it returns <code>true</code>
+     * if the first filter is an exclude filter or if no filter is defined;
+     * <code>false</code> if the first filter is an include filter.
+     *
+     * @param path the path to check
+     * @return <code>true</code> if this set matches the item
+     */
+    public boolean contains(String path) {
+        if (!covers(path)) {
+            return false;
+        }
+        List<Entry<PathFilter>> entries = getEntries();
+        if (entries.isEmpty()) {
+            return true;
+        } else {
+            boolean result = !entries.get(0).include;
+            for (Entry<PathFilter> entry: entries) {
+                if (entry.filter.matches(path)) {
+                    result = entry.include;
+                }
+            }
+            return result;
+        }
+    }
+
+    @Override
+    public FilterSet seal() {
+        if (!isSealed()) {
+            super.seal();
+            onlyRelativePatterns = true;
+            for (Entry<PathFilter> entry: getEntries()) {
+                if (!entry.include || entry.filter.isAbsolute()) {
+                    onlyRelativePatterns = false;
+                    break;
+                }
+            }
+        }
+        return this;
+    }
+
+
+    /**
+     * Translates this path filter with the given mapping. Note that only absolute filters can be translated.
+     * @param mapping the mapping to apply
+     * @return the new filter
+     * @since 2.4.10
+     */
+    public PathFilterSet translate(PathMapping mapping) {
+        if (mapping == null) {
+            return this;
+        }
+        PathFilterSet mapped = new PathFilterSet(mapping.map(getRoot()));
+        mapped.setImportMode(getImportMode());
+        for (Entry<PathFilter> e: getEntries()) {
+            if (e.isInclude()) {
+                mapped.addInclude(e.getFilter().translate(mapping));
+            } else {
+                mapped.addExclude(e.getFilter().translate(mapping));
+            }
+        }
+        mapped.seal();
+        return mapped;
+    }
+
+    /**
+     * Checks if this path filter set only contains entries that are relative
+     * include patterns, eg: ".* /foo.*". in this case the aggregator will use a
+     * different strategy when providing non matching leave nodes.
+     * @return <code>true</code> if only contains relative patterns
+     */
+    public boolean hasOnlyRelativePatterns() {
+        seal();
+        return onlyRelativePatterns;
+    }
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/PathMapping.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/PathMapping.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/PathMapping.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/PathMapping.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.vault.fs.api;
+
+/**
+ * Provides an interface for a general path mapping.
+ *
+ * @since 2.4.10
+ */
+public interface PathMapping {
+
+    /**
+     * Implements an identity mapping
+     */
+    PathMapping IDENTITY = new PathMapping() {
+        public String map(String path) {
+            return path;
+        }
+    };
+
+    /**
+     * Maps the given path to a new location.
+     * @param path the path
+     * @return the mapped path.
+     */
+    String map(String path);
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/ProgressTrackerListener.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/ProgressTrackerListener.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/ProgressTrackerListener.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/ProgressTrackerListener.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.api;
+
+/**
+ * A <code>ProgressTrackerListener</code> can be provided by clients to
+ * receive messages and errors during operations.
+ */
+public interface ProgressTrackerListener {
+
+    /**
+     * Is called when a message is received.
+     * @param mode message mode
+     * @param action action
+     * @param path path or message the action was performed on
+     */
+    void onMessage(Mode mode, String action, String path);
+
+    /**
+     * Is called when an error is received.
+     * @param mode message mode
+     * @param path path or message
+     * @param e error
+     */
+    void onError(Mode mode, String path, Exception e);
+
+    /**
+     * Message mode
+     */
+    enum Mode {
+        
+        /**
+         * Argument represents a generic text.
+         */
+        TEXT,
+
+        /**
+         * Argument represents a path.
+         */
+        PATHS
+    }
+
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/RepositoryAddress.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/RepositoryAddress.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/RepositoryAddress.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/RepositoryAddress.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,361 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.api;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.BitSet;
+
+import javax.jcr.Credentials;
+import javax.jcr.SimpleCredentials;
+
+/**
+ * The repository address locates a jcr repository in with a URI representation.
+ * It is composed out of a uri and accepts the following formats:
+ *
+ * <ul>
+ * <li> scheme://host:port/
+ * <li> scheme://host:port/prefix
+ * <li> scheme://host:port/prefix/workspace
+ * <li> scheme://host:port/prefix/workspace/jcr_root/path
+ * <ul>
+ */
+public class RepositoryAddress {
+
+    /**
+     * the (virtual) jcr root. 
+     */
+    public final static String JCR_ROOT = "/jcr:root";
+
+    /**
+     * the final uri
+     */
+    private final URI uri;
+
+    /**
+     * the specific part (uri up to excluding the workspace segment)
+     */
+    private final URI specific;
+
+    /**
+     * the workspace or null
+     */
+    private final String workspace;
+
+    /**
+     * the path
+     */
+    private final String path;
+
+    /**
+     * Creates a new default repository address.
+     * @param uri the uri
+     * @throws URISyntaxException if the uri is not valid
+     */
+    public RepositoryAddress(String uri) throws URISyntaxException {
+        this(new URI(uri));
+    }
+
+    /**
+     * Creates a new default repository address.
+     * @param uri the uri
+     * @throws URISyntaxException if the uri is not valid
+     */
+    public RepositoryAddress(URI uri) throws URISyntaxException {
+        // decode uri
+        String path = uri.getPath();
+        String workspace;
+        String prefix = "/";
+        String localPath = "/";
+
+        if (path.length() == 0 || path.equals("/")) {
+            workspace = "-";
+            localPath = "/";
+        } else if (!uri.isAbsolute()) {
+            // fix format: /wsp/path
+            int idx1 = path.indexOf('/', 1);
+            if (idx1 < 0) {
+                workspace = path.substring(1);
+            } else {
+                workspace = path.substring(1, idx1);
+                localPath = path.substring(idx1);
+            }
+        } else {
+            if (path.charAt(path.length() -1) != '/') {
+                path = path + "/";
+            }
+            int idx1 = -1;
+            int idx2 = 0;
+            int idx3 = path.indexOf('/', 1);
+            while (idx3 > 0) {
+                String segment = path.substring(idx2, idx3);
+                if (segment.equals(JCR_ROOT)) {
+                    break;
+                }
+                idx1 = idx2;
+                idx2 = idx3;
+                idx3 = path.indexOf('/', idx3 + 1);
+            }
+            if (idx3 < 0) {
+                // no jcr_root found
+                // special case for rmi backward compatibility
+                if (uri.getScheme() != null && uri.getScheme().equals("rmi")) {
+                    idx1 = path.indexOf('/', 1);
+                    idx2 = path.indexOf('/', idx1 + 1);
+                    if (idx2 < 0) {
+                        workspace = "-";
+                        prefix = path.substring(0, idx1);
+                        localPath = "/";
+                    } else {
+                        workspace = path.substring(idx1 + 1, idx2);
+                        prefix = path.substring(0, idx1);
+                        int end = path.length();
+                        if (end != idx2 + 1) {
+                            end--;
+                        }
+                        localPath = path.substring(idx2, end);
+                    }
+                } else {
+                    workspace = idx1 < 0 ? "-" : path.substring(idx1+1,idx2);
+                    prefix = idx1 <= 0 ? "/" : path.substring(0, idx1);
+                    localPath = "/";
+                }
+            } else {
+                workspace = path.substring(idx1 + 1, idx2);
+                prefix = path.substring(0, idx1);
+                int end = path.length();
+                if (end - idx3 > 1) {
+                    end--;
+                }
+                localPath = path.substring(idx3, end);
+            }
+        }
+        // sanitize HTTP address (probably wrong place)
+        if (uri.getScheme() != null && uri.getScheme().startsWith("http")) {
+            if (prefix.equals("/") || prefix.equals("/crx")) {
+                prefix = "/crx/server";
+                workspace = "-";
+            }
+        }
+        if (prefix.length() == 0) {
+            prefix = "/";
+        }
+        this.path = localPath;
+        this.workspace = workspace;
+        this.specific = uri.resolve(prefix);
+        StringBuffer buf = new StringBuffer(specific.toString());
+        if (buf.charAt(buf.length() - 1) != '/') {
+            buf.append('/');
+        }
+        buf.append(workspace);
+        buf.append(JCR_ROOT);
+        if (!localPath.equals("/")) {
+            buf.append(escapePath(localPath));
+        }
+        this.uri = new URI(buf.toString());
+    }
+
+    /**
+     * Private constructor that sets all fields.
+     * @param uri the address uri
+     * @param specific the specific uri
+     * @param workspace the workspace
+     * @param path the path
+     */
+    private RepositoryAddress(URI uri, URI specific, String workspace, String path) {
+        this.uri = uri;
+        this.specific = specific;
+        this.workspace = workspace;
+        this.path = path;
+    }
+
+
+    /**
+     * Returns the uri of this address
+     * @return the uri of this address
+     */
+    public URI getURI() {
+        return uri;
+    }
+
+    /**
+     * Returns a new repository address with the given path.
+     * @param path the path to include in the new address
+     * @return a new repository address
+     */
+    public RepositoryAddress resolve(String path) {
+        if (path == null || path.length() == 0 || path.equals(".") || path.equals("./")) {
+            return this;
+        }
+        StringBuffer newPath = new StringBuffer(specific.getPath());
+        newPath.append("/");
+        newPath.append(workspace);
+        newPath.append(JCR_ROOT);
+        if (path.charAt(0) != '/') {
+            if (this.path.endsWith("/")) {
+                path = this.path + path;
+            } else {
+                path = this.path + "/" + path;
+            }
+        }
+        newPath.append(escapePath(path));
+        URI uri = specific.resolve(newPath.toString());
+        return new RepositoryAddress(uri, specific, workspace, path);
+    }
+
+    /**
+     * Returns the name of the workspace or <code>null</code> if the default
+     * workspace is used.
+     * @return the name of the workspace or <code>null</code>
+     */
+    public String getWorkspace() {
+        return "-".equals(workspace) ? null : workspace;
+    }
+
+    /**
+     * Returns the specific part of the uri, i.e. the part that is used to
+     * actually connect to the repository
+     * @return the specific part
+     */
+    public URI getSpecificURI() {
+        return specific;
+    }
+
+    /**
+     * Returns the path to a repository item. If not explicit path is specified
+     * by this address the root path '/' is returned.
+     * @return the path to a repository item.
+     */
+    public String getPath() {
+        return path;
+    }
+
+    /**
+     * Returns JCR credentials from the URI or <code>null</code> if no user info
+     * is specified.
+     * @return the creds
+     */
+    public Credentials getCredentials() {
+        String userinfo = uri.getUserInfo();
+        if (userinfo == null) {
+            return null;
+        } else {
+            int idx = userinfo.indexOf(':');
+            if (idx < 0) {
+                return new SimpleCredentials(userinfo, new char[0]);
+            } else {
+                return new SimpleCredentials(
+                        userinfo.substring(0, idx),
+                        userinfo.substring(idx+1).toCharArray());
+            }
+        }
+
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return same as {@link #getURI() getURI().toString()}
+     */
+    public String toString() {
+        return getURI().toString();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public int hashCode() {
+        return getURI().hashCode();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof RepositoryAddress) {
+            return getURI().equals(((RepositoryAddress) obj).getURI());
+        }
+        return false;
+    }
+
+    private static BitSet URISaveEx;
+
+    static {
+        URISaveEx = new BitSet(256);
+        int i;
+        for (i = 'a'; i <= 'z'; i++) {
+            URISaveEx.set(i);
+        }
+        for (i = 'A'; i <= 'Z'; i++) {
+            URISaveEx.set(i);
+        }
+        for (i = '0'; i <= '9'; i++) {
+            URISaveEx.set(i);
+        }
+        URISaveEx.set('-');
+        URISaveEx.set('_');
+        URISaveEx.set('.');
+        URISaveEx.set('!');
+        URISaveEx.set('~');
+        URISaveEx.set('*');
+        URISaveEx.set('\'');
+        URISaveEx.set('(');
+        URISaveEx.set(')');
+        URISaveEx.set('/');
+    }
+
+    private static final char[] hexTable = "0123456789abcdef".toCharArray();
+
+
+    /**
+     * Does an URL encoding of the <code>string</code> using the
+     * <code>escape</code> character. The characters that don't need encoding
+     * are those defined 'unreserved' in section 2.3 of the 'URI generic syntax'
+     * RFC 2396, but without the escape character. If <code>isPath</code> is
+     * <code>true</code>, additionally the slash '/' is ignored, too.
+     *
+     * @param string the string to encode.
+     * @return the escaped string
+     * @throws NullPointerException if <code>string</code> is <code>null</code>.
+     */
+    private static String escapePath(String string) {
+        try {
+            byte[] bytes = string.getBytes("utf-8");
+            StringBuffer out = new StringBuffer(bytes.length);
+            for (byte aByte : bytes) {
+                int c = aByte & 0xff;
+                if (URISaveEx.get(c) && c != '%') {
+                    out.append((char) c);
+                } else {
+                    out.append('%');
+                    out.append(hexTable[(c >> 4) & 0x0f]);
+                    out.append(hexTable[(c) & 0x0f]);
+                }
+            }
+            return out.toString();
+        } catch (UnsupportedEncodingException e) {
+            throw new InternalError(e.toString());
+        }
+    }
+
+
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/RepositoryFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/RepositoryFactory.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/RepositoryFactory.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/RepositoryFactory.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.api;
+
+import java.util.Set;
+
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+
+/**
+ * <code>RepositoryProvider</code>...
+ */
+public interface RepositoryFactory {
+
+    public Set<String> getSupportedSchemes();
+
+    public Repository createRepository(RepositoryAddress address)
+            throws RepositoryException;
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/SerializationType.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/SerializationType.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/SerializationType.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/SerializationType.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.api;
+
+/**
+ * Provides a simple enumeration of possible serialization types.
+ *
+ */
+public enum SerializationType {
+
+    /**
+     * specifies that the source type is not known
+     */
+    UNKOWN("x-vaultfs/unknown", "application/octet-stream"),
+
+    /**
+     * specifies that the source type is not serializable
+     */
+    NONE("x-vaultfs/none", "application/octet-stream"),
+
+    /**
+     * specifies that the source is XML but the type not known
+     */
+    XML_GENERIC("xml/generic", "text/xml"),
+
+    /**
+     * specifies that the source is a docview serialization
+     */
+    XML_DOCVIEW("xml/docview", "text/xml"),
+
+    /**
+     * specifies that the source is a compact node type definition
+     */
+    CND("text/cnd", "text/cnd"),
+
+    /**
+     * specifies that the source is generic data.
+     */
+    GENERIC("x-jcrfs/binary", "application/octet-stream");
+
+    /**
+     * the string representation
+     */
+    private final String name;
+
+    /**
+     * the content type of the serialization
+     */
+    private final String contentType;
+
+    /**
+     * Creates a new serialization type
+     * @param name the (debug) name of the type
+     * @param contentType the default content type
+     */
+    private SerializationType(String name, String contentType) {
+        this.name = name;
+        this.contentType = contentType;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString() {
+        return name;
+    }
+
+    /**
+     * Returns the name
+     * @return the name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the content type of this serialization type
+     * @return the content type
+     */
+    public String getContentType() {
+        return contentType;
+    }
+
+    /**
+     * Returns the serialization type with the given name
+     * @param name the name to find
+     * @return the serialization type or null
+     */
+    public static SerializationType fromName(String name) {
+        for (SerializationType s: SerializationType.values()) {
+            if (s.name.equals(name)) {
+                return s;
+            }
+        }
+        return null;
+    }
+
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/SimplePathMapping.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/SimplePathMapping.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/SimplePathMapping.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/SimplePathMapping.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.vault.fs.api;
+
+/**
+ * Implements a simple path mapping that strips and prefixes a path.
+ * @since 2.4.10
+ */
+public class SimplePathMapping implements PathMapping {
+
+    private final String strip;
+
+    private final String root;
+
+    /**
+     * Create a simple path mapping.
+     * @param strip the string to strip from the beginning of the path
+     * @param root the prefix to add to the path.
+     */
+    public SimplePathMapping(String strip, String root) {
+        this.strip = strip;
+        this.root = root;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String map(String path) {
+        if (path.startsWith(strip)) {
+            StringBuilder b = new StringBuilder(root);
+            b.append(path.substring(strip.length()));
+            return b.toString();
+        } else {
+            return path;
+        }
+    }
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFile.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFile.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFile.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFile.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.api;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * <code>VaultFile</code>...
+ */
+public interface VaultFile extends Dumpable {
+    /**
+     * Returns the os path
+     * @return the os path.
+     */
+    String getPath();
+
+    String getRepoRelPath();
+
+    String getAggregatePath();
+
+    /**
+     * Returns the name of this file.
+     * @return the name of this file.
+     */
+    String getName();
+
+    /**
+     * Returns the underlying artifact for this os file. If this file represents
+     * the <em>Meta-Directory</em> <code>null</code> is returned.
+     * @return the artifact or <code>null</code>.
+     */
+    Artifact getArtifact();
+
+    /**
+     * Checks if this file is a directory.
+     * @return <code>true</code> if this file is a directory.
+     */
+    boolean isDirectory();
+
+    /**
+     * Checks if this file is transient. a file is transient if it's only used
+     * as hierarchical node for a deeper 'real' file. i.e.
+     * @return <code>true</code> if this file is transient
+     */
+    boolean isTransient();
+
+    /**
+     * Returns the parent file or <code>null</code> if this is the root file.
+     * @return the parent file.
+     * @throws IOException if an I/O error occurs.
+     * @throws RepositoryException if a repository error occurs.
+     */
+    VaultFile getParent() throws IOException, RepositoryException;
+
+    /**
+     * Returns the artifacts node of this file or <code>null</code> if it's
+     * transient
+     * @return the artifacts node
+     */
+    Aggregate getAggregate();
+
+    /**
+     * Returns the aggregate that controls this file.
+     * @return the artifacts node
+     */
+    Aggregate getControllingAggregate();
+
+    /**
+     * Returns the child with the given name or <code>null</code>
+     * @param name the name of the child
+     * @return the child or <code>null</code>
+     * @throws RepositoryException if an error occurs
+     */
+    VaultFile getChild(String name) throws RepositoryException;
+
+    /**
+     * Returns a collection of the children
+     * @return a collection of the children
+     * @throws RepositoryException if an error occurs
+     */
+    Collection<? extends VaultFile> getChildren() throws RepositoryException;
+
+    /**
+     * Returns the os file set for this file. The set contains those are the
+     * files that are generated from the same jcr file.
+     *
+     * @return the file set of related files
+     * @throws RepositoryException if an error occurs.
+     */
+    Collection<? extends VaultFile> getRelated() throws RepositoryException;
+
+    /**
+     * Checks if this file can be read from (eg. if it's not a directory)
+     * @return <code>true</code> if this file can be read from.
+     */
+    boolean canRead();
+
+    /**
+     * Returns the last modified date or <code>0</code> if not known.
+     * @return the last modified date or <code>0</code>
+     */
+    long lastModified();
+
+    /**
+     * Returns the length of the serialized data if it's known without doing the
+     * actual serialization.
+     * @return the length or <code>-1</code> if the length cannot be determined.
+     */
+    long length();
+
+    /**
+     * Returns the content type of this file or <code>null</code> if the type
+     * cannot be determined or if it's a directory.
+     * @return the content type or <code>null</code>.
+     */
+    String getContentType();
+
+    /**
+     * Returns the underlying file system.
+     * @return the Vault filesystem
+     */
+    VaultFileSystem getFileSystem();
+
+    void invalidate() throws RepositoryException;
+
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFileOutput.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFileOutput.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFileOutput.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFileOutput.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.api;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * <code>VaultFileOutput</code>...
+ */
+public interface VaultFileOutput {
+    OutputStream getOutputStream() throws IOException;
+
+    void setContentType(String contentType);
+
+    void close() throws IOException, RepositoryException;
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFileSystem.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFileSystem.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFileSystem.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFileSystem.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.api;
+
+import java.io.IOException;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * <code>VaultFileSystem</code>...
+ */
+public interface VaultFileSystem {
+
+    /**
+     * Releases all resources attached to this Vault filesystem
+     * @throws RepositoryException if an error occurs.
+     */
+    void unmount() throws RepositoryException;
+
+    /**
+     * Checks if this tree is still mounted and if the attached session
+     * is still live.
+     *
+     * @return <code>true</code> if still mounted
+     */
+    boolean isMounted();
+
+    /**
+     * Returns the root file
+     * @return the root file
+     */
+    VaultFile getRoot();
+
+    /**
+     * Returns the attached artifacts manager.
+     * @return the attached artifacts manager.
+     */
+    AggregateManager getAggregateManager();
+
+    /**
+     * Returns the file at the given path. If the file does not exists
+     * <code>null</code> is thrown.
+     *
+     * @param path the path of the file
+     * @return the file or <code>null</code>
+     * @throws IOException if an I/O error occurs.
+     * @throws RepositoryException if a repository error occurs.
+     */
+    VaultFile getFile(String path) throws IOException, RepositoryException;
+
+    /**
+     * Returns the file at the given path. The path can be relative and may
+     * contain ".." path elements. If the file does not exists <code>null</code>
+     * is returned.
+     *
+     * @param parent the parent file.
+     * @param path the path of the file
+     * @return the file or <code>null</code>
+     * @throws IOException if an I/O error occurs.
+     * @throws RepositoryException if a repository error occurs.
+     */
+    VaultFile getFile(VaultFile parent, String path)
+            throws IOException, RepositoryException;
+
+    /**
+     * Starts a new transaction.
+     * @return a new transaction.
+     */
+    VaultFsTransaction startTransaction();
+
+    /**
+     * Flushes the file cache
+     * @throws RepositoryException if an error occurs
+     */
+    void invalidate() throws RepositoryException;
+
+    /**
+     * Returns the vault configuration that is used
+     * @return the vault configuration.
+     */
+    VaultFsConfig getConfig();
+
+    /**
+     * Returns the current workspace filter
+     * @return the workspace filter
+     */
+    WorkspaceFilter getWorkspaceFilter();
+
+    
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFsConfig.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFsConfig.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFsConfig.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFsConfig.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.api;
+
+import java.io.InputStream;
+import java.util.List;
+
+/**
+ * <code>VaultFsConfig</code>...
+ */
+public interface VaultFsConfig {
+    
+    InputStream getSource();
+
+    /**
+     * Returns the source xml that constructs this filter
+     * @return the source xml
+     */
+    String getSourceAsString();
+
+    List<Aggregator> getAggregators();
+
+    List<ArtifactHandler> getHandlers();
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFsTransaction.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFsTransaction.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFsTransaction.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultFsTransaction.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.api;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * <code>VaultFsTransaction</code>...
+ */
+public interface VaultFsTransaction {
+
+    boolean isVerbose();
+
+    void setVerbose(boolean verbose);
+
+    void delete(VaultFile file) throws IOException;
+
+    void modify(VaultFile file, VaultInputSource input) throws IOException;
+
+    VaultFileOutput add(String path, VaultInputSource input)
+        throws IOException, RepositoryException;
+
+    void mkdir(String path) throws IOException, RepositoryException;
+
+    /**
+     * Commits the transaction and uploads all modifications to the repository.
+     *
+     * @return a list of modifications
+     * @throws IOException if an I/O error occurs
+     * @throws RepositoryException if a repository error occurs
+     */
+    Collection<Info> commit() throws RepositoryException, IOException;
+
+    public enum Type {
+        ADDED, ADDED_X, DELETED, MODIFIED, MOVED, MKDIR, ERROR
+    }
+
+    /**
+     * the transaction info
+     */
+    public static class Info {
+
+        private final Type type;
+
+        private String path;
+
+        public Info(Type type, String path) {
+            this.type = type;
+            this.path = path;
+        }
+
+        public String getPath() {
+            return path;
+        }
+
+        public Type getType() {
+            return type;
+        }
+
+    }
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultInputSource.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultInputSource.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultInputSource.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/VaultInputSource.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.api;
+
+import java.io.InputStream;
+import java.io.Reader;
+
+import org.xml.sax.InputSource;
+
+/**
+ * Extends the {@link InputSource} by a content length and last modified.
+ *
+ */
+public abstract class VaultInputSource extends InputSource {
+
+    protected VaultInputSource() {
+    }
+
+    protected VaultInputSource(String systemId) {
+        super(systemId);
+    }
+
+    protected VaultInputSource(InputStream byteStream) {
+        super(byteStream);
+    }
+
+    protected VaultInputSource(Reader characterStream) {
+        super(characterStream);
+    }
+
+    /**
+     * Returns the content length of the underlying file.
+     * @return the content length of the underlying file or -1 if unknown.
+     */
+    public abstract long getContentLength();
+
+    /**
+     * Returns the last modified date of the underlying file.
+     * @return the last modified date of the underlying file or 0 if unknown.
+     */
+    public abstract long getLastModified();
+
+
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/WorkspaceFilter.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/WorkspaceFilter.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/WorkspaceFilter.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/api/WorkspaceFilter.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.api;
+
+import java.io.InputStream;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+/**
+ * <code>WorkspaceFilter</code>...
+ */
+public interface WorkspaceFilter extends Dumpable {
+
+    /**
+     * Returns a list of path filter sets.
+     * @return the list of path filter sets.
+     */
+    List<PathFilterSet> getFilterSets();
+
+    /**
+     * Returns the filter set that covers the respective path
+     * @param path the path
+     * @return the filter set or <code>null</code>
+     */
+    PathFilterSet getCoveringFilterSet(String path);
+
+    /**
+     * Returns the import mode for the given path.
+     * @param path path to check
+     * @return the import mode or {@link ImportMode#REPLACE} if the given path
+     *         is not covered by this filter.
+     */
+    ImportMode getImportMode(String path);
+
+    /**
+     * Checks if the given path is contained in this workspace filter.
+     * It returns <code>true</code> if any of the filter sets contain the path
+     * and it's not globally ignored.
+     *
+     * @param path to check
+     * @return <code>true</code> if the given path is included in this filter.
+     */
+    boolean contains(String path);
+
+    /**
+     * Checks if the given path is covered in this workspace filter.
+     * It only returns <code>true</code> if at least one of the sets covers
+     * the path and is not globally ignored.
+     *
+     * @param path the pathto check
+     * @return <code>true</code> if the given path is covered by this filter.
+     */
+    boolean covers(String path);
+
+    /**
+     * Checks if the given path is an ancestor of any of the filter sets.
+     *
+     * @param path the item to check
+     * @return <code>true</code> if the given item is an ancestor
+     */
+    boolean isAncestor(String path);
+
+    /**
+     * Checks if the given path is globally ignored.
+     *
+     * @param path the path to check.
+     * @return <code>true</code> if the item is globally ignored.
+     */
+    boolean isGloballyIgnored(String path);
+
+    /**
+     * Returns the source xml that constructs this filter
+     * @return the source xml
+     */
+    InputStream getSource();
+
+    /**
+     * Returns the source xml that constructs this filter
+     * @return the source xml
+     */
+    String getSourceAsString();
+
+    /**
+     * Translates this workspace filter using the given path mapping.
+     *
+     * @param mapping the path mapping
+     * @return a new workspace filter
+     * @since 2.4.10
+     */
+    WorkspaceFilter translate(PathMapping mapping);
+
+    /**
+     * Dumps the coverage of this filter against the given node to the listener.
+     * @param rootNode root node
+     * @param listener listener
+     * @throws RepositoryException if an error occurs
+     */
+    void dumpCoverage(Node rootNode, ProgressTrackerListener listener)
+            throws RepositoryException;
+
+    /**
+     * Dumps the coverage of this filter using the given session. The traversal starts
+     * at the common ancestor of all filter sets. If <code>skipJcrContent</code> is <code>true</code>
+     * the jcr:content nodes are excluded from traversal and reporting.
+     *
+     * @param session session
+     * @param listener listener to report progress
+     * @param skipJcrContent <code>true</code> to skip jcr:content nodes
+     * @throws RepositoryException if an error occurs
+     */
+    void dumpCoverage(Session session, ProgressTrackerListener listener, boolean skipJcrContent)
+            throws RepositoryException;
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/AbstractConfig.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/AbstractConfig.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/AbstractConfig.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/AbstractConfig.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,151 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.config;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.jackrabbit.vault.util.RejectingEntityResolver;
+import org.apache.jackrabbit.vault.util.xml.serialize.OutputFormat;
+import org.apache.jackrabbit.vault.util.xml.serialize.XMLSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * <code>VaultUserConfig</code>...
+ *
+ */
+abstract public class AbstractConfig {
+
+    protected static Logger log = LoggerFactory.getLogger(AbstractConfig.class);
+
+    public static final String DIR_NAME = ".vault";
+
+    public static final String ATTR_VERSION = "version";
+
+    protected double version = getSupportedVersion();
+
+    abstract protected String getRootElemName();
+
+    abstract protected double getSupportedVersion();
+
+    protected void load(Element doc) throws ConfigurationException {
+        if (!doc.getNodeName().equals(getRootElemName())) {
+            throw new ConfigurationException("unexpected element: " + doc.getNodeName());
+        }
+        String v = doc.getAttribute(ATTR_VERSION);
+        if (v == null || v.equals("")) {
+            v = "1.0";
+        }
+        version = Double.parseDouble(v);
+        if (version > getSupportedVersion()) {
+            throw new ConfigurationException("version " + version + " not supported.");
+        }
+
+        NodeList nl = doc.getChildNodes();
+        for (int i=0; i<nl.getLength(); i++) {
+            Node child = nl.item(i);
+            if (child.getNodeType() == Node.ELEMENT_NODE) {
+                doLoad((Element) child);
+            }
+        }
+    }
+
+    abstract protected void doLoad(Element child) throws ConfigurationException;
+
+    public boolean load(File configFile) throws IOException, ConfigurationException {
+        return configFile.canRead() && load(FileUtils.openInputStream(configFile));
+    }
+
+    public boolean load(InputStream in) throws IOException, ConfigurationException {
+        try {
+            DocumentBuilderFactory factory =
+                DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            // disable DTD loading (bug #36897)
+            builder.setEntityResolver(new RejectingEntityResolver());
+            Document document = builder.parse(in);
+            Element doc = document.getDocumentElement();
+            load(doc);
+            return true;
+        } catch (ParserConfigurationException e) {
+            throw new ConfigurationException(e);
+        } catch (SAXException e) {
+            throw new ConfigurationException(e);
+        } finally {
+            IOUtils.closeQuietly(in);
+        }
+    }
+
+    public void save(File configFile) throws IOException {
+        save(FileUtils.openOutputStream(configFile));
+    }
+    
+    public void save(OutputStream out) throws IOException {
+        OutputFormat fmt = new OutputFormat("xml", "UTF-8", true);
+        fmt.setLineWidth(0);
+        fmt.setIndent(2);
+        XMLSerializer ser = new XMLSerializer(out, fmt);
+        try {
+            write(ser);
+        } catch (SAXException e) {
+            throw new IOException(e.toString());
+        } finally {
+            IOUtils.closeQuietly(out);
+        }
+    }
+
+    public File getConfigDir() throws IOException {
+        File userHome = new File(System.getProperty("user.home"));
+        File configDir = new File(userHome, DIR_NAME);
+        if (!configDir.exists()) {
+            configDir.mkdirs();
+            if (!configDir.exists()) {
+                throw new IOException("Error: Unable to create " + configDir.getAbsolutePath());
+            }
+        }
+        return configDir;
+    }
+
+    protected void write(ContentHandler handler) throws SAXException {
+        handler.startDocument();
+        AttributesImpl attrs = new AttributesImpl();
+        attrs.addAttribute("", ATTR_VERSION, "", "CDATA", String.valueOf(version));
+        handler.startElement("", getRootElemName(), "", attrs);
+        doWrite(handler);
+        handler.endElement("", getRootElemName(), "");
+        handler.endDocument();
+    }
+
+    abstract protected void doWrite(ContentHandler handler) throws SAXException;
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/AbstractVaultFsConfig.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/AbstractVaultFsConfig.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/AbstractVaultFsConfig.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/AbstractVaultFsConfig.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.fs.config;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.jackrabbit.vault.fs.api.Aggregator;
+import org.apache.jackrabbit.vault.fs.api.ArtifactHandler;
+import org.apache.jackrabbit.vault.fs.api.VaultFsConfig;
+import org.apache.jackrabbit.vault.util.RejectingEntityResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+/**
+ * <code>JcrFsConfig</code>...
+ */
+public abstract class AbstractVaultFsConfig implements VaultFsConfig {
+
+    /**
+     * default logger
+     */
+    private static final Logger log = LoggerFactory.getLogger(AbstractVaultFsConfig.class);
+
+    public static final String ATTR_VERSION = "version";
+
+    private List<Aggregator> aggregators = new ArrayList<Aggregator>();
+
+    private List<ArtifactHandler> handlers = new ArrayList<ArtifactHandler>();
+
+    private byte[] source;
+
+    private String name = "";
+
+    public static VaultFsConfig load(File file)
+            throws ConfigurationException, IOException {
+        return load(new FileInputStream(file), file.getName());
+    }
+
+    public static VaultFsConfig load(InputStream in, String name)
+            throws ConfigurationException, IOException {
+        try {
+            byte[] source = IOUtils.toByteArray(in);
+            Document document = parse(new ByteArrayInputStream(source));
+
+            Element doc = document.getDocumentElement();
+            if (!doc.getNodeName().equals("vaultfs")) {
+                throw new ConfigurationException("<vaultfs> expected.");
+            }
+            String v = doc.getAttribute(ATTR_VERSION);
+            if (v == null || v.equals("")) {
+                v = "1.0";
+            }
+            double version = Double.parseDouble(v);
+            AbstractVaultFsConfig config;
+            if (version != VaultFsConfig11.SUPPORTED_VERSION) {
+                throw new ConfigurationException("version " + version + " not supported.");
+            } else {
+                config = new VaultFsConfig11();
+            }
+            config.setSource(source);
+            config.setName(name);
+            config.process(doc);
+            return config;
+        } finally {
+            IOUtils.closeQuietly(in);
+        }
+
+    }
+
+    protected abstract void process(Element doc) throws ConfigurationException;
+
+    private void setSource(byte[] bytes) {
+        this.source = bytes;
+    }
+
+    private void setName(String name) {
+        this.name = name;
+    }
+
+    public InputStream getSource() {
+        return new ByteArrayInputStream(source);
+    }
+
+    public String getSourceAsString() {
+        try {
+            return new String(source, "utf-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    public List<Aggregator> getAggregators() {
+        return aggregators;
+    }
+
+    public List<ArtifactHandler> getHandlers() {
+        return handlers;
+    }
+
+    private static Document parse(InputStream xml)
+            throws ConfigurationException, IOException {
+        try {
+            DocumentBuilderFactory factory =
+                DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            // disable DTD loading (bug #36897)
+            builder.setEntityResolver(new RejectingEntityResolver());
+            return builder.parse(xml);
+        } catch (ParserConfigurationException e) {
+            throw new ConfigurationException(
+                    "Unable to create configuration XML parser", e);
+        } catch (SAXException e) {
+            throw new ConfigurationException(
+                    "Configuration file syntax error.", e);
+        }
+    }
+
+    protected static Collection<Element> getChildElements(Node elem) {
+        NodeList nodeList = elem.getChildNodes();
+        List<Element> nodes = new ArrayList<Element>(nodeList.getLength());
+        for (int i=0; i<nodeList.getLength(); i++) {
+            Node child = nodeList.item(i);
+            if (child.getNodeType() == Node.ELEMENT_NODE) {
+                nodes.add((Element) child);
+            }
+        }
+        return nodes;
+    }
+
+    protected void fail(String msg, Node elem) throws ConfigurationException {
+        String path = "";
+        while (elem != null && elem.getNodeType() != Node.DOCUMENT_NODE) {
+            path = " > " + elem.getNodeName() + path;
+            elem = elem.getParentNode();
+        }
+        throw new ConfigurationException(msg + ". Location: " + name + path);
+    }
+
+}
\ No newline at end of file