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 [10/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-cl...

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/ConfigHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/ConfigHelper.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/ConfigHelper.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/ConfigHelper.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,208 @@
+/*
+ * 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.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Element;
+
+/**
+ * <code>ConfigHelper</code>...
+ */
+public class ConfigHelper {
+
+    /**
+     * default logger
+     */
+    private static final Logger log = LoggerFactory.getLogger(ConfigHelper.class);
+
+    private Map defaultPackages = new HashMap();
+
+    private Map defaultClasses = new HashMap();
+
+    private Map<String, String> mappings = new HashMap<String, String>();
+
+    public Map getDefaultPackages() {
+        return defaultPackages;
+    }
+
+    public Map getDefaultClasses() {
+        return defaultClasses;
+    }
+
+    protected Map<String, String> getMappings() {
+        return mappings;
+    }
+
+    public String getDefaultPackage(String name) {
+        return (String) defaultPackages.get(name);
+    }
+
+    public String getDefaultClass(String name) {
+        return (String) defaultClasses.get(name);
+    }
+
+    public Object create(Element elem)
+            throws ConfigurationException {
+
+        String className = elem.getAttribute("class");
+        if (className == null || className.equals("")) {
+            className = (String) defaultClasses.get(elem.getNodeName());
+        }
+        if (className == null || className.equals("")) {
+            // create string object
+            return elem.getFirstChild().getNodeValue();
+        }
+        String field = null;
+        int pos = className.indexOf('#');
+        if (pos>0) {
+            field = className.substring(pos + 1);
+            className = className.substring(0, pos);
+        }
+
+        // try to get class without prepending package
+        Class clazz = null;
+        try {
+            clazz = getClass().getClassLoader().loadClass(className);
+        } catch (ClassNotFoundException e) {
+            // ignore
+        }
+        if (clazz == null) {
+            // check for default package
+            if (className.indexOf('.') < 0) {
+                String pack = (String) defaultPackages.get(elem.getNodeName());
+                if (pack == null) {
+                    throw new ConfigurationException("Default package for class attribute of " + elem.getNodeName() + " missing.");
+                }
+                className = pack + "." + className;
+            }
+
+            // check for mapping
+            if (mappings.containsKey(className)) {
+                className = mappings.get(className);
+            }
+
+            try {
+                clazz = getClass().getClassLoader().loadClass(className);
+            } catch (ClassNotFoundException e) {
+                throw new ConfigurationException("Error while creating instance for " + elem.getNodeName(), e);
+            }
+
+        }
+        try {
+            if (field == null) {
+                return clazz.newInstance();
+            } else {
+                return clazz.getField(field).get(null);
+            }
+        } catch (InstantiationException e) {
+            throw new ConfigurationException("Error while creating instance for " + elem.getNodeName(), e);
+        } catch (NoSuchFieldException e) {
+            throw new ConfigurationException("Error while creating instance for " + elem.getNodeName(), e);
+        } catch (IllegalAccessException e) {
+            throw new ConfigurationException("Error while creating instance for " + elem.getNodeName(), e);
+        }
+    }
+
+    public static String getMethodName(String prefix, String name) {
+        return prefix + name.substring(0, 1).toUpperCase() + name.substring(1);
+    }
+
+    public static Method getMethod(Object obj, String name, Class ... params) {
+        Method[] ms = obj.getClass().getMethods();
+        for (Method m : ms) {
+            if (m.getName().equals(name)) {
+                Class[] pt = m.getParameterTypes();
+                if (pt.length == params.length) {
+                    for (int j = 0; j < params.length; j++) {
+                        if (!params[j].isAssignableFrom(pt[j])) {
+                            m = null;
+                            break;
+                        }
+                    }
+                    if (m != null) {
+                        return m;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    public static boolean hasSetter(Object obj, String name)
+            throws ConfigurationException {
+        String setter = getMethodName("set", name);
+        if (getMethod(obj, setter, Object.class) != null) {
+            log.debug("Has setter {} on {}" , name, obj);
+            return true;
+        } else {
+            log.debug("{} has no setter for {}" , obj, name);
+            return false;
+        }
+    }
+
+    public static boolean setField(Object obj, String name, Object value)
+            throws ConfigurationException {
+        // ignore 'class' setters
+        if (name.equals("class")) {
+            return false;
+        }
+        String setter = getMethodName("set", name);
+        try {
+            Method m = getMethod(obj, setter, Object.class);
+            if (m == null) {
+                log.error("{} has no setter for {}" , obj, name);
+                throw new ConfigurationException(obj + " has not setter for " + name);
+            }
+            m.invoke(obj, value);
+            log.debug("Setting {} on {}" , name, obj);
+            return true;
+        } catch (IllegalAccessException e) {
+            throw new ConfigurationException("Unable to set " + setter + " of " + obj , e);
+        } catch (InvocationTargetException e) {
+            throw new ConfigurationException("Unable to set " + setter + " of " + obj , e);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> T invokeGetter(Object obj, String name, Class<T> T)
+            throws ConfigurationException {
+        try {
+            String getter = getMethodName("get", name);
+            Method m = obj.getClass().getMethod(getter);
+            if (T.isAssignableFrom(m.getReturnType())) {
+                return (T) m.invoke(obj);
+            } else {
+                return null;
+            }
+        } catch (NoSuchMethodException e) {
+            log.debug("{} has no field {} or type " + T, obj, name);
+            return null;
+        } catch (IllegalAccessException e) {
+            throw new ConfigurationException("Unable to get list " + name + " of " + obj);
+        } catch (InvocationTargetException e) {
+            throw new ConfigurationException("Unable to get list " + name + " of " + obj);
+        }
+    }
+
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/ConfigurationException.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/ConfigurationException.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/ConfigurationException.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/ConfigurationException.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,40 @@
+/*
+ * 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;
+
+/**
+ * <code>ConfigurationException</code>...
+ *
+ */
+public class ConfigurationException extends Exception {
+
+    public ConfigurationException() {
+    }
+
+    public ConfigurationException(String message) {
+        super(message);
+    }
+
+    public ConfigurationException(Throwable cause) {
+        super(cause);
+    }
+
+    public ConfigurationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/CredentialsConfig.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/CredentialsConfig.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/CredentialsConfig.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/CredentialsConfig.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,62 @@
+/*
+ * 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 javax.jcr.Credentials;
+
+import org.w3c.dom.Element;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * <code>CredentialsConfig</code>...
+*
+*/
+public abstract class CredentialsConfig {
+
+    public final String type;
+    public static final String ATTR_TYPE = "type";
+    public static final String ELEM_CREDETIALS = "credentials";
+
+    public CredentialsConfig(String type) {
+        this.type = type;
+    }
+
+    public static CredentialsConfig load(Element elem) throws ConfigurationException {
+        assert elem.getNodeName().equals(ELEM_CREDETIALS);
+
+        String type = elem.getAttribute(ATTR_TYPE);
+        if (type == null || type.equals("simple")) {
+            return SimpleCredentialsConfig.load(elem);
+        }
+        throw new ConfigurationException("unknown credentials type: " + type);
+    }
+
+    public abstract Credentials getCredentials();
+
+    public void write(ContentHandler handler) throws SAXException {
+        AttributesImpl attrs = new AttributesImpl();
+        attrs.addAttribute("", ATTR_TYPE, "", "CDATA", type);
+        handler.startElement("", ELEM_CREDETIALS, "", attrs);
+        writeInner(handler);
+        handler.endElement("", ELEM_CREDETIALS, "");
+    }
+
+    protected abstract void writeInner(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/DefaultMetaInf.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/DefaultMetaInf.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/DefaultMetaInf.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/DefaultMetaInf.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,323 @@
+/*
+ * 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.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.jcr.NamespaceException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.jackrabbit.spi.commons.privilege.ParseException;
+import org.apache.jackrabbit.spi.commons.privilege.PrivilegeDefinitionReader;
+import org.apache.jackrabbit.vault.fs.api.VaultFsConfig;
+import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter;
+import org.apache.jackrabbit.vault.fs.spi.CNDReader;
+import org.apache.jackrabbit.vault.fs.spi.NodeTypeSet;
+import org.apache.jackrabbit.vault.fs.spi.PrivilegeDefinitions;
+import org.apache.jackrabbit.vault.fs.spi.ServiceProviderFactory;
+import org.apache.jackrabbit.vault.util.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstracts the way of accessing the vault specific meta-info of a checkout.
+ */
+public class DefaultMetaInf implements MetaInf {
+
+    private static Logger log = LoggerFactory.getLogger(DefaultMetaInf.class);
+
+    private VaultSettings settings;
+
+    private WorkspaceFilter filter;
+
+    private VaultFsConfig config;
+
+    private Properties properties;
+
+    private Collection<NodeTypeSet> cnds = new LinkedList<NodeTypeSet>();
+
+    private PrivilegeDefinitions privileges = new PrivilegeDefinitions();
+
+    private boolean hasDefinition;
+
+    /**
+     * Returns the package format version of this package. If the package
+     * lacks this information, {@link #FORMAT_VERSION_2} is returned, since this
+     * feature was implemented recently.
+     *
+     * @return the package format version
+     * @since 2.0
+     */
+    public int getPackageFormatVersion() {
+        String prop = properties == null
+                ? null
+                : properties.getProperty(PACKAGE_FORMAT_VERSION);
+        if (prop != null) {
+            try {
+                return Integer.getInteger(prop);
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+        return FORMAT_VERSION_2;
+    }
+
+    public void loadFilter(InputStream in, String systemId)
+            throws ConfigurationException, IOException {
+        DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+        filter.load(in);
+        setFilter(filter);
+        log.debug("Loaded filter from {}.", systemId);
+    }
+
+    public void loadConfig(InputStream in, String systemId)
+            throws ConfigurationException, IOException {
+        VaultFsConfig config = AbstractVaultFsConfig.load(in, systemId);
+        setConfig(config);
+        log.debug("Loaded config from {}.", systemId);
+    }
+
+    public void loadSettings(InputStream in, String systemId)
+            throws ConfigurationException, IOException {
+        VaultSettings settings = new VaultSettings();
+        settings.load(in);
+        setSettings(settings);
+        log.debug("Loaded settings from {}.", systemId);
+    }
+
+    public void loadProperties(InputStream in, String systemId)
+            throws IOException {
+        Properties props = new Properties();
+        props.loadFromXML(in);
+        setProperties(props);
+        log.debug("Loaded properties from {}.", systemId);
+    }
+
+    public void loadPrivileges(InputStream in, String systemId)
+            throws IOException {
+        try {
+            PrivilegeDefinitionReader reader = new PrivilegeDefinitionReader(in, "text/xml");
+            Collections.addAll(privileges.getDefinitions(), reader.getPrivilegeDefinitions());
+            for (Map.Entry<String, String> e: reader.getNamespaces().entrySet()) {
+                privileges.getNamespaceMapping().setMapping(e.getKey(), e.getValue());
+            }
+        } catch (ParseException e) {
+            log.error("Error while reading Privileges: {}", e.toString());
+            IOException io = new IOException("Error while reading privileges.");
+            io.initCause(e);
+            throw io;
+        } catch (NamespaceException e) {
+            log.error("Error while reading Privileges: {}", e.toString());
+            IOException io = new IOException("Error while reading privileges.");
+            io.initCause(e);
+            throw io;
+        }
+        log.debug("Loaded privileges from {}.", systemId);
+    }
+
+    public void save(File metaDir) throws IOException {
+        if (metaDir.isDirectory()) {
+            saveConfig(metaDir);
+            saveFilter(metaDir);
+            saveSettings(metaDir);
+            saveProperties(metaDir);
+        } else {
+            throw new IOException("meta directory does not exist or is non a directory: " + metaDir.getAbsolutePath());
+        }
+    }
+
+    public VaultSettings getSettings() {
+        return settings;
+    }
+
+    public void setSettings(VaultSettings settings) {
+        this.settings = settings;
+    }
+
+    public WorkspaceFilter getFilter() {
+        return filter;
+    }
+
+    public void setFilter(WorkspaceFilter filter) {
+        this.filter = filter;
+    }
+
+    public VaultFsConfig getConfig() {
+        return config;
+    }
+
+    public void setConfig(VaultFsConfig config) {
+        this.config = config;
+    }
+
+    public Properties getProperties() {
+        return properties;
+    }
+
+    public void setProperties(Properties properties) {
+        this.properties = properties;
+    }
+
+    public Collection<NodeTypeSet> getNodeTypes() {
+        return cnds;
+    }
+
+    public PrivilegeDefinitions getPrivileges() {
+        return privileges;
+    }
+
+    public void setCNDs(Collection<NodeTypeSet> cnds) {
+        this.cnds = cnds;
+    }
+
+    public boolean hasDefinition() {
+        return hasDefinition;
+    }
+
+    public void setHasDefinition(boolean hasDefinition) {
+        this.hasDefinition = hasDefinition;
+    }
+
+    protected void loadSettings(File metaDir)
+            throws ConfigurationException, IOException {
+        File file = new File(metaDir, Constants.SETTINGS_XML);
+        if (file.isFile()) {
+            VaultSettings settings = new VaultSettings();
+            settings.load(file);
+            this.settings = settings;
+        } else {
+            settings = VaultSettings.createDefault();
+        }
+    }
+
+    protected void saveSettings(File metaDir) throws IOException {
+        if (settings != null) {
+            File file = new File(metaDir, Constants.SETTINGS_XML);
+            settings.save(file);
+        }
+    }
+
+    protected void loadConfig(File metaDir)
+            throws ConfigurationException, IOException {
+        File file = new File(metaDir, Constants.CONFIG_XML);
+        if (file.isFile()) {
+            this.config = AbstractVaultFsConfig.load(file);
+        }
+    }
+
+    protected void saveConfig(File metaDir)
+            throws IOException {
+        if (config != null) {
+            File file = new File(metaDir, Constants.CONFIG_XML);
+            IOUtils.copy(
+                    config.getSource(),
+                    FileUtils.openOutputStream(file)
+            );
+        }
+    }
+
+    protected void loadFilter(File metaDir, boolean vltMode)
+            throws ConfigurationException, IOException {
+        File file = new File(metaDir, Constants.FILTER_XML);
+        if (vltMode) {
+            File altFile = new File(metaDir, Constants.FILTER_VLT_XML);
+            if (altFile.isFile()) {
+                file = altFile;
+                log.info("Using alternative filter from {}", altFile.getPath());
+            }
+        }
+        if (file.isFile()) {
+            DefaultWorkspaceFilter filter = new DefaultWorkspaceFilter();
+            filter.load(file);
+            this.filter = filter;
+        }
+    }
+
+    protected void saveFilter(File metaDir)
+            throws IOException {
+        if (filter != null) {
+            File file = new File(metaDir, Constants.FILTER_XML);
+            IOUtils.copy(
+                    filter.getSource(),
+                    FileUtils.openOutputStream(file)
+            );
+        }
+    }
+
+    protected void loadProperties(File metaDir) throws IOException {
+        File file = new File(metaDir, Constants.PROPERTIES_XML);
+        if (file.isFile()) {
+            Properties properties = new Properties();
+            properties.loadFromXML(FileUtils.openInputStream(file));
+            this.properties = properties;
+        }
+    }
+
+    protected void saveProperties(File metaDir) throws IOException {
+        if (properties != null) {
+            File file = new File(metaDir, Constants.PROPERTIES_XML);
+            properties.storeToXML(
+                    FileUtils.openOutputStream(file),
+                    "Custom Vault Properties", "utf-8");
+        }
+    }
+
+    protected void loadPrivileges(File metaDir) throws IOException {
+        File file = new File(metaDir, Constants.PRIVILEGES_XML);
+        if (file.isFile()) {
+            InputStream in = FileUtils.openInputStream(file);
+            try {
+                loadPrivileges(in, file.getPath());
+            } finally {
+                IOUtils.closeQuietly(in);
+            }
+        }
+    }
+
+    protected void loadCNDs(File metaDir) throws IOException {
+        for (File file: metaDir.listFiles()) {
+            if (file.getName().endsWith(".cnd")) {
+                Reader r = null;
+                try {
+                    r = new InputStreamReader(new FileInputStream(file), "utf8");
+                    CNDReader reader = ServiceProviderFactory.getProvider().getCNDReader();
+                    reader.read(r, file.getName(), null);
+                    cnds.add(reader);
+                } catch (IOException e) {
+                    log.error("Error while reading CND: {}", e.toString());
+                    IOException io = new IOException("Error while reading CND.");
+                    io.initCause(e);
+                    throw io;
+                } finally {
+                    IOUtils.closeQuietly(r);
+                }
+            }
+        }
+    }
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/DefaultWorkspaceFilter.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/DefaultWorkspaceFilter.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/DefaultWorkspaceFilter.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/DefaultWorkspaceFilter.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,448 @@
+/*
+ * 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.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+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.util.Text;
+import org.apache.jackrabbit.vault.fs.api.DumpContext;
+import org.apache.jackrabbit.vault.fs.api.Dumpable;
+import org.apache.jackrabbit.vault.fs.api.FilterSet;
+import org.apache.jackrabbit.vault.fs.api.ImportMode;
+import org.apache.jackrabbit.vault.fs.api.PathFilter;
+import org.apache.jackrabbit.vault.fs.api.PathFilterSet;
+import org.apache.jackrabbit.vault.fs.api.PathMapping;
+import org.apache.jackrabbit.vault.fs.api.ProgressTrackerListener;
+import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter;
+import org.apache.jackrabbit.vault.fs.filter.DefaultPathFilter;
+import org.apache.jackrabbit.vault.fs.spi.ProgressTracker;
+import org.apache.jackrabbit.vault.util.RejectingEntityResolver;
+import org.apache.jackrabbit.vault.util.Tree;
+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.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * Holds a list of {@link PathFilterSet}s.
+ *
+ */
+public class DefaultWorkspaceFilter implements Dumpable, WorkspaceFilter {
+
+    /**
+     * default logger
+     */
+    private static final Logger log = LoggerFactory.getLogger(DefaultWorkspaceFilter.class);
+
+    private final List<PathFilterSet> filterSets = new LinkedList<PathFilterSet>();
+
+    public static final String ATTR_VERSION = "version";
+
+    public static final double SUPPORTED_VERSION = 1.0;
+
+    protected double version = SUPPORTED_VERSION;
+
+    private byte[] source;
+
+    /**
+     * globally ignored paths. they are not persisted, yet
+     */
+    private PathFilter globalIgnored;
+
+    /**
+     * global import mode override (e.g. for snapshot restores)
+     */
+    private ImportMode importMode;
+
+    public void add(PathFilterSet set) {
+        filterSets.add(set);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public List<PathFilterSet> getFilterSets() {
+        return filterSets;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public PathFilterSet getCoveringFilterSet(String path) {
+        if (isGloballyIgnored(path)) {
+            return null;
+        }
+        for (PathFilterSet set: filterSets) {
+            if (set.covers(path)) {
+                return set;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ImportMode getImportMode(String path) {
+        if (importMode != null) {
+            return importMode;
+        }
+        FilterSet set = getCoveringFilterSet(path);
+        return set == null ? ImportMode.REPLACE : set.getImportMode();
+    }
+
+    public void setImportMode(ImportMode importMode) {
+        this.importMode = importMode;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean contains(String path) {
+        if (isGloballyIgnored(path)) {
+            return false;
+        }
+        for (PathFilterSet set: filterSets) {
+            if (set.contains(path)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean covers(String path) {
+        if (isGloballyIgnored(path)) {
+            return false;
+        }
+        for (PathFilterSet set: filterSets) {
+            if (set.covers(path)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isAncestor(String path) {
+        for (PathFilterSet set: filterSets) {
+            if (set.isAncestor(path)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isGloballyIgnored(String path) {
+        return globalIgnored != null && globalIgnored.matches(path);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public WorkspaceFilter translate(PathMapping mapping) {
+        if (mapping == null) {
+            return this;
+        }
+        DefaultWorkspaceFilter mapped = new DefaultWorkspaceFilter();
+        if (globalIgnored != null) {
+            mapped.setGlobalIgnored(globalIgnored.translate(mapping));
+        }
+        for (PathFilterSet set: filterSets) {
+            mapped.add(set.translate(mapping));
+        }
+        return mapped;
+    }
+
+    /**
+     * Loads the workspace filter from the given file
+     * @param file source
+     * @throws ConfigurationException if the source is not valid
+     * @throws IOException if an I/O error occurs
+     */
+    public void load(File file) throws IOException, ConfigurationException {
+        load(new FileInputStream(file));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public InputStream getSource() {
+        if (source == null) {
+            generateSource();
+        }
+        return new ByteArrayInputStream(source);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getSourceAsString() {
+        if (source == null) {
+            generateSource();
+        }
+        try {
+            return new String(source, "utf-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    /**
+     * Loads the workspace filter from the given input source
+     * @param in source
+     * @throws ConfigurationException if the source is not valid
+     * @throws IOException if an I/O error occurs
+     */
+    public void load(InputStream in) throws IOException, ConfigurationException {
+        try {
+            source = IOUtils.toByteArray(in);
+            in = getSource();
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            factory.setNamespaceAware(true);
+            //factory.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            // disable DTD loading (bug #36897)
+            builder.setEntityResolver(new RejectingEntityResolver());
+            Document document = builder.parse(in);
+            Element doc = document.getDocumentElement();
+            if (!doc.getNodeName().equals("workspaceFilter")) {
+                throw new ConfigurationException("<workspaceFilter> expected.");
+            }
+            String v = doc.getAttribute(ATTR_VERSION);
+            if (v == null || v.equals("")) {
+                v = "1.0";
+            }
+            version = Double.parseDouble(v);
+            if (version > SUPPORTED_VERSION) {
+                throw new ConfigurationException("version " + version + " not supported.");
+            }
+            read(doc);
+        } catch (ParserConfigurationException e) {
+            throw new ConfigurationException(
+                    "Unable to create configuration XML parser", e);
+        } catch (SAXException e) {
+            throw new ConfigurationException(
+                    "Configuration file syntax error.", e);
+        } finally {
+            IOUtils.closeQuietly(in);
+        }
+
+    }
+
+    private void read(Element elem) throws ConfigurationException {
+        NodeList nl = elem.getChildNodes();
+        for (int i=0; i<nl.getLength(); i++) {
+            Node child = nl.item(i);
+            if (child.getNodeType() == Node.ELEMENT_NODE) {
+                if (!child.getNodeName().equals("filter")) {
+                    throw new ConfigurationException("<filter> expected.");
+                }
+                PathFilterSet def = readDef((Element) child);
+                filterSets.add(def);
+            }
+        }
+    }
+
+    private PathFilterSet readDef(Element elem) throws ConfigurationException {
+        String root = elem.getAttribute("root");
+        PathFilterSet def = new PathFilterSet(root == null || root.length() == 0 ? "/" : root);
+        // check for import mode
+        String mode = elem.getAttribute("mode");
+        if (mode != null && mode.length() > 0) {
+            def.setImportMode(ImportMode.valueOf(mode.toUpperCase()));
+        }
+        // check for filters
+        NodeList n1 = elem.getChildNodes();
+        for (int i=0; i<n1.getLength(); i++) {
+            Node child = n1.item(i);
+            if (child.getNodeType() == Node.ELEMENT_NODE) {
+                if (child.getNodeName().equals("include")) {
+                    def.addInclude(readFilter((Element) child));
+                } else if (child.getNodeName().equals("exclude")) {
+                    def.addExclude(readFilter((Element) child));
+                } else {
+                    throw new ConfigurationException("either <include> or <exclude> expected.");
+                }
+            }
+        }
+        return def;
+    }
+
+    protected PathFilter readFilter(Element elem) throws ConfigurationException {
+        String pattern = elem.getAttribute("pattern");
+        if (pattern == null || pattern.equals("")) {
+            throw new ConfigurationException("Filter pattern must not be empty");
+        }
+        return new DefaultPathFilter(pattern);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void dump(DumpContext ctx, boolean isLast) {
+        Iterator<PathFilterSet> iter = filterSets.iterator();
+        while (iter.hasNext()) {
+            PathFilterSet set = iter.next();
+            ctx.println(!iter.hasNext(), "ItemFilterSet");
+            ctx.indent(!iter.hasNext());
+            set.dump(ctx, false);
+            ctx.outdent();
+        }
+    }
+
+    /**
+     * Reset the source content to a null state.
+     */
+    public void resetSource() {
+        source = null;
+    }
+
+
+    private void generateSource() {
+        try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            XMLSerializer ser = new XMLSerializer(out, new OutputFormat("xml", "UTF-8", true));
+            ser.startDocument();
+            AttributesImpl attrs = new AttributesImpl();
+            attrs.addAttribute(null, null, ATTR_VERSION, "CDATA", String.valueOf(version));
+            ser.startElement(null, null, "workspaceFilter", attrs);
+            for (PathFilterSet set: filterSets) {
+                attrs = new AttributesImpl();
+                attrs.addAttribute(null, null, "root", "CDATA", set.getRoot());
+                if (set.getImportMode() != ImportMode.REPLACE) {
+                    attrs.addAttribute(null, null, "mode", "CDATA", set.getImportMode().name().toLowerCase());
+                }
+                ser.startElement(null, null, "filter", attrs);
+                for (PathFilterSet.Entry<PathFilter> entry: set.getEntries()) {
+                    // only handle path filters
+                    PathFilter filter = entry.getFilter();
+                    if (filter instanceof DefaultPathFilter) {
+                        attrs = new AttributesImpl();
+                        attrs.addAttribute(null, null, "pattern", "CDATA",
+                                ((DefaultPathFilter) filter).getPattern());
+                        if (entry.isInclude()) {
+                            ser.startElement(null, null, "include", attrs);
+                            ser.endElement("include");
+                        } else {
+                            ser.startElement(null, null, "exclude", attrs);
+                            ser.endElement("exclude");
+                        }
+                    } else {
+                        throw new IllegalArgumentException("Can only export default path filters, yet.");
+                    }
+                }
+                ser.endElement("filter");
+            }
+            ser.endElement("workspaceFilter");
+            ser.endDocument();
+            source = out.toByteArray();
+        } catch (SAXException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    public void setGlobalIgnored(PathFilter ignored) {
+        globalIgnored = ignored;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void dumpCoverage(javax.jcr.Node rootNode, ProgressTrackerListener listener)
+            throws RepositoryException {
+        ProgressTracker tracker = new ProgressTracker(listener);
+        log.debug("Starting coverage dump at / (skipJcrContent=false)");
+        dumpCoverage(rootNode, tracker, false);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void dumpCoverage(Session session, ProgressTrackerListener listener, boolean skipJcrContent)
+            throws RepositoryException {
+        ProgressTracker tracker = new ProgressTracker(listener);
+        // get common ancestor
+        Tree<PathFilterSet> tree = new Tree<PathFilterSet>();
+        for (PathFilterSet set: filterSets) {
+            tree.put(set.getRoot(), set);
+        }
+        String rootPath = tree.getRootPath();
+        javax.jcr.Node rootNode;
+        try {
+            rootNode = session.getNode(rootPath);
+        } catch (RepositoryException e) {
+            log.warn("Common ancestor {} not found. Using root node", rootPath);
+            rootNode = session.getRootNode();
+            rootPath = "/";
+        }
+        log.debug("Starting coverage dump at {} (skipJcrContent={})", rootPath, skipJcrContent);
+        dumpCoverage(rootNode, tracker, skipJcrContent);
+    }
+
+    private void dumpCoverage(javax.jcr.Node node, ProgressTracker tracker, boolean skipJcrContent)
+            throws RepositoryException {
+        String path = node.getPath();
+        if (skipJcrContent && "jcr:content".equals(Text.getName(path))) {
+            return;
+        }
+        boolean contained;
+        if ((contained = contains(path)) || isAncestor(path)) {
+            if (contained) {
+                tracker.track("A", path);
+            }
+            NodeIterator iter = node.getNodes();
+            while (iter.hasNext()) {
+                dumpCoverage(iter.nextNode(), tracker, skipJcrContent);
+            }
+
+        }
+    }
+
+
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/ExportRoot.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/ExportRoot.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/ExportRoot.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/ExportRoot.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,162 @@
+/*
+ * 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 org.apache.jackrabbit.vault.util.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represents the root of a vault export or a vlt checkout. it has the following
+ * structure:
+ *
+ * <xmp>
+ * root
+ * |-- META-INF
+ * |   `-- vault
+ * |       |-- config.xml
+ * |       |-- filter.xml
+ * |       |-- nodetypes.cnd
+ * |       `-- properties.xml
+ * `-- jcr_root
+ *     :
+ * </xmp>
+ *
+ */
+public class ExportRoot {
+
+    private static final Logger log = LoggerFactory.getLogger(ExportRoot.class);
+
+    private final File rootDir;
+
+    private final File jcrRoot;
+
+    private final File metaDir;
+
+    private DefaultMetaInf metaInf;
+
+    public ExportRoot(File rootDir) {
+        this.rootDir = rootDir;
+        this.jcrRoot = new File(rootDir, Constants.ROOT_DIR);
+        this.metaDir = new File(rootDir, Constants.META_DIR);
+    }
+
+    /**
+     * Checks if this export root already has the necessary structure setup.
+     * @return <code>true</code> if valid.
+     */
+    public boolean isValid() {
+        return jcrRoot.isDirectory() && metaDir.isDirectory();
+    }
+
+    public void assertValid() throws IOException {
+        if (!isValid()) {
+            throw new IOException(Constants.META_DIR + " does not exist or is not valid.");
+        }
+    }
+
+    /**
+     * Creates the necessary directories if they do not exist yet.
+     * @throws IOException if an I/O error occurs
+     */
+    public void create() throws IOException {
+        if (!jcrRoot.isDirectory()) {
+            jcrRoot.mkdirs();
+            if (!jcrRoot.isDirectory()) {
+                throw new IOException("Unable to create " + jcrRoot.getAbsolutePath());
+            }
+            log.info("Created {}", jcrRoot.getAbsolutePath());
+        }
+        if (!metaDir.isDirectory()) {
+            metaDir.mkdirs();
+            if (!metaDir.isDirectory()) {
+                throw new IOException("Unable to create " + metaDir.getAbsolutePath());
+            }
+            log.info("Created {}", metaDir.getAbsolutePath());
+        }
+    }
+
+    /**
+     * Returns the meta information.
+     * @return the meta information.
+     */
+    public MetaInf getMetaInf() {
+        if (metaInf == null) {
+            metaInf = new DefaultMetaInf();
+            if (metaDir.exists()) {
+                try {
+                    metaInf.loadConfig(metaDir);
+                    metaInf.loadFilter(metaDir, true);
+                    metaInf.loadSettings(metaDir);
+                    metaInf.loadProperties(metaDir);
+                    metaInf.loadCNDs(metaDir);
+                    metaInf.loadPrivileges(metaDir);
+                    metaInf.setHasDefinition(new File(metaDir, Constants.PACKAGE_DEFINITION_XML).canRead());
+                } catch (ConfigurationException e) {
+                    log.warn("Error while loading meta dir." , e);
+                } catch (IOException e) {
+                    log.warn("Error while loading meta dir." , e);
+                }
+            }
+        }
+        return metaInf;
+    }
+
+    public File getRoot() {
+        return rootDir;
+    }
+
+    public File getJcrRoot() {
+        return jcrRoot;
+    }
+
+    public File getMetaDir() {
+        return metaDir;
+    }
+
+    public static ExportRoot findRoot(File cwd) {
+        if (cwd == null) {
+            return null;
+        }
+        // find root
+        File jcrRoot = new File(cwd, Constants.ROOT_DIR);
+        if (!jcrRoot.exists() || !jcrRoot.isDirectory()) {
+            jcrRoot = cwd;
+            while (jcrRoot != null) {
+                if (!jcrRoot.exists()) {
+                    jcrRoot = null;
+                } else {
+                    if (jcrRoot.getName().equals(Constants.ROOT_DIR)) {
+                        break;
+                    }
+                    jcrRoot = jcrRoot.getParentFile();
+                }
+            }
+        }
+
+        if (jcrRoot == null) {
+            log.info("could not find " + Constants.ROOT_DIR + " along the ancestors of {}", cwd.getPath());
+            return null;
+        }
+        return new ExportRoot(jcrRoot.getParentFile());
+    }
+
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/MetaInf.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/MetaInf.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/MetaInf.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/MetaInf.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,114 @@
+/*
+ * 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.util.Collection;
+import java.util.Properties;
+
+import org.apache.jackrabbit.vault.fs.api.VaultFsConfig;
+import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter;
+import org.apache.jackrabbit.vault.fs.spi.NodeTypeSet;
+import org.apache.jackrabbit.vault.fs.spi.PrivilegeDefinitions;
+
+/**
+ * Abstracts the way of accessing the vault specific meta-info of a checkout.
+ */
+public interface MetaInf {
+
+    /**
+     * Format Version 1. Used for content assembled until Vault 1.2.8
+     * @since 2.0
+     */
+    public static int FORMAT_VERSION_1 = 1;
+
+    /**
+     * Format Version 2. Used for content assembled since Vault 1.2.9
+     * @since 2.0
+     */
+    public static int FORMAT_VERSION_2 = 2;
+
+    /**
+     * Name of the package format version
+     * @since 2.0
+     */
+    public static String PACKAGE_FORMAT_VERSION = "packageFormatVersion";
+
+    /**
+     * Name of the 'created' property
+     */
+    public static String CREATED = "created";
+
+    /**
+     * Name of the 'created by' property
+     */
+    public static String CREATED_BY = "createdBy";
+    
+    /**
+     * Returns the package format version of this package. If the package
+     * lacks this information, {@link #FORMAT_VERSION_2} is returned, since this
+     * feature was implemented recently.
+     *
+     * @return the package format version
+     * @since 2.0
+     */
+    int getPackageFormatVersion();
+
+    /**
+     * Returns the vault settings.
+     * @return the vault settings.
+     */
+    VaultSettings getSettings();
+
+    /**
+     * Returns the workspace filter.
+     * @return the workspace filter.
+     */
+    WorkspaceFilter getFilter();
+
+    /**
+     * Returns the vault config
+     * @return the vault config
+     */
+    VaultFsConfig getConfig();
+
+    /**
+     * Returns the properties
+     * @return the properties
+     */
+    Properties getProperties();
+
+    /**
+     * Returns the node types
+     * @return the node types
+     */
+    Collection<NodeTypeSet> getNodeTypes();
+
+    /**
+     * Returns custom privileges defined in the meta inf.
+     * @return a collection of custom privileges.
+     * @since 3.0
+     */
+    PrivilegeDefinitions getPrivileges();
+    
+    /**
+     * Checks if the meta-inf contains a serialized definition.
+     * @return <code>true</code> if it contains a serialized definition.
+     */
+    boolean hasDefinition();
+
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/Registry.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/Registry.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/Registry.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/Registry.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,97 @@
+/*
+ * 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.util.HashMap;
+import java.util.Map;
+
+import org.apache.jackrabbit.vault.fs.api.Aggregator;
+import org.apache.jackrabbit.vault.fs.api.ArtifactHandler;
+import org.apache.jackrabbit.vault.fs.impl.aggregator.FileAggregator;
+import org.apache.jackrabbit.vault.fs.impl.aggregator.FileFolderAggregator;
+import org.apache.jackrabbit.vault.fs.impl.aggregator.FullCoverageAggregator;
+import org.apache.jackrabbit.vault.fs.impl.aggregator.GenericAggregator;
+import org.apache.jackrabbit.vault.fs.impl.aggregator.NodeTypeAggregator;
+import org.apache.jackrabbit.vault.fs.impl.io.FileArtifactHandler;
+import org.apache.jackrabbit.vault.fs.impl.io.FolderArtifactHandler;
+import org.apache.jackrabbit.vault.fs.impl.io.GenericArtifactHandler;
+import org.apache.jackrabbit.vault.fs.impl.io.NodeTypeArtifactHandler;
+
+/**
+ * <code>Registry</code>...
+ */
+public class Registry {
+
+    public static Registry instance;
+
+    private final Map<String, Class<? extends Aggregator>> aggregators;
+
+    private final Map<String, Class<? extends ArtifactHandler>> handlers;
+
+    public synchronized static Registry getInstance() {
+        if (instance == null) {
+            instance = new Registry();
+        }
+        return instance;
+    }
+
+    private Registry() {
+        aggregators = new HashMap<String, Class<? extends Aggregator>>();
+        aggregators.put("file", FileAggregator.class);
+        aggregators.put("full", FullCoverageAggregator.class);
+        aggregators.put("generic", GenericAggregator.class);
+        aggregators.put("nodetype", NodeTypeAggregator.class);
+        aggregators.put("filefolder", FileFolderAggregator.class);
+
+        handlers = new HashMap<String, Class<? extends ArtifactHandler>>();
+        handlers.put("file", FileArtifactHandler.class);
+        handlers.put("folder", FolderArtifactHandler.class);
+        handlers.put("nodetype", NodeTypeArtifactHandler.class);
+        handlers.put("generic", GenericArtifactHandler.class);
+    }
+
+    public Class<? extends Aggregator> getAggregatorClass(String type) {
+        return aggregators.get(type);
+    }
+
+    public Class<? extends ArtifactHandler> getHandlerClass(String type) {
+        return handlers.get(type);
+    }
+
+    public Aggregator createAggregator(String type) {
+        if (aggregators.containsKey(type)) {
+            try {
+                return aggregators.get(type).newInstance();
+            } catch (Exception e) {
+                throw new IllegalArgumentException("Unable to create aggregator of type: " + type, e);
+            }
+        }
+        return null;
+    }
+
+    public ArtifactHandler createHandler(String type) {
+        if (handlers.containsKey(type)) {
+            try {
+                return handlers.get(type).newInstance();
+            } catch (Exception e) {
+                throw new IllegalArgumentException("Unable to create handler of type: " + type, e);
+            }
+        }
+        return null;
+    }
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/SimpleCredentialsConfig.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/SimpleCredentialsConfig.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/SimpleCredentialsConfig.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/SimpleCredentialsConfig.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,80 @@
+/*
+ * 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 javax.jcr.Credentials;
+import javax.jcr.SimpleCredentials;
+
+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>SimpleCredentialsConfig</code>...
+*
+*/
+public class SimpleCredentialsConfig extends CredentialsConfig {
+
+    private final SimpleCredentials creds;
+    public static final String ELEM_USER = "user";
+    public static final String ATTR_NAME = "name";
+    public static final String ATTR_PASSWORD = "password";
+
+    public SimpleCredentialsConfig(SimpleCredentials creds) {
+        super("simple");
+        this.creds = creds;
+    }
+
+    public Credentials getCredentials() {
+        return creds;
+    }
+
+    public static SimpleCredentialsConfig load(Element elem) throws ConfigurationException {
+        assert elem.getNodeName().equals(ELEM_CREDETIALS);
+
+        NodeList nl = elem.getChildNodes();
+        for (int i=0; i<nl.getLength(); i++) {
+            Node child = nl.item(i);
+            if (child.getNodeType() == Node.ELEMENT_NODE) {
+                if (child.getNodeName().equals(ELEM_USER)) {
+                    Element e = (Element) child;
+                    String name = e.getAttribute(ATTR_NAME);
+                    String pass = e.getAttribute(ATTR_PASSWORD);
+                    return new SimpleCredentialsConfig(
+                            new SimpleCredentials(
+                                    name,
+                                    pass == null ? new char[0] : pass.toCharArray()));
+                }
+            }
+        }
+        throw new ConfigurationException("mandatory element <user> missing.");
+    }
+
+    public void writeInner(ContentHandler handler) throws SAXException {
+        if (creds != null) {
+            AttributesImpl attrs = new AttributesImpl();
+            attrs.addAttribute("", ATTR_NAME, "", "CDATA", creds.getUserID());
+            attrs.addAttribute("", ATTR_PASSWORD, "", "CDATA", new String(creds.getPassword()));
+            handler.startElement("", ELEM_USER, "", attrs);
+            handler.endElement("", ELEM_USER, "");
+        }
+    }
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/VaultAuthConfig.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/VaultAuthConfig.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/VaultAuthConfig.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/VaultAuthConfig.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,140 @@
+/*
+ * 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.util.HashMap;
+import java.util.Map;
+
+import org.apache.jackrabbit.vault.util.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+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>...
+ *
+ */
+public class VaultAuthConfig extends AbstractConfig {
+
+    protected static Logger log = LoggerFactory.getLogger(VaultAuthConfig.class);
+
+    public static final String ELEM_REPOSITORY = "repository";
+    public static final String ATTR_URI = "uri";
+
+    private final Map<String, RepositoryConfig> repoConfigs = new HashMap<String, RepositoryConfig>();
+
+    protected void doLoad(Element child) throws ConfigurationException {
+        if (!child.getNodeName().equals(ELEM_REPOSITORY)) {
+            throw new ConfigurationException("unexpected element: " + child.getLocalName());
+        }
+        RepositoryConfig cfg = RepositoryConfig.load(child);
+        if (cfg != null) {
+            repoConfigs.put(cfg.uri, cfg);
+        }
+    }
+
+    protected String getRootElemName() {
+        return "auth";
+    }
+
+    protected double getSupportedVersion() {
+        return 1.0;
+    }
+
+    public RepositoryConfig getRepoConfig(String uri) {
+        return repoConfigs.get(uri);
+    }
+
+    public void addRepositoryConfig(RepositoryConfig cfg) {
+        repoConfigs.put(cfg.uri, cfg);
+    }
+
+    protected void doWrite(ContentHandler handler) throws SAXException {
+        for (RepositoryConfig cfg: repoConfigs.values()) {
+            cfg.write(handler);
+        }
+    }
+
+    public boolean load() throws IOException, ConfigurationException {
+        return load(new File(getConfigDir(), Constants.AUTH_XML));
+    }
+
+    public void save() throws IOException {
+        save(new File(getConfigDir(), Constants.AUTH_XML));
+    }
+
+    public static class RepositoryConfig {
+
+        public final String uri;
+
+        public CredentialsConfig creds;
+
+        public RepositoryConfig(String uri) {
+            this.uri = uri;
+        }
+
+        public CredentialsConfig getCredsConfig() {
+            return creds;
+        }
+
+        public void addCredsConfig(CredentialsConfig creds) {
+            this.creds = creds;
+        }
+
+        public static RepositoryConfig load(Element elem) throws ConfigurationException {
+            assert elem.getNodeName().equals(ELEM_REPOSITORY);
+
+            String uri = elem.getAttribute(ATTR_URI);
+            if (uri == null) {
+                throw new ConfigurationException("missing attribute: " + ATTR_URI);
+            }
+            RepositoryConfig cfg = new RepositoryConfig(uri);
+            NodeList nl = elem.getChildNodes();
+            for (int i=0; i<nl.getLength(); i++) {
+                Node child = nl.item(i);
+                if (child.getNodeType() == Node.ELEMENT_NODE) {
+                    if (child.getNodeName().equals(CredentialsConfig.ELEM_CREDETIALS)) {
+                        CredentialsConfig ccfg = CredentialsConfig.load((Element) child);
+                        if (ccfg != null) {
+                            cfg.creds = ccfg;
+                        }
+                    } else {
+                        throw new ConfigurationException("unexpected element: " + child.getLocalName());
+                    }
+                }
+            }
+            return cfg;
+        }
+
+        public void write(ContentHandler handler) throws SAXException {
+            AttributesImpl attrs = new AttributesImpl();
+            attrs.addAttribute("", ATTR_URI, "", "CDATA", uri);
+            handler.startElement("", ELEM_REPOSITORY, "", attrs);
+            creds.write(handler);
+            handler.endElement("", ELEM_REPOSITORY, "");
+        }
+    }
+
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/VaultFsConfig11.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/VaultFsConfig11.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/VaultFsConfig11.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/VaultFsConfig11.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,190 @@
+/*
+ * 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.util.Map;
+
+import org.apache.jackrabbit.vault.fs.api.Aggregator;
+import org.apache.jackrabbit.vault.fs.api.ArtifactHandler;
+import org.apache.jackrabbit.vault.fs.api.ItemFilter;
+import org.apache.jackrabbit.vault.fs.api.ItemFilterSet;
+import org.apache.jackrabbit.vault.fs.filter.IsMandatoryFilter;
+import org.apache.jackrabbit.vault.fs.filter.IsNodeFilter;
+import org.apache.jackrabbit.vault.fs.filter.NameItemFilter;
+import org.apache.jackrabbit.vault.fs.filter.NodeTypeItemFilter;
+import org.apache.jackrabbit.vault.fs.impl.aggregator.GenericAggregator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+
+/**
+ * <code>JcrFsConfig</code>...
+ */
+class VaultFsConfig11 extends AbstractVaultFsConfig {
+
+    /**
+     * the default logger
+     */
+    private static final Logger log = LoggerFactory.getLogger(VaultFsConfig11.class);
+
+    public static final double SUPPORTED_VERSION = 1.1;
+
+    private final ConfigHelper helper = new ConfigHelper();
+
+    @SuppressWarnings("unchecked")
+    public VaultFsConfig11() {
+        helper.getDefaultPackages().put("include", "org.apache.jackrabbit.vault.fs.filter");
+        helper.getDefaultPackages().put("exclude", "org.apache.jackrabbit.vault.fs.filter");
+
+        // add renamed classes from prior versions
+        Map<String, String> m = helper.getMappings();
+        m.put("org.apache.jackrabbit.vault.fs.imprt.FolderArtifactHandler", "org.apache.jackrabbit.vault.fs.impl.io.FileArtifactHandler");
+        m.put("org.apache.jackrabbit.vault.fs.imprt.FileArtifactHandler", "org.apache.jackrabbit.vault.fs.impl.io.FileArtifactHandler");
+        m.put("org.apache.jackrabbit.vault.fs.imprt.GenericArtifactHandler", "org.apache.jackrabbit.vault.fs.impl.io.GenericArtifactHandler");
+        m.put("org.apache.jackrabbit.vault.fs.imprt.NodeTypeArtifactHandler", "org.apache.jackrabbit.vault.fs.impl.io.NodeTypeArtifactHandler");
+
+
+        m.put("org.apache.jackrabbit.vault.fs.filter.ItemFilter", "org.apache.jackrabbit.vault.fs.api.ItemFilter");
+        m.put("org.apache.jackrabbit.vault.fs.filter.PathFilter", "org.apache.jackrabbit.vault.fs.api.PathFilter");
+    }
+
+    protected void process(Element elem) throws ConfigurationException {
+        for (Element child: getChildElements(elem)) {
+            if (child.getNodeName().equals("aggregates")) {
+                for (Element agg: getChildElements(child)) {
+                    if (agg.getNodeName().equals("aggregate")) {
+                        processAggregate(agg);
+                    } else {
+                        log.warn("Unkown element name in config: " + agg.getNodeName());
+                    }
+                }
+
+            } else if (child.getNodeName().equals("handlers")) {
+                for (Element handler: getChildElements(child)) {
+                    if (handler.getNodeName().equals("handler")) {
+                        processHandler(handler);
+                    } else {
+                        log.warn("Unkown element name in config: " + handler.getNodeName());
+                    }
+                }
+
+            } else {
+                log.warn("Unkown element name in config: " + child.getNodeName());
+            }
+        }
+    }
+
+    private void processAggregate(Element elem) throws ConfigurationException {
+        String type = elem.getAttribute("type");
+        if (type == null || type.equals("")) {
+            type = "generic";
+        }
+        Aggregator aggregator = Registry.getInstance().createAggregator(type);
+        if (aggregator == null) {
+            fail("Aggregator of type " + type + " is not registered.", elem);
+        }
+        if (aggregator instanceof GenericAggregator) {
+            GenericAggregator ga = (GenericAggregator) aggregator;
+            String title = elem.getAttribute("title");
+            if (title != null) {
+                ga.setName(title);
+            }
+            if ("true".equals(elem.getAttribute("isDefault"))) {
+                ga.setIsDefault("true");
+            }
+            for (Element child: getChildElements(elem)) {
+                if (child.getNodeName().equals("matches")) {
+                    processFilter(ga.getMatchFilter(), child);
+                } else if (child.getNodeName().equals("contains")) {
+                    processFilter(ga.getContentFilter(), child);
+                }
+            }
+        }
+        // finally add aggregator
+        getAggregators().add(aggregator);
+    }
+
+    private void processFilter(ItemFilterSet filterSet, Element elem)
+            throws ConfigurationException {
+        for (Element child: getChildElements(elem)) {
+            Boolean isInclude = null;
+            if (child.getNodeName().equals("include")) {
+                isInclude = true;
+            } else if (child.getNodeName().equals("exclude")) {
+                isInclude = false;
+            } else {
+                log.warn("Unknown filter type in list: " + child.getNodeName());
+            }
+            if (isInclude != null) {
+                try {
+                    NamedNodeMap attrs = child.getAttributes();
+                    ItemFilter filter = null;
+                    String clazz = child.getAttribute("class");
+                    if (clazz != null && clazz.length() > 0) {
+                        filter = (ItemFilter) helper.create(child);
+                    } else {
+                        // create filter based on some attributes
+                        if (attrs.getNamedItem("nodeType") != null) {
+                            filter = new NodeTypeItemFilter();
+                        } else if (attrs.getNamedItem("isNode") != null) {
+                            filter = new IsNodeFilter();
+                        } else if (attrs.getNamedItem("name") != null) {
+                            filter = new NameItemFilter();
+                        } else if (attrs.getNamedItem("isMandatory") != null) {
+                            filter = new IsMandatoryFilter();
+                        }
+                    }
+                    if (filter != null) {
+                        for (int i=0; i<attrs.getLength(); i++) {
+                            Attr attr = (Attr) attrs.item(i);
+                            if (ConfigHelper.hasSetter(filter, attr.getName())) {
+                                ConfigHelper.setField(filter, attr.getName(), attr.getValue());
+                            }
+                        }
+                        if (isInclude) {
+                            filterSet.addInclude(filter);
+                        } else {
+                            filterSet.addExclude(filter);
+                        }
+                    }
+                } catch (ConfigurationException e) {
+                    throw e;
+                } catch (Exception e) {
+                    fail("Error while processing: " + e, child);
+                }
+            }
+        }
+    }
+
+    private void processHandler(Element elem) throws ConfigurationException {
+        String type = elem.getAttribute("type");
+        if (type == null || type.equals("")) {
+            type = "generic";
+        }
+        ArtifactHandler handler = Registry.getInstance().createHandler(type);
+        if (handler == null) {
+            fail("Handler of type " + type + " is not registered.", elem);
+        }
+        // finally add handler
+        getHandlers().add(handler);
+    }
+
+
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/VaultSettings.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/VaultSettings.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/VaultSettings.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/config/VaultSettings.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,85 @@
+/*
+ * 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.util.HashSet;
+import java.util.Set;
+
+import org.w3c.dom.Element;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * <code>VaultUserConfig</code>...
+ *
+ */
+public class VaultSettings extends AbstractConfig {
+
+    public static final String ELEM_IGNORE = "ignore";
+
+    public static final String ATTR_IGNORE_NAME = "name";
+
+    private Set<String> ignores = new HashSet<String>();
+
+    public Set<String> getIgnoredNames() {
+        return ignores;
+    }
+
+    protected void doLoad(Element child) throws ConfigurationException {
+        if (child.getNodeName().equals(ELEM_IGNORE)) {
+            loadIgnore(child);
+        } else {
+            throw new ConfigurationException("unexpected element: " + child.getLocalName());
+        }
+    }
+
+    public boolean isIgnored(String name) {
+        return ignores.contains(name);
+    }
+
+    private void loadIgnore(Element ignore) {
+        String name = ignore.getAttribute(ATTR_IGNORE_NAME);
+        if (name != null) {
+            ignores.add(name);
+        }
+    }
+
+    protected String getRootElemName() {
+        return "vault";
+    }
+
+    protected double getSupportedVersion() {
+        return 1.0;
+    }
+
+    protected void doWrite(ContentHandler handler) throws SAXException {
+        for (String ignore: ignores) {
+            AttributesImpl attrs = new AttributesImpl();
+            attrs.addAttribute("", ATTR_IGNORE_NAME, "", "CDATA", ignore);
+            handler.startElement("", ELEM_IGNORE, "", attrs);
+            handler.endElement("", ELEM_IGNORE, "");
+        }
+    }
+
+    public static VaultSettings createDefault() {
+        VaultSettings s = new VaultSettings();
+        s.ignores.add(".svn");
+        return s;
+    }
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/filter/BaseFilter.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/filter/BaseFilter.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/filter/BaseFilter.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/filter/BaseFilter.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,72 @@
+/*
+ * 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.filter;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.PropertyIterator;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.vault.fs.api.DumpContext;
+import org.apache.jackrabbit.vault.fs.api.ItemFilter;
+import org.apache.jackrabbit.vault.util.JcrConstants;
+
+/**
+ * Implements an item filter that matches if a node only has the primary
+ * properties: jcr:primaryType, jcr:mixinTypes, jcr:uuid, jcr:created and
+ * jcr:createdBy
+ */
+public class BaseFilter implements ItemFilter {
+
+    private static final Set<String> validNames = new HashSet<String>();
+    static {
+        validNames.add(JcrConstants.JCR_PRIMARYTYPE);
+        validNames.add(JcrConstants.JCR_MIXINTYPES);
+        validNames.add(JcrConstants.JCR_UUID);
+        validNames.add(JcrConstants.JCR_CREATED);
+        validNames.add(JcrConstants.JCR_CREATED_BY);
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean matches(Item item, int depth) throws RepositoryException {
+        if (item.isNode()) {
+            PropertyIterator iter = ((Node) item).getProperties();
+            while (iter.hasNext()) {
+                String name = iter.nextProperty().getName();
+                if (!validNames.contains(name)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void dump(DumpContext ctx, boolean isLast) {
+        ctx.printf(isLast, "%s:", getClass().getSimpleName());
+    }
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/filter/DeclaringTypeItemFilter.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/filter/DeclaringTypeItemFilter.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/filter/DeclaringTypeItemFilter.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/filter/DeclaringTypeItemFilter.java Sat Aug 10 05:53:42 2013
@@ -0,0 +1,114 @@
+/*
+ * 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.filter;
+
+import javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.vault.fs.api.DumpContext;
+
+/**
+ * Filter that checks the declared type of an item
+ *
+ */
+public class DeclaringTypeItemFilter extends DepthItemFilter {
+
+    /**
+     * The node type to check
+     */
+    private String nodeType;
+
+    /**
+     * indicates if only props should be checked
+     */
+    private boolean propsOnly;
+
+    /**
+     * Default constructor.
+     */
+    public DeclaringTypeItemFilter() {
+    }
+
+    /**
+     * Creates a new filter for the given node type and flags.
+     * @param nodeType the node type name to check
+     * @param propsOnly if <code>true</code> only properties are checked
+     * @param minDepth the minimal depth
+     * @param maxDepth the maximal depth
+     */
+    public DeclaringTypeItemFilter(String nodeType, boolean propsOnly,
+                                   int minDepth, int maxDepth) {
+        super(minDepth, maxDepth);
+        this.nodeType = nodeType;
+        this.propsOnly = propsOnly;
+    }
+
+    /**
+     * Creates a new filter for the given node type and flags
+     * @param nodeType the node type name to check
+     * @param propsOnly if <code>true</code> only properties are checked
+     */
+    public DeclaringTypeItemFilter(String nodeType, boolean propsOnly) {
+        this(nodeType, propsOnly, 0, Integer.MAX_VALUE);
+    }
+
+    /**
+     * Sets the node type to match the declaring one of the item
+     * @param nodeType the node type
+     */
+    public void setNodeType(String nodeType) {
+        this.nodeType = nodeType;
+    }
+
+    /**
+     * Sets the flag that indicates if only properties are to be checked.
+     * @param propsOnly if <code>true</code> only properties are checked.
+     */
+    public void setPropsOnly(String propsOnly) {
+        this.propsOnly = Boolean.valueOf(propsOnly);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Matches if the declaring node type of the item is equal to the one
+     * specified in this filter. If the item is a node and <code>propsOnly</code>
+     * flag is <code>true</code> it returns <code>false</code>.
+     */
+    public boolean matches(Item item) throws RepositoryException {
+        if (item.isNode()) {
+            return !propsOnly && ((Node) item).getDefinition().getDeclaringNodeType().getName().equals(nodeType);
+        } else {
+            return ((Property) item).getDefinition().getDeclaringNodeType().getName().equals(nodeType);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void dump(DumpContext ctx, boolean isLast) {
+        super.dump(ctx, isLast);
+        ctx.indent(isLast);
+        ctx.printf(false, "nodeType: %s", nodeType);
+        ctx.printf(true, "propsOnly: %b", propsOnly);
+        ctx.outdent();
+    }
+    
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/filter/DefaultPathFilter.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/filter/DefaultPathFilter.java?rev=1512568&view=auto
==============================================================================
--- jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/filter/DefaultPathFilter.java (added)
+++ jackrabbit/commons/filevault/trunk/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/filter/DefaultPathFilter.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.filter;
+
+import java.util.regex.Pattern;
+
+import org.apache.jackrabbit.vault.fs.api.DumpContext;
+import org.apache.jackrabbit.vault.fs.api.PathFilter;
+import org.apache.jackrabbit.vault.fs.api.PathMapping;
+
+/**
+ * The default path filter provides hierarchical filtering.
+ *
+ */
+public class DefaultPathFilter implements PathFilter {
+
+    /**
+     * the internal regex pattern
+     */
+    private Pattern regex;
+
+    /**
+     * Default constructor
+     */
+    public DefaultPathFilter() {
+    }
+
+    /**
+     * Creates a new default path filter
+     * @param pattern the pattern
+     * @see #setPattern
+     */
+    public DefaultPathFilter(String pattern) {
+        setPattern(pattern);
+    }
+
+    /**
+     * Sets the regexp pattern for this filter.
+     *
+     * Examples:
+     * <xmp>
+     * | Pattern        | Matches
+     * | /foo           | exactly "/foo"
+     * | /foo.*         | all paths starting with "/foo"
+     * | ^.* /foo[^/]*$ | all files starting with "foo"
+     * | /foo/[^/]*$    | all direct children of /foo
+     * | /foo/.*        | all children of /foo
+     * | /foo(/.*)?     | all children of /foo and foo itself
+     * </xmp>
+     *
+     * @param pattern the pattern.
+     */
+    public void setPattern(String pattern) {
+        regex = Pattern.compile(pattern);
+    }
+
+    /**
+     * Returns the pattern
+     * @return the pattern
+     */
+    public String getPattern() {
+        return regex.pattern();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean matches(String path) {
+        return regex.matcher(path).matches();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isAbsolute() {
+        return regex.pattern().startsWith("/");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public PathFilter translate(PathMapping mapping) {
+        if (mapping == null) {
+            return this;
+        }
+        String pattern = regex.pattern();
+        if (!pattern.startsWith("/")) {
+            return this;
+        }
+        return new DefaultPathFilter(mapping.map(pattern));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public void dump(DumpContext ctx, boolean isLast) {
+        ctx.printf(isLast, "%s:", getClass().getSimpleName());
+        ctx.indent(isLast);
+        ctx.printf(true, "regex: %s", regex.toString());
+        ctx.outdent();
+    }
+}
\ No newline at end of file