JCRVLT-495 allow to limit filtering to certain file patterns (#52)
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..6b9aca9
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,5 @@
+# Set the default behavior, in case people don't have core.autocrlf set.
+* text=auto
+
+# all XML files should keep lf newlines, even on Windows
+*.xml text eol=lf
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 1bfdfdb..bd05a83 100644
--- a/pom.xml
+++ b/pom.xml
@@ -344,12 +344,12 @@
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-archiver</artifactId>
- <version>3.5.0</version>
+ <version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-archiver</artifactId>
- <version>4.2.0</version>
+ <version>4.2.3</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
diff --git a/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/VaultMojo.java b/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/VaultMojo.java
index 914ba15..d08df70 100644
--- a/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/VaultMojo.java
+++ b/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/VaultMojo.java
@@ -63,6 +63,7 @@
import org.codehaus.plexus.archiver.util.DefaultFileSet;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.MatchPatterns;
import org.codehaus.plexus.util.StringUtils;
import org.jetbrains.annotations.NotNull;
@@ -107,12 +108,14 @@
private File outputDirectory;
/** Enables resource filtering on the meta-inf source files similar to what the <a href="https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html">maven-resources-plugin</a> does.
+ * It is recommended to limit filtering with {@link #filteredFilePatterns} and {@link #nonFilteredFileExtensions}.
* @since 1.1.0
*/
@Parameter(property = "vault.enableMetaInfFiltering", defaultValue = "false")
private boolean enableMetaInfFiltering;
/** Enables resource filtering on the {@link AbstractSourceAndMetadataPackageMojo#jcrRootSourceDirectory} source files similar to what the <a href="https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html">maven-resources-plugin</a> does.
+ * It is recommended to limit filtering with {@link #filteredFilePatterns} and {@link #nonFilteredFileExtensions}.
* @since 1.1.0
*/
@Parameter(property = "vault.enableJcrRootFiltering", defaultValue = "false")
@@ -171,12 +174,23 @@
@Parameter(property="vault.escapedBackslashesInFilePath", defaultValue = "false")
private boolean escapedBackslashesInFilePath;
- /** Additional list of file extensions that should not be filtered.
- * (already defined are : jpg, jpeg, gif, bmp, png)
+ /** Additional list of file extensions that should not be filtered, e.g. binaries.
+ * Already predefined as extensions which should never be filtered are: jpg, jpeg, gif, bmp, png, ico.
+ * Instead of using this deny list approach for binary files and others which should not be filtered,
+ * consider using an allow list via {@link #filteredFilePatterns} instead.
* @since 1.1.0 */
@Parameter(property="vault.nonFilteredFileExtensions")
private List<String> nonFilteredFileExtensions;
+ /**
+ * Restricts the files which should be filtered to the ones having matching one of the given <a href="http://ant.apache.org/manual/dirtasks.html#patterns">Ant patterns</a>.
+ * Evaluated before {@link #nonFilteredFileExtensions}.
+ * All patterns are relative to the root paths (given through the filter.xml root entries or the META-INF directory).
+ * If empty or not set all files except for the ones from {@link #nonFilteredFileExtensions} are filtered.
+ * @since 1.1.8 */
+ @Parameter(property="vault.filteredFilePatterns")
+ private List<String> filteredFilePatterns;
+
/** Stop searching endToken at the end of line when filtering is applied.
*
* @since 1.1.0 */
@@ -248,13 +262,16 @@
Path destFile = Paths.get(destFileName);
if ((destFile.startsWith(Constants.ROOT_DIR) && enableJcrRootFiltering) ||
(destFile.startsWith(Constants.META_INF) && enableMetaInfFiltering)) {
- getLog().info("Apply filtering to " + getProjectRelativeFilePath(sourceFile));
- Resource resource = new Resource();
- resource.setDirectory(sourceFile.getParent());
- resource.setIncludes(Collections.singletonList(sourceFile.getName()));
- resource.setFiltering(true);
- File newTargetDirectory = applyFiltering(destFile.getParent().toString(), mavenResourcesExecution, resource);
- sourceFile = new File(newTargetDirectory, sourceFile.getName());
+ MatchPatterns matchPatterns = MatchPatterns.from(filteredFilePatterns);
+ if (filteredFilePatterns == null || matchPatterns.matches(sourceFile.toString(), true)) {
+ getLog().info("Apply filtering to " + getProjectRelativeFilePath(sourceFile));
+ Resource resource = new Resource();
+ resource.setDirectory(sourceFile.getParent());
+ resource.setIncludes(Collections.singletonList(sourceFile.getName()));
+ resource.setFiltering(true);
+ File newTargetDirectory = applyFiltering(destFile.getParent().toString(), mavenResourcesExecution, resource);
+ sourceFile = new File(newTargetDirectory, sourceFile.getName());
+ }
}
getLog().debug("Adding file " + getProjectRelativeFilePath(sourceFile) + " to package at " + destFileName + "'");
archiver.addFile(sourceFile, destFileName);
@@ -274,21 +291,60 @@
(fileSet.getPrefix().startsWith(Constants.META_INF) && enableMetaInfFiltering)) {
getLog().info("Apply filtering to FileSet below " + getProjectRelativeFilePath(fileSet.getDirectory()));
- Resource resource = new Resource();
- resource.setDirectory(fileSet.getDirectory().getPath());
- if (fileSet.getIncludes() != null) {
- resource.setIncludes(Arrays.asList(fileSet.getIncludes()));
+ Resource filteringSourceResource = new Resource();
+ filteringSourceResource.setDirectory(fileSet.getDirectory().getPath());
+
+ // since allow lists (i.e. only filtering specific extensions) is not natively supported
+ // split up the fileSet
+ if (filteredFilePatterns != null && !filteredFilePatterns.isEmpty()) {
+ if (fileSet.getIncludes() != null) {
+ throw new IllegalStateException("FileSet can not have includes set, as those are used for filteredFileExtensions");
+ }
+ // create an additional file set with unfiltered files
+ DefaultFileSet unfilteredFileSet = cloneFileSet(fileSet);
+
+ // add all filtered file patterns to excludes
+ String[] excludes = Stream.of(Arrays.asList(fileSet.getExcludes()), filteredFilePatterns).flatMap(x -> x.stream()).toArray(String[]::new);
+ unfilteredFileSet.setExcludes(excludes);
+
+ getLog().debug("Adding unfiltered fileSet '" + getString(unfilteredFileSet) + "' to package");
+ archiver.addFileSet(unfilteredFileSet);
+ filteringSourceResource.setIncludes(filteredFilePatterns);
+ } else {
+ if (fileSet.getIncludes() != null) {
+ filteringSourceResource.setIncludes(Arrays.asList(fileSet.getIncludes()));
+ }
}
+
if (fileSet.getExcludes() != null) {
- resource.setExcludes(Arrays.asList(fileSet.getExcludes()));
+ filteringSourceResource.setExcludes(Arrays.asList(fileSet.getExcludes()));
// default exclude are managed via mavenResourcesExecution
}
- resource.setFiltering(true);
- File newTargetDirectory = applyFiltering(fileSet.getPrefix(), mavenResourcesExecution, resource);
- fileSet.setDirectory(newTargetDirectory);
+ filteringSourceResource.setFiltering(true);
+ File newTargetDirectory = applyFiltering(fileSet.getPrefix(), mavenResourcesExecution, filteringSourceResource);
+ if (newTargetDirectory.exists()) {
+ fileSet.setDirectory(newTargetDirectory);
+ getLog().debug("Adding filtered fileSet '" + getString(fileSet) + "' to package");
+ archiver.addFileSet(fileSet);
+ }
+ } else {
+ getLog().debug("Adding fileSet '" + getString(fileSet) + "' to package");
+ archiver.addFileSet(fileSet);
}
- getLog().debug("Adding fileSet '" + getString(fileSet) + "' to package");
- archiver.addFileSet(fileSet);
+ }
+
+ static DefaultFileSet cloneFileSet(DefaultFileSet defaultFileSet) {
+ DefaultFileSet newFileSet = new DefaultFileSet(defaultFileSet.getDirectory());
+ newFileSet.setCaseSensitive(defaultFileSet.isCaseSensitive());
+ newFileSet.setExcludes(defaultFileSet.getExcludes());
+ newFileSet.setFileMappers(defaultFileSet.getFileMappers());
+ newFileSet.setFileSelectors(defaultFileSet.getFileSelectors());
+ newFileSet.setIncludes(defaultFileSet.getIncludes());
+ newFileSet.setIncludingEmptyDirectories(defaultFileSet.isIncludingEmptyDirectories());
+ newFileSet.setPrefix(defaultFileSet.getPrefix());
+ newFileSet.setStreamTransformer(defaultFileSet.getStreamTransformer());
+ newFileSet.setUsingDefaultExcludes(defaultFileSet.isUsingDefaultExcludes());
+ return newFileSet;
}
private static String getString(FileSet fileSet) {
diff --git a/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/VaultMojoTest.java b/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/VaultMojoTest.java
index 10a319f..7536fe4 100644
--- a/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/VaultMojoTest.java
+++ b/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/VaultMojoTest.java
@@ -21,7 +21,10 @@
import java.util.Collections;
import java.util.Set;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.jackrabbit.filevault.maven.packaging.it.ProjectBuilder;
+import org.codehaus.plexus.archiver.util.DefaultFileSet;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;
@@ -45,4 +48,14 @@
Collection<File> uncoveredFiles = VaultMojo.getUncoveredFiles(sourceDirectory, excludes, "", entryNames);
Assert.assertThat(uncoveredFiles, Matchers.empty());
}
+
+ @Test
+ public void testCloneFileSet() {
+ DefaultFileSet fileSet = new DefaultFileSet();
+ fileSet.setIncludes(new String[] { "ab", "c" });
+ fileSet.setExcludes(new String[] { "de", "f" });
+ fileSet.setIncludingEmptyDirectories(true);
+ DefaultFileSet clonedFileSet = VaultMojo.cloneFileSet(fileSet);
+ Assert.assertTrue("Expected " + ToStringBuilder.reflectionToString(fileSet) + " but got " + ToStringBuilder.reflectionToString(clonedFileSet), EqualsBuilder.reflectionEquals(fileSet, clonedFileSet));
+ }
}
diff --git a/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/FilteringIT.java b/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/FilteringIT.java
index b7adc82..57fa2cf 100644
--- a/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/FilteringIT.java
+++ b/src/test/java/org/apache/jackrabbit/filevault/maven/packaging/it/FilteringIT.java
@@ -18,6 +18,7 @@
import java.io.IOException;
+import org.apache.commons.lang3.StringUtils;
import org.apache.maven.it.VerificationException;
import org.junit.Test;
@@ -26,41 +27,68 @@
*/
public class FilteringIT {
- private ProjectBuilder verify(String projectName, boolean enableJcrRootFiltering, boolean enableMetaInfFiltering, String ... goals) throws VerificationException, IOException {
- return new ProjectBuilder()
+ private ProjectBuilder verify(String projectName, boolean enableJcrRootFiltering, boolean enableMetaInfFiltering, String filteredFilePatterns, String ... goals) throws VerificationException, IOException {
+ ProjectBuilder projectBuilder = new ProjectBuilder()
.setTestProjectDir("filtering-tests/" + projectName)
.setTestGoals(goals)
.setProperty("vault.enableMetaInfFiltering", Boolean.toString(enableMetaInfFiltering))
- .setProperty("vault.enableJcrRootFiltering", Boolean.toString(enableJcrRootFiltering))
+ .setProperty("vault.enableJcrRootFiltering", Boolean.toString(enableJcrRootFiltering));
+ if (StringUtils.isNotBlank(filteredFilePatterns)) {
+ projectBuilder.setProperty("vault.filteredFilePatterns", filteredFilePatterns);
+ }
+ return projectBuilder
.build()
.verifyExpectedFiles();
}
@Test
public void test_simple_filter_with_filtering_enabled() throws Exception {
- verify("simple-filter", true, true)
+ verify("simple-filter", true, true, null)
+ // cannot check checksum of properties.xml as that one has platform dependent new lines!
+ //.verifyExpectedFileChecksum("META-INF/vault/properties.xml", "295fb69e")
.verifyExpectedFileChecksum("jcr_root/apps/bar/test1.properties", "10791371")
- .verifyExpectedFileChecksum("jcr_root/apps/foo/test2.properties", "7563f01d");
+ .verifyExpectedFileChecksum("jcr_root/apps/foo/test2.properties", "7563f01d")
+ .verifyExpectedFileChecksum("jcr_root/apps/foo/child/.content.xml", "d9b1ad2");
}
@Test
public void test_simple_filter_with_filtering_disabled() throws Exception {
- verify("simple-filter", false, false)
- .verifyExpectedFileChecksum("jcr_root/apps/bar/test1.properties", "34e5a01d")
- .verifyExpectedFileChecksum("jcr_root/apps/foo/test2.properties", "a41ae6f8");
+ verify("simple-filter", false, false, null)
+ // cannot check checksum of properties.xml as that one has platform dependent new lines!
+ //.verifyExpectedFileChecksum("META-INF/vault/properties.xml", "5953911b")
+ .verifyExpectedFileChecksum("jcr_root/apps/bar/test1.properties", "34e5a01d")
+ .verifyExpectedFileChecksum("jcr_root/apps/foo/test2.properties", "a41ae6f8")
+ .verifyExpectedFileChecksum("jcr_root/apps/foo/child/.content.xml", "f8aee8df");
}
@Test
- public void test_simple_filter_with_filtering_partially_enabled() throws Exception {
- verify("simple-filter", true, false)
- .verifyExpectedFileChecksum("jcr_root/apps/bar/test1.properties", "10791371")
- .verifyExpectedFileChecksum("jcr_root/apps/foo/test2.properties", "7563f01d");
+ public void test_simple_filter_with_filtering_enabled_on_jcrroot() throws Exception {
+ verify("simple-filter", true, false, null)
+ // cannot check checksum of properties.xml as that one has platform dependent new lines!
+ //.verifyExpectedFileChecksum("META-INF/vault/properties.xml", "5953911b")
+ .verifyExpectedFileChecksum("jcr_root/apps/bar/test1.properties", "10791371")
+ .verifyExpectedFileChecksum("jcr_root/apps/foo/test2.properties", "7563f01d")
+ .verifyExpectedFileChecksum("jcr_root/apps/foo/child/.content.xml", "d9b1ad2");
}
@Test
- public void test_simple_filter_with_filtering_partially_enabled2() throws Exception {
- verify("simple-filter", false, true)
- .verifyExpectedFileChecksum("jcr_root/apps/bar/test1.properties", "34e5a01d")
- .verifyExpectedFileChecksum("jcr_root/apps/foo/test2.properties", "a41ae6f8");
+ public void test_simple_filter_with_filtering_enabled_on_metainf() throws Exception {
+ verify("simple-filter", false, true, null)
+ // cannot check checksum of properties.xml as that one has platform dependent new lines!
+ //.verifyExpectedFileChecksum("META-INF/vault/properties.xml", "295fb69e")
+ .verifyExpectedFileChecksum("jcr_root/apps/bar/test1.properties", "34e5a01d")
+ .verifyExpectedFileChecksum("jcr_root/apps/foo/test2.properties", "a41ae6f8")
+ .verifyExpectedFileChecksum("jcr_root/apps/foo/child/.content.xml", "f8aee8df");
+ }
+
+ @Test
+ public void test_simple_filter_with_filtering_partially_enabled_on_jcrroot() throws Exception {
+ verify("simple-filter", true, false, "**/child/*.xml")
+ // cannot check checksum of properties.xml as that one has platform dependent new lines!
+ //.verifyExpectedFileChecksum("META-INF/vault/properties.xml", "5953911b")
+ .verifyExpectedFileChecksum("jcr_root/apps/bar/test1.properties", "34e5a01d")
+ .verifyExpectedFileChecksum("jcr_root/apps/foo/test2.properties", "a41ae6f8")
+ .verifyExpectedFileChecksum("jcr_root/apps/bar/.content.xml", "f8aee8df")
+ .verifyExpectedFileChecksum("jcr_root/apps/foo/child/.content.xml", "d9b1ad2");
}
}
diff --git a/src/test/resources/test-projects/filtering-tests/simple-filter/expected-files.txt b/src/test/resources/test-projects/filtering-tests/simple-filter/expected-files.txt
index 2a8bd38..f63b6da 100644
--- a/src/test/resources/test-projects/filtering-tests/simple-filter/expected-files.txt
+++ b/src/test/resources/test-projects/filtering-tests/simple-filter/expected-files.txt
@@ -14,5 +14,8 @@
jcr_root/apps/
jcr_root/apps/bar/
jcr_root/apps/bar/test1.properties
+jcr_root/apps/bar/.content.xml
jcr_root/apps/foo/
-jcr_root/apps/foo/test2.properties
\ No newline at end of file
+jcr_root/apps/foo/test2.properties
+jcr_root/apps/foo/child/
+jcr_root/apps/foo/child/.content.xml
\ No newline at end of file
diff --git a/src/test/resources/test-projects/filtering-tests/simple-filter/jcr_root/apps/bar/.content.xml b/src/test/resources/test-projects/filtering-tests/simple-filter/jcr_root/apps/bar/.content.xml
new file mode 100644
index 0000000..d61361e
--- /dev/null
+++ b/src/test/resources/test-projects/filtering-tests/simple-filter/jcr_root/apps/bar/.content.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+jcr:primaryType="nt:unstructured"
+customKey2="${customKey}" />
\ No newline at end of file
diff --git a/src/test/resources/test-projects/filtering-tests/simple-filter/jcr_root/apps/foo/child/.content.xml b/src/test/resources/test-projects/filtering-tests/simple-filter/jcr_root/apps/foo/child/.content.xml
new file mode 100644
index 0000000..d61361e
--- /dev/null
+++ b/src/test/resources/test-projects/filtering-tests/simple-filter/jcr_root/apps/foo/child/.content.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+jcr:primaryType="nt:unstructured"
+customKey2="${customKey}" />
\ No newline at end of file