Index: src/test/java/org/modeshape/connector/filesystem/InclusionExclusionFilenameFilterTest.java =================================================================== --- src/test/java/org/modeshape/connector/filesystem/InclusionExclusionFilenameFilterTest.java (revision 0) +++ src/test/java/org/modeshape/connector/filesystem/InclusionExclusionFilenameFilterTest.java (revision 0) @@ -0,0 +1,73 @@ +/* + * ModeShape (http://www.modeshape.org) + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. Some portions may be licensed + * to Red Hat, Inc. under one or more contributor license agreements. + * See the AUTHORS.txt file in the distribution for a full listing of + * individual contributors. + * + * ModeShape is free software. Unless otherwise indicated, all code in ModeShape + * is licensed to you under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * ModeShape is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.modeshape.connector.filesystem; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author johnament + */ +public class InclusionExclusionFilenameFilterTest { + + private InclusionExclusionFilenameFilter filter; + + @Before + public void setUp() { + filter = new InclusionExclusionFilenameFilter(); + } + + @Test + public void testEmptyFilter() { + assertTrue(filter.accept(null, "anystring")); + } + + @Test + public void testInclusionOnly() { + filter.setInclusionPattern("(.+)\\.mode"); + assertTrue(filter.accept(null, "myfile.mode")); + assertFalse(filter.accept(null,"anotherfile.txt")); + } + + @Test + public void testExclusionOnly() { + filter.setExclusionPattern("(.+)\\.mode"); + assertFalse(filter.accept(null, "myfile.mode")); + assertTrue(filter.accept(null,"anotherfile.txt")); + } + + @Test + public void testInclusionExclusion() { + filter.setInclusionPattern("(.+)\\.mode"); + filter.setExclusionPattern("ignore_me(.+)\\.mode"); + assertTrue(filter.accept(null,"validfile.mode")); + assertFalse(filter.accept(null,"ignore_meinvalidfile.mode")); + } + +} \ No newline at end of file Index: src/test/java/org/modeshape/connector/filesystem/FileSystemConnectorWritableTest.java =================================================================== --- src/test/java/org/modeshape/connector/filesystem/FileSystemConnectorWritableTest.java (revision 2557) +++ src/test/java/org/modeshape/connector/filesystem/FileSystemConnectorWritableTest.java (working copy) @@ -78,6 +78,7 @@ source.setCreatingWorkspacesAllowed(true); source.setUpdatesAllowed(true); source.setExclusionPattern("\\.svn"); + source.setInclusionPattern(".+"); testWorkspaceRoot = new File(REPO_PATH, "test"); testWorkspaceRoot.mkdir(); Index: src/test/java/org/modeshape/connector/filesystem/ModeOnlyFilenameFilter.java =================================================================== --- src/test/java/org/modeshape/connector/filesystem/ModeOnlyFilenameFilter.java (revision 0) +++ src/test/java/org/modeshape/connector/filesystem/ModeOnlyFilenameFilter.java (revision 0) @@ -0,0 +1,17 @@ +package org.modeshape.connector.filesystem; + +import java.io.File; +import java.io.FilenameFilter; + +/** + * + * @author johnament + */ +public class ModeOnlyFilenameFilter implements FilenameFilter { + + @Override + public boolean accept(File file, String string) { + return string.endsWith(".mode"); + } + +} Index: src/main/java/org/modeshape/connector/filesystem/InclusionExclusionFilenameFilter.java =================================================================== --- src/main/java/org/modeshape/connector/filesystem/InclusionExclusionFilenameFilter.java (revision 0) +++ src/main/java/org/modeshape/connector/filesystem/InclusionExclusionFilenameFilter.java (revision 0) @@ -0,0 +1,84 @@ +/* + * ModeShape (http://www.modeshape.org) + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. Some portions may be licensed + * to Red Hat, Inc. under one or more contributor license agreements. + * See the AUTHORS.txt file in the distribution for a full listing of + * individual contributors. + * + * ModeShape is free software. Unless otherwise indicated, all code in ModeShape + * is licensed to you under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * ModeShape is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.modeshape.connector.filesystem; + +import java.io.File; +import java.util.regex.Pattern; + +/** + * Provides basic filename filter implementation for simple inclusion/exclusion pattern. + * + * @author johnament + */ +public class InclusionExclusionFilenameFilter implements java.io.FilenameFilter { + private String inclusionPattern = null; + private String exclusionPattern = null; + private Pattern inclusion; + private Pattern exclusion; + + public void setExclusionPattern(String exclusionPattern) { + this.exclusionPattern = exclusionPattern; + if(exclusionPattern == null) { + this.exclusion = null; + } else { + this.exclusion = Pattern.compile(exclusionPattern); + } + } + + public void setInclusionPattern(String inclusionPattern) { + this.inclusionPattern = inclusionPattern; + if(inclusionPattern == null) { + this.inclusion = null; + } else { + this.inclusion = Pattern.compile(inclusionPattern); + } + } + + public String getExclusionPattern() { + return exclusionPattern; + } + + public String getInclusionPattern() { + return inclusionPattern; + } + + @Override + public boolean accept(File file, String string) { + if(inclusionPattern == null && exclusionPattern == null) { + return true; + } else if (inclusionPattern == null && exclusionPattern != null) { + return !exclusion.matcher(string).matches(); + //return !string.matches(exclusionPattern); + } else { + if(exclusionPattern == null) { + return inclusion.matcher(string).matches(); +// return string.matches(inclusionPattern); + } + return inclusion.matcher(string).matches() && + !exclusion.matcher(string).matches(); + //return string.matches(inclusionPattern) && !string.matches(exclusionPattern); + } + } + +} Index: src/main/java/org/modeshape/connector/filesystem/FileSystemSource.java =================================================================== --- src/main/java/org/modeshape/connector/filesystem/FileSystemSource.java (revision 2557) +++ src/main/java/org/modeshape/connector/filesystem/FileSystemSource.java (working copy) @@ -81,6 +81,7 @@ protected static final String ALLOW_CREATING_WORKSPACES = "allowCreatingWorkspaces"; protected static final String MAX_PATH_LENGTH = "maxPathLength"; protected static final String EXCLUSION_PATTERN = "exclusionPattern"; + protected static final String INCLUSION_PATTERN = "inclusionPattern"; protected static final String FILENAME_FILTER = "filenameFilter"; protected static final String CUSTOM_PROPERTY_FACTORY = "customPropertyFactory"; protected static final String EAGER_FILE_LOADING = "eagerFileLoading"; @@ -126,17 +127,10 @@ public static final int DEFAULT_MAX_PATH_LENGTH = 255; // 255 for windows users public static final String DEFAULT_EXCLUSION_PATTERN = null; + public static final String DEFAULT_INCLUSION_PATTERN = null; public static final FilenameFilter DEFAULT_FILENAME_FILTER = null; - private static final FilenameFilter ACCEPT_ALL_FILTER = new FilenameFilter() { + private static final FilenameFilter ACCEPT_ALL_FILTER = new InclusionExclusionFilenameFilter(); - @Override - public boolean accept( File file, - String filename ) { - return true; - } - - }; - protected static Map EXTRA_PROPERTIES_CLASSNAME_BY_KEY; static { @@ -173,6 +167,11 @@ @Category( i18n = FileSystemI18n.class, value = "exclusionPatternPropertyCategory" ) private volatile String exclusionPattern = DEFAULT_EXCLUSION_PATTERN; + @Description( i18n = FileSystemI18n.class, value = "inclusionPatternPropertyDescription" ) + @Label( i18n = FileSystemI18n.class, value = "inclusionPatternPropertyLabel" ) + @Category( i18n = FileSystemI18n.class, value = "inclusionPatternPropertyCategory" ) + private volatile String inclusionPattern = DEFAULT_INCLUSION_PATTERN; + @Description( i18n = FileSystemI18n.class, value = "eagerFileLoadingPropertyDescription" ) @Label( i18n = FileSystemI18n.class, value = "eagerFileLoadingPropertyLabel" ) @Category( i18n = FileSystemI18n.class, value = "eagerFileLoadingPropertyCategory" ) @@ -189,6 +188,9 @@ private volatile String extraProperties = DEFAULT_EXTRA_PROPERTIES; private volatile FilenameFilter filenameFilter = DEFAULT_FILENAME_FILTER; + private volatile InclusionExclusionFilenameFilter inclusionExclusionFilenameFilter + = new InclusionExclusionFilenameFilter(); + private volatile RepositorySourceCapabilities capabilities = new RepositorySourceCapabilities( SUPPORTS_SAME_NAME_SIBLINGS, DEFAULT_SUPPORTS_UPDATES, @@ -251,25 +253,48 @@ * may be null */ public String getExclusionPattern() { - return exclusionPattern; + return this.inclusionExclusionFilenameFilter.getExclusionPattern(); } /** * Sets the regular expression that, if matched by a file or folder, indicates that the file or folder should be ignored *

- * Only one of the {@code exclusionPattern} and {@code filenameFilter} properties may be non-null at any one time. Calling - * this method automatically sets the {@code filenameFilter} property to {@code null}. + * Only one of FilenameFilter or Inclusion/Exclusion Pattern are used at a given time. If Inclusion/exclusion are set, then + * FilenameFilter is ignored. *

* * @param exclusionPattern the regular expression that, if matched by a file or folder, indicates that the file or folder * should be ignored. If this pattern is {@code null}, no files will be excluded. */ public synchronized void setExclusionPattern( String exclusionPattern ) { - this.exclusionPattern = exclusionPattern; - this.filenameFilter = null; + this.inclusionExclusionFilenameFilter.setExclusionPattern(exclusionPattern); } /** + * Get the regular expression that, if matched by a file or folder, indicates that the file or folder should be included + * + * @return the regular expression that, if matched by a file or folder, indicates that the file or folder should be included; + * may be null + */ + public String getInclusionPattern() { + return this.inclusionExclusionFilenameFilter.getInclusionPattern(); + } + + /** + * Sets the regular expression that, if matched by a file or folder, indicates that the file or folder should be included + *

+ * Only one of FilenameFilter or Inclusion/Exclusion Pattern are used at a given time. If Inclusion/exclusion are set, then + * FilenameFilter is ignored. + *

+ * + * @param exclusionPattern the regular expression that, if matched by a file or folder, indicates that the file or folder + * should be ignored. If this pattern is {@code null}, no files will be excluded. + */ + public synchronized void setInclusionPattern( String inclusionPattern ) { + this.inclusionExclusionFilenameFilter.setInclusionPattern(inclusionPattern); + } + + /** * @return the {@FilenameFilter filename filter} (if any) that is used to restrict which content can be * accessed by this connector; may be null */ @@ -280,8 +305,8 @@ /** * Sets the filename filter that is used to restrict which content can be accessed by this connector *

- * Only one of the {@code exclusionPattern} and {@code filenameFilter} properties may be non-null at any one time. Calling - * this method automatically sets the {@code exclusionPattern} property to {@code null}. + * Only one of FilenameFilter or Inclusion/Exclusion Pattern are used at a given time. If Inclusion/exclusion are set, then + * FilenameFilter is ignored. *

* * @param filenameFilter the filename filter that is used to restrict which content can be accessed by this connector. If this @@ -289,7 +314,6 @@ */ public synchronized void setFilenameFilter( FilenameFilter filenameFilter ) { this.filenameFilter = filenameFilter; - this.exclusionPattern = null; } /** @@ -319,15 +343,16 @@ Class filenameFilterClass = Class.forName(filenameFilterClassName); this.filenameFilter = (FilenameFilter)filenameFilterClass.newInstance(); - this.exclusionPattern = null; } FilenameFilter filenameFilter( boolean hideFilesForCustomProperties ) { if (this.filenameFilter != null) return this.filenameFilter; + if (this.getInclusionPattern() != null || this.getExclusionPattern() != null) + return this.inclusionExclusionFilenameFilter; // Otherwise, create one that take into account the exclusion pattern ... FilenameFilter filenameFilter = null; - final String filterPattern = exclusionPattern; + final String filterPattern = this.inclusionExclusionFilenameFilter.getExclusionPattern(); if (filterPattern != null) { filenameFilter = new FilenameFilter() { Pattern filter = Pattern.compile(filterPattern); @@ -622,9 +647,12 @@ if (getCustomPropertiesFactory() != null) { ref.add(new StringRefAddr(CUSTOM_PROPERTY_FACTORY, getCustomPropertiesFactory().getClass().getName())); } - if (exclusionPattern != null) { - ref.add(new StringRefAddr(EXCLUSION_PATTERN, exclusionPattern)); + if (this.inclusionExclusionFilenameFilter.getExclusionPattern() != null) { + ref.add(new StringRefAddr(EXCLUSION_PATTERN, this.inclusionExclusionFilenameFilter.getExclusionPattern())); } + if (this.inclusionExclusionFilenameFilter.getInclusionPattern() != null) { + ref.add(new StringRefAddr(INCLUSION_PATTERN, this.inclusionExclusionFilenameFilter.getInclusionPattern())); + } if (filenameFilter != null) { ref.add(new StringRefAddr(FILENAME_FILTER, filenameFilter.getClass().getName())); } @@ -648,6 +676,7 @@ String defaultWorkspace = (String)values.get(DEFAULT_WORKSPACE); String createWorkspaces = (String)values.get(ALLOW_CREATING_WORKSPACES); String exclusionPattern = (String)values.get(EXCLUSION_PATTERN); + String inclusionPattern = (String)values.get(INCLUSION_PATTERN); String filenameFilterClassName = (String)values.get(FILENAME_FILTER); String maxPathLength = (String)values.get(DEFAULT_MAX_PATH_LENGTH); String customPropertiesFactoryClassName = (String)values.get(CUSTOM_PROPERTY_FACTORY); @@ -669,6 +698,7 @@ if (createWorkspaces != null) source.setCreatingWorkspacesAllowed(Boolean.parseBoolean(createWorkspaces)); if (workspaceNames != null && workspaceNames.length != 0) source.setPredefinedWorkspaceNames(workspaceNames); if (exclusionPattern != null) source.setExclusionPattern(exclusionPattern); + if (inclusionPattern != null) source.setInclusionPattern(inclusionPattern); if (filenameFilterClassName != null) source.setFilenameFilter(filenameFilterClassName); if (maxPathLength != null) source.setMaxPathLength(Integer.valueOf(maxPathLength)); if (extraPropertiesBehavior != null) source.setExtraPropertiesBehavior(extraPropertiesBehavior);