jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From k...@apache.org
Subject svn commit: r1868139 [2/3] - in /jackrabbit/commons/filevault-package-maven-plugin/trunk: ./ src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/ src/main/java/org/apache/jac...
Date Tue, 08 Oct 2019 15:22:04 GMT
Copied: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/MavenBasedPackageDependency.java (from r1863646, jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/Dependency.java)
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/MavenBasedPackageDependency.java?p2=jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/MavenBasedPackageDependency.java&p1=jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/Dependency.java&r1=1863646&r2=1868139&rev=1868139&view=diff
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/Dependency.java (original)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/MavenBasedPackageDependency.java Tue Oct  8 15:22:03 2019
@@ -16,14 +16,16 @@
  */
 package org.apache.jackrabbit.filevault.maven.packaging;
 
+import java.io.File;
 import java.io.IOException;
 
 import javax.annotation.Nullable;
 
-import org.apache.jackrabbit.filevault.maven.packaging.impl.PackageDependency;
-import org.apache.jackrabbit.filevault.maven.packaging.impl.PackageInfo;
+import org.apache.jackrabbit.vault.packaging.Dependency;
 import org.apache.jackrabbit.vault.packaging.PackageId;
+import org.apache.jackrabbit.vault.packaging.PackageInfo;
 import org.apache.jackrabbit.vault.packaging.VersionRange;
+import org.apache.jackrabbit.vault.packaging.impl.DefaultPackageInfo;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.project.MavenProject;
@@ -58,7 +60,7 @@ import org.codehaus.plexus.util.StringUt
  * accepted versions, where the bounds are either included using parentheses
  * {@code ()} or excluded using brackets {@code []}
  */
-public class Dependency {
+public class MavenBasedPackageDependency {
 
     /**
      * The group name, required for package-id references
@@ -93,17 +95,34 @@ public class Dependency {
     /**
      * Resolved package dependency. only available after {@link #resolve(MavenProject, Log)}
      */
-    private PackageDependency dependency;
+    private org.apache.jackrabbit.vault.packaging.Dependency dependency;
+    
+    // default constructor for passing Maven Mojo parameters of that type
+    public MavenBasedPackageDependency() {
+        
+    }
+
+    public MavenBasedPackageDependency(Dependency dependency, File file) throws IOException {
+        super();
+        this.dependency = dependency;
+        this.name = dependency.getName();
+        this.group = dependency.getGroup();
+        this.version = dependency.getRange().toString();
+        readMetaData(file);
+    }
 
     /**
-     * Converts a list of {@link Dependency} instances to vault dependencies.
+     * Converts a list of {@link MavenBasedPackageDependency} instances to vault dependencies.
      *
+     * @param project the Maven project
      * @param log the Logger
-     * @param dependencyList The list of {@link Dependency} instances to convert.
+     * @param dependencyList The list of {@link MavenBasedPackageDependency} instances to convert.
      * @return The Vault Packaging Dependency representing the dependencies.
+     * @throws IOException in case meta information could not be read from the project dependency or the 
+     * dependency is not a content package.
      */
-    static PackageDependency[] resolve(final MavenProject project, final Log log, final Dependency... dependencyList) throws IOException {
-        PackageDependency[] dependencies = new PackageDependency[dependencyList.length];
+    public static org.apache.jackrabbit.vault.packaging.Dependency[] resolve(final MavenProject project, final Log log, final MavenBasedPackageDependency... dependencyList) throws IOException {
+        org.apache.jackrabbit.vault.packaging.Dependency[] dependencies = new org.apache.jackrabbit.vault.packaging.Dependency[dependencyList.length];
         for (int i = 0; i < dependencies.length; i++) {
             dependencies[i] = dependencyList[i].resolve(project, log);
         }
@@ -113,37 +132,55 @@ public class Dependency {
     /**
      * Helper method for {@link #toString)} to convert an instance of this
      * class to a Vault Packaging Dependency for easy string conversion.
+     * @throws IOException in case meta information could not be read from the project dependency or the 
+     * dependency is not a content package.
      */
-    private PackageDependency resolve(final MavenProject project, final Log log) throws IOException {
+    @SuppressWarnings("deprecation")
+    private org.apache.jackrabbit.vault.packaging.Dependency resolve(final MavenProject project, final Log log) throws IOException {
         if (!StringUtils.isEmpty(group) || !StringUtils.isEmpty(name)) {
-            log.warn("Using package id in dependencies is deprecated. use maven coordinates instead: " + group + ":" + name);
+            log.warn("Using package id in dependencies is deprecated. Use Maven coordinates (given via 'groupId' and 'artifactId') instead of '" + group + ":" + name +"'!");
         }
         if (!StringUtils.isEmpty(groupId) && !StringUtils.isEmpty(artifactId)) {
-            for (Artifact a : project.getDependencyArtifacts()) {
-                if (a.getArtifactId().equals(artifactId) && a.getGroupId().equals(groupId)) {
-                    PackageInfo info = PackageInfo.read(a.getFile());
-                    if (info != null) {
-                        PackageId id = info.getId();
-                        group = id.getGroup();
-                        name = id.getName();
-                        if (StringUtils.isEmpty(version)) {
-                            version = new VersionRange(id.getVersion(), true, null, false).toString();
-                        }
-                        this.info = info;
+            boolean foundMavenDependency = false;
+            if (!StringUtils.isEmpty(version)) {
+                log.warn("The version should not be explicitly given if the dependency is specified with 'groupId' and 'artifactId' as the version can be automatically determined from the Maven dependencies");
+            }
+            if (project != null) {
+                for (Artifact a : project.getDependencyArtifacts()) {
+                    if (a.getArtifactId().equals(artifactId) && a.getGroupId().equals(groupId)) {
+                        readMetaData(a.getFile());
+                        foundMavenDependency = true;
                         break;
-                    } else {
-                        throw new IOException("Specified dependency " + this + " is not a package.");
                     }
                 }
+                if (!foundMavenDependency) {
+                    throw new IOException("Specified dependency '" + this + "' was not found among the Maven dependencies of this project!");
+                }
+            } else {
+                throw new IOException("Dependency '" + this + "' was given via Maven coordinates but there is no Maven project connect which allows to resolve those.");
             }
         }
         if (StringUtils.isEmpty(group) || StringUtils.isEmpty(name)) {
-            throw new IOException("Specified dependency " + this + " is not qualified.");
+            throw new IOException("Specified dependency " + this + " is not qualified (group and name or groupId and artifactId is missing)!");
         }
         VersionRange range = StringUtils.isEmpty(version) ? VersionRange.INFINITE : VersionRange.fromString(version);
-        return dependency = new PackageDependency(group, name, range);
+        return dependency = new org.apache.jackrabbit.vault.packaging.Dependency(group, name, range);
     }
 
+    public void readMetaData(File file) throws IOException {
+        PackageInfo info = DefaultPackageInfo.read(file);
+        if (info != null) {
+            PackageId id = info.getId();
+            group = id.getGroup();
+            name = id.getName();
+            if (StringUtils.isEmpty(version)) {
+                version = new VersionRange(id.getVersion(), true, null, false).toString();
+            }
+            this.info = info;
+        } else {
+            throw new IOException("Specified dependency " + this + " is not a package.");
+        }
+    }
     /**
      * Returns the package info or {@code null}.
      *
@@ -160,7 +197,7 @@ public class Dependency {
      * @return the package dependency.
      */
     @Nullable
-    public PackageDependency getPackageDependency() {
+    public org.apache.jackrabbit.vault.packaging.Dependency getPackageDependency() {
         return dependency;
     }
 

Modified: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/SimpleEmbedded.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/SimpleEmbedded.java?rev=1868139&r1=1868138&r2=1868139&view=diff
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/SimpleEmbedded.java (original)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/SimpleEmbedded.java Tue Oct  8 15:22:03 2019
@@ -96,6 +96,7 @@ public class SimpleEmbedded {
         return excludeTransitive;
     }
     
+    @SuppressWarnings("deprecation")
     public Collection<Artifact> getMatchingArtifacts(final MavenProject project) {
 
         // get artifacts depending on whether we exclude transitives or not

Added: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ValidateFilesMojo.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ValidateFilesMojo.java?rev=1868139&view=auto
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ValidateFilesMojo.java (added)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ValidateFilesMojo.java Tue Oct  8 15:22:03 2019
@@ -0,0 +1,248 @@
+/*
+ * 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.filevault.maven.packaging;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.jackrabbit.filevault.maven.packaging.validator.impl.context.DirectoryValidationContext;
+import org.apache.jackrabbit.vault.fs.config.ConfigurationException;
+import org.apache.jackrabbit.vault.packaging.PackageInfo;
+import org.apache.jackrabbit.vault.util.Constants;
+import org.apache.jackrabbit.vault.validation.ValidationExecutor;
+import org.apache.jackrabbit.vault.validation.ValidationViolation;
+import org.apache.jackrabbit.vault.validation.spi.ValidationContext;
+import org.apache.maven.lifecycle.LifecycleExecutor;
+import org.apache.maven.lifecycle.LifecycleNotFoundException;
+import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException;
+import org.apache.maven.lifecycle.MavenExecutionPlan;
+import org.apache.maven.plugin.InvalidPluginDescriptorException;
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.MojoNotFoundException;
+import org.apache.maven.plugin.PluginDescriptorParsingException;
+import org.apache.maven.plugin.PluginManagerException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.PluginResolutionException;
+import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.codehaus.plexus.util.Scanner;
+
+/** Validates individual files with all registered validators. This is only active for incremental builds (i.e. inside m2e)
+    or when mojo "validate-package" is not executed in the current Maven execution */
+@Mojo(name = "validate-files", defaultPhase = LifecyclePhase.PROCESS_CLASSES, requiresDependencyResolution = ResolutionScope.COMPILE)
+public class ValidateFilesMojo extends AbstractValidateMojo {
+
+    //-----
+    // Start: Copied from AbstractMetadataPackageMojo
+    // -----
+    /**
+     * The directory that contains the META-INF/vault. Multiple directories can be specified as a comma separated list,
+     * which will act as a search path and cause the plugin to look for the first existing directory.
+     * <p>
+     * This directory is added as fileset to the package archiver before the the {@link #workDirectory}. This means that
+     * files specified in this directory have precedence over the one present in the {@link #workDirectory}. For example,
+     * if this directory contains a {@code properties.xml} it will not be overwritten by the generated one. A special
+     * case is the {@code filter.xml} which will be merged with inline filters if present.
+     */
+    @Parameter(property = "vault.metaInfVaultDirectory", required = true, defaultValue = "${project.basedir}/META-INF/vault,"
+            + "${project.basedir}/src/main/META-INF/vault," + "${project.basedir}/src/main/content/META-INF/vault,"
+            + "${project.basedir}/src/content/META-INF/vault")
+    File[] metaInfVaultDirectory;
+
+    /**
+     * The directory containing the metadata to be packaged up into the content package.
+     * Basically containing all files/folders being generated by goal "generate-metadata".
+     */
+    @Parameter(
+            defaultValue = "${project.build.directory}/vault-work",
+            required = true)
+    File workDirectory;
+    //-----
+    // End: Copied from AbstractMetadataPackageMojo
+    // -----
+    
+    //-----
+    // Start: Copied from AbstractSourceAndMetadataPackageMojo
+    // -----
+    
+
+    /**
+     * The directory containing the content to be packaged up into the content
+     * package.
+     *
+     * This property is deprecated; use {@link #jcrRootSourceDirectory} instead.
+     */
+    @Deprecated
+    @Parameter
+    private File builtContentDirectory;
+
+    /**
+     * The directory that contains the jcr_root of the content. Multiple directories can be specified as a comma separated list,
+     * which will act as a search path and cause the plugin to look for the first existing directory.
+     */
+    @Parameter(property = "vault.jcrRootSourceDirectory", required = true, defaultValue = "${project.basedir}/jcr_root,"
+            + "${project.basedir}/src/main/jcr_root," + "${project.basedir}/src/main/content/jcr_root,"
+            + "${project.basedir}/src/content/jcr_root," + "${project.build.outputDirectory}")
+    private File[] jcrRootSourceDirectory;
+
+    /**
+     * The file name patterns to exclude in addition to the ones listed in
+     * {@link AbstractScanner#DEFAULTEXCLUDES}. The format of each pattern is described in {@link DirectoryScanner}.
+     * The comparison is against the path relative to the according filter root.
+     * Since this is hardly predictable it is recommended to use only filename/directory name patterns here 
+     * but not take into account file system hierarchies!
+     * <p>
+     * Each value is either a regex pattern if enclosed within {@code %regex[} and {@code ]}, otherwise an 
+     * <a href="https://ant.apache.org/manual/dirtasks.html#patterns">Ant pattern</a>.
+     */
+    @Parameter(property = "vault.excludes", defaultValue = "**/.vlt,**/.vltignore", required = true)
+    protected String[] excludes;
+    //-----
+    // End: Copied from AbstractSourceAndMetadataPackageMojo
+    // -----
+
+    @Component
+    protected LifecycleExecutor lifecycleExecutor;
+
+    private static final String PLUGIN_KEY = "org.apache.jackrabbit:filevault-package-maven-plugin";
+
+    public ValidateFilesMojo() {
+    }
+
+    @Override
+    public void doExecute(Collection<PackageInfo> resolvedDependencies) throws MojoExecutionException, MojoFailureException {
+        final List<String> allGoals;
+        if (session != null) {
+            allGoals = session.getGoals();
+            getLog().debug("Following goals are detected: " + StringUtils.join(allGoals, ", "));
+        } else {
+            getLog().debug("MavenSession not available. Maybe executed by m2e.");
+            allGoals = Collections.emptyList();
+        }
+        // is another mojo from this plugin called in this maven session later on?
+        try {
+            if (!buildContext.isIncremental() && isMojoGoalExecuted(lifecycleExecutor, "validate-package", allGoals.toArray(new String[0]))) { // how to detect that "install" contains "package"? how to resolve the given goals?
+                getLog().info("Skip this mojo as this is not an incremental build and 'validate-package' is executed later on!");
+                return;
+            }
+        } catch (PluginNotFoundException | PluginResolutionException | PluginDescriptorParsingException | MojoNotFoundException
+                | NoPluginFoundForPrefixException | InvalidPluginDescriptorException | PluginVersionResolutionException
+                | LifecyclePhaseNotFoundException | LifecycleNotFoundException | PluginManagerException e1) {
+            getLog().warn("Could not determine plugin executions", e1);
+        }
+        try {
+            File metaInfoVaultSourceDirectory = AbstractMetadataPackageMojo.getMetaInfVaultSourceDirectory(metaInfVaultDirectory, getLog());
+            File metaInfRootDirectory = null;
+            if (metaInfoVaultSourceDirectory != null) {
+                metaInfRootDirectory = metaInfoVaultSourceDirectory.getParentFile();
+            }
+            File generatedMetaInfRootDirectory = new File(workDirectory, Constants.META_INF);
+            getLog().info("Using generatedMetaInfRootDirectory: " + generatedMetaInfRootDirectory + " and metaInfRootDir: " + metaInfRootDirectory);
+            ValidationContext context = new DirectoryValidationContext(generatedMetaInfRootDirectory, metaInfRootDirectory, resolver, resolvedDependencies, getLog());
+            ValidationExecutor executor = validationExecutorFactory.createValidationExecutor(context, false, false, validatorsSettings);
+            if (executor == null) {
+                throw new MojoExecutionException("No registered validators found!");
+            }
+            validationHelper.printUsedValidators(getLog(), executor, context, true);
+            if (metaInfRootDirectory != null) {
+                validateDirectory(executor, metaInfRootDirectory, true);
+            }
+            validateDirectory(executor, generatedMetaInfRootDirectory, true);
+            File jcrSourceDirectory = AbstractSourceAndMetadataPackageMojo.getJcrSourceDirectory(jcrRootSourceDirectory, builtContentDirectory, getLog());
+            if (jcrSourceDirectory != null) {
+                validateDirectory(executor, jcrSourceDirectory, false);
+            }
+            validationHelper.printMessages(executor.done(), getLog(), buildContext, project.getBasedir().toPath());
+        } catch (IOException | ConfigurationException e) {
+            throw new MojoFailureException("Could not execute validation", e);
+        }
+        validationHelper.failBuildInCaseOfViolations(failOnValidationWarnings);
+    }
+
+    private void validateDirectory(ValidationExecutor executor, File baseDir, boolean isMetaInf) {
+        Scanner scanner = buildContext.newScanner(baseDir);
+        // make sure filtering does work equally as within the package goal
+        scanner.setExcludes(excludes);
+        scanner.addDefaultExcludes();
+        scanner.scan();
+        getLog().info("Scanning baseDir '" + baseDir + "'...");
+        for (String relativeFile : scanner.getIncludedFiles()) {
+            File absoluteFile = new File(baseDir, relativeFile);
+            validationHelper.clearPreviousValidationMessages(buildContext, absoluteFile);
+            getLog().info("Validating file '" + absoluteFile + "'...");
+            try (InputStream input = new FileInputStream(absoluteFile)) {
+                final Collection<ValidationViolation> messages;
+                if (isMetaInf) {
+                    messages = executor.validateMetaInf(input, Paths.get(relativeFile), baseDir.toPath());
+                } else {
+                    messages = executor.validateJcrRoot(input, Paths.get(relativeFile), baseDir.toPath());
+                }
+                validationHelper.printMessages(messages, getLog(), buildContext, project.getBasedir().toPath());
+            } catch (FileNotFoundException e) {
+                getLog().error("Could not find file " + absoluteFile, e);
+            } catch (IOException e) {
+                getLog().error("Could not validate file " + absoluteFile, e);
+            }
+        }
+    }
+
+    /**
+     * Checks if a certain goal is executed at some point in time in the same Maven Session
+     * @param lifecycleExecutor
+     * @param mojoGoal
+     * @param goals
+     * @return
+     * @throws PluginNotFoundException
+     * @throws PluginResolutionException
+     * @throws PluginDescriptorParsingException
+     * @throws MojoNotFoundException
+     * @throws NoPluginFoundForPrefixException
+     * @throws InvalidPluginDescriptorException
+     * @throws PluginVersionResolutionException
+     * @throws LifecyclePhaseNotFoundException
+     * @throws LifecycleNotFoundException
+     * @throws PluginManagerException
+     * @see <a href=https://github.com/apache/maven/blob/master/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java">DefaultLifecycleExecutor</a>
+     */
+    private boolean isMojoGoalExecuted(LifecycleExecutor lifecycleExecutor, String mojoGoal, String... goals) throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, PluginVersionResolutionException, LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginManagerException {
+        if (goals.length == 0) {
+            return false;
+        }
+        MavenExecutionPlan executionPlan = lifecycleExecutor.calculateExecutionPlan(session, goals);
+        for (MojoExecution mojoExecution : executionPlan.getMojoExecutions()) {
+            if (PLUGIN_KEY.equals(mojoExecution.getPlugin().getKey()) && mojoGoal.equals(mojoExecution.getGoal())) {
+                return true;
+            }
+        }
+        return false;
+    }
+}

Added: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ValidatePackageMojo.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ValidatePackageMojo.java?rev=1868139&view=auto
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ValidatePackageMojo.java (added)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ValidatePackageMojo.java Tue Oct  8 15:22:03 2019
@@ -0,0 +1,147 @@
+/*
+ * 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.filevault.maven.packaging;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.jackrabbit.filevault.maven.packaging.validator.impl.context.ArchiveValidationContextImpl;
+import org.apache.jackrabbit.filevault.maven.packaging.validator.impl.context.SubPackageValidationContext;
+import org.apache.jackrabbit.vault.fs.io.Archive;
+import org.apache.jackrabbit.vault.fs.io.ZipArchive;
+import org.apache.jackrabbit.vault.fs.io.ZipStreamArchive;
+import org.apache.jackrabbit.vault.packaging.PackageInfo;
+import org.apache.jackrabbit.vault.util.Constants;
+import org.apache.jackrabbit.vault.validation.ValidationExecutor;
+import org.apache.jackrabbit.vault.validation.ValidationViolation;
+import org.apache.jackrabbit.vault.validation.spi.ValidationMessageSeverity;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.xml.sax.SAXException;
+
+
+/** Validates the whole package with all registered validators. This is only active for incremental builds (i.e. inside m2e) */
+@Mojo(
+        name = "validate-package", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.COMPILE, requiresProject = false)
+public class ValidatePackageMojo extends AbstractValidateMojo {
+
+    /** The package file to validate. By default will be the project's artifact (in case a project is given) */
+    @Parameter(property = "vault.packageToValidate", defaultValue = "${project.artifact.file}", required=true)
+    private File packageFile;
+
+    /** If set to {@code true} always executes all validators also for all sub packages (recursively). */
+    @Parameter(required = true, defaultValue = "false")
+    private boolean enforceRecursiveSubpackageValidation;
+
+    public ValidatePackageMojo() {
+    }
+
+    @Override
+    public void doExecute(Collection<PackageInfo> resolvedDependencies) throws MojoExecutionException, MojoFailureException {
+        try {
+            validatePackage(packageFile, resolvedDependencies);
+            validationHelper.failBuildInCaseOfViolations(failOnValidationWarnings);
+        } catch (IOException | ParserConfigurationException | SAXException e) {
+            throw new MojoExecutionException("Could not validate package '" + packageFile + "': " + e.getMessage(), e);
+        }
+    }
+
+    private void validatePackage(File file, Collection<PackageInfo> resolvedDependencies) throws IOException, ParserConfigurationException, SAXException, MojoExecutionException {
+        getLog().info("Start validating package '" + file + "'...");
+
+        // open file to extract the meta data for the validation context
+        ArchiveValidationContextImpl context;
+        ValidationExecutor executor;
+        try (Archive archive = new ZipArchive(file)) {
+            archive.open(true);
+            context = new ArchiveValidationContextImpl(archive, file.toPath(), resolver, resolvedDependencies, getLog());
+            executor = validationExecutorFactory.createValidationExecutor(context, false, enforceRecursiveSubpackageValidation, validatorsSettings);
+            if (executor != null) {
+                validationHelper.printUsedValidators(getLog(), executor, context, true);
+                validateArchive(archive, file.toPath(), context, executor);
+            } else {
+                throw new MojoExecutionException("No registered validators found!");
+            }
+            getLog().debug("End validating package '" + file + "'.");
+        }
+    }
+
+    private void validateArchive(Archive archive, Path path, ArchiveValidationContextImpl context,
+            ValidationExecutor executor) throws IOException, SAXException, ParserConfigurationException {
+        validateEntry(archive, archive.getRoot(), Paths.get(""), path, context, executor);
+        validationHelper.printMessages(executor.done(), getLog(), buildContext, packageFile.toPath());
+    }
+
+    private void validateEntry(Archive archive, Archive.Entry entry, Path entryPath, Path packagePath, ArchiveValidationContextImpl context,
+            ValidationExecutor executor) throws IOException, SAXException, ParserConfigurationException {
+        for (Archive.Entry childEntry : entry.getChildren()) {
+            if (childEntry.isDirectory()) {
+                validateEntry(archive, childEntry, entryPath.resolve(childEntry.getName()), packagePath, context, executor);
+            } else {
+                try (InputStream input = archive.openInputStream(childEntry)) {
+                    validateInputStream(input, entryPath.resolve(childEntry.getName()), packagePath, context, executor);
+                }
+            }
+        }
+    }
+
+    private void validateInputStream(InputStream inputStream, Path entryPath, Path packagePath, ArchiveValidationContextImpl context,
+            ValidationExecutor executor) throws IOException, SAXException, ParserConfigurationException {
+        Collection<ValidationViolation> messages = new LinkedList<>();
+        if (entryPath.startsWith(Constants.META_INF)) {
+            messages.addAll(executor.validateMetaInf(inputStream, Paths.get(Constants.META_INF).relativize(entryPath), packagePath.resolve(Constants.META_INF)));
+        } else if (entryPath.startsWith(Constants.ROOT_DIR)) {
+            // in case this is a subpackage
+            if (entryPath.getFileName().toString().endsWith(VaultMojo.PACKAGE_EXT)) {
+                Path subPackagePath = context.getPackageRootPath().resolve(entryPath);
+                getLog().info("Start validating sub package '" + subPackagePath + "'...");
+                // can't use archive.getSubPackage because that holds the wrong metadata
+                Archive subArchive = new ZipStreamArchive(inputStream);
+                subArchive.open(true);
+                SubPackageValidationContext subPackageValidationContext = new SubPackageValidationContext(context, subArchive, subPackagePath, resolver, getLog());
+                ValidationExecutor subPackageValidationExecutor = validationExecutorFactory
+                        .createValidationExecutor(subPackageValidationContext, true, enforceRecursiveSubpackageValidation, validatorsSettings);
+                if (subPackageValidationExecutor != null) {
+                    validationHelper.printUsedValidators(getLog(), executor, subPackageValidationContext, false);
+                    validateArchive(subArchive, subPackagePath, subPackageValidationContext, subPackageValidationExecutor);
+                } else {
+                    getLog().debug("Skip validating sub package as no validator is interested in it.");
+                }
+                getLog().info("End validating sub package.");
+            } else {
+                // strip off jcr_root
+                Path relativeJcrPath = Paths.get(Constants.ROOT_DIR).relativize(entryPath);
+                messages.addAll(executor.validateJcrRoot(inputStream, relativeJcrPath, packagePath.resolve(Constants.ROOT_DIR)));
+            }
+        } else {
+            messages.add(new ValidationViolation(ValidationMessageSeverity.WARN, "Found unexpected file outside of " + Constants.ROOT_DIR + " and " + Constants.META_INF, entryPath, packagePath, null, 0,0, null));
+        }
+        validationHelper.printMessages(messages, getLog(), buildContext, packageFile.toPath());
+    }
+
+}

Added: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ValidationHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ValidationHelper.java?rev=1868139&view=auto
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ValidationHelper.java (added)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ValidationHelper.java Tue Oct  8 15:22:03 2019
@@ -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.filevault.maven.packaging;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.jackrabbit.vault.validation.ValidationExecutor;
+import org.apache.jackrabbit.vault.validation.ValidationViolation;
+import org.apache.jackrabbit.vault.validation.spi.ValidationContext;
+import org.apache.jackrabbit.vault.validation.spi.Validator;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+import org.sonatype.plexus.build.incremental.BuildContext;
+import org.sonatype.plexus.build.incremental.DefaultBuildContext;
+
+public class ValidationHelper {
+
+    /**
+     * Set to {@code true} if at least one {@link ValidationViolation} has been given out
+     */
+    private int noOfEmittedValidationMessagesWithLevelWarn = 0;
+    
+    /**
+     * Set to {@code true} if at least one validation violation with severity {@link ValidationMessageSeverity#ERROR} has been given out
+     */
+    private int noOfEmittedValidationMessagesWithLevelError = 0;
+
+    protected ValidationHelper() {
+    }
+
+
+    /**
+     * 
+     * @param violations
+     * @param log
+     * @param buildContext
+     * @param baseDirectory the directory to which all absolute paths should be made relative (i.e. the Maven basedir)
+     */
+    public void printMessages(Collection<ValidationViolation> violations, Log log, BuildContext buildContext, Path baseDirectory) {
+        for (ValidationViolation violation : violations) {
+            final int buildContextSeverity;
+                switch (violation.getSeverity()) {
+                    case ERROR:
+                        log.error(getDetailMessage(violation, baseDirectory));
+                        if (violation.getThrowable() != null) {
+                            log.debug(violation.getThrowable());
+                        }
+                        buildContextSeverity = BuildContext.SEVERITY_ERROR;
+                        noOfEmittedValidationMessagesWithLevelError++;
+                        break;
+                    case WARN:
+                        log.warn(getDetailMessage(violation, baseDirectory));
+                        if (violation.getThrowable() != null) {
+                            log.debug(violation.getThrowable());
+                        }
+                        noOfEmittedValidationMessagesWithLevelWarn++;
+                        buildContextSeverity = BuildContext.SEVERITY_WARNING;
+                        break;
+                    case INFO:
+                        log.info(getDetailMessage(violation, baseDirectory));
+                        buildContextSeverity = -1;
+                        break;
+                    default:
+                        log.debug(getDetailMessage(violation, baseDirectory));
+                        buildContextSeverity = -1;
+                        break;
+            }
+            // only emit via build context inside eclipse, otherwise log from above is better!
+            if (buildContextSeverity > 0 && !(buildContext instanceof DefaultBuildContext)) {
+                File file;
+                if (violation.getFilePath() != null) {
+                    file = violation.getFilePath().toFile();
+                } else {
+                    // take the base path
+                    file = baseDirectory.toFile();
+                }
+                buildContext.addMessage(file, violation.getLine(), violation.getColumn(), getMessage(violation), buildContextSeverity, violation.getThrowable());
+            }
+        }
+    }
+
+    private static String getMessage(ValidationViolation violation) {
+        StringBuilder message = new StringBuilder();
+        if (violation.getValidatorId() != null) {
+            message.append(violation.getValidatorId()).append(": ");
+        }
+        message.append(violation.getMessage());
+        return message.toString();
+    }
+
+    public void printUsedValidators(Log log, ValidationExecutor executor, ValidationContext context, boolean printUnusedValidators) {
+        log.info("Using " + executor.getAllValidatorsById().entrySet().size() + " validators: " + ValidationHelper.getValidatorNames(executor, ", ") + " for package of type " + context.getPackageType());
+        if (printUnusedValidators) {
+            Map<String, Validator> unusedValidatorsById = executor.getUnusedValidatorsById();
+            if (!unusedValidatorsById.isEmpty()) {
+                log.warn("There are unused validators among those which are not executed: " + StringUtils.join(unusedValidatorsById.keySet(), "."));
+            }
+        }
+    }
+
+    private static String getDetailMessage(ValidationViolation violation, Path baseDirectory) {
+        StringBuilder message = new StringBuilder("ValidationViolation: ");
+        message.append("\"").append(getMessage(violation)).append("\"");
+        if (violation.getFilePath() != null) {
+            message.append(", filePath=").append(baseDirectory.relativize(violation.getFilePath()));
+        }
+        if (violation.getNodePath() != null) {
+            message.append(", nodePath=").append(violation.getNodePath());
+        }
+        if (violation.getLine() > 0) {
+            message.append(", line=").append(violation.getLine());
+        }
+        if (violation.getColumn() > 0) {
+            message.append(", column=").append(violation.getColumn());
+        }
+        return message.toString();
+    }
+
+    private static String getValidatorNames(ValidationExecutor executor, String separator) {
+        StringBuilder validatorNames = new StringBuilder();
+        boolean isFirstItem = true;
+        for (Map.Entry<String, Validator> validatorById : executor.getAllValidatorsById().entrySet()) {
+            if (!isFirstItem) {
+                validatorNames.append(separator);
+            } else {
+                isFirstItem = false;
+            }
+            validatorNames.append(validatorById.getKey()).append(" (").append(validatorById.getValue().getClass().getName()).append(")");
+        }
+        return validatorNames.toString();
+    }
+
+    public void clearPreviousValidationMessages(BuildContext context, File file) {
+        context.removeMessages(file);
+    }
+
+    protected void failBuildInCaseOfViolations(boolean failForWarning) throws MojoFailureException {
+        if (failForWarning && (noOfEmittedValidationMessagesWithLevelWarn > 0 || noOfEmittedValidationMessagesWithLevelError > 0)) {
+            throw new MojoFailureException("Found " +noOfEmittedValidationMessagesWithLevelWarn+noOfEmittedValidationMessagesWithLevelError + " violation(s) (either ERROR or WARN). Check above warnings/errors for details");
+        } else if (noOfEmittedValidationMessagesWithLevelError > 0) {
+            throw new MojoFailureException("Found " + noOfEmittedValidationMessagesWithLevelError + " violation(s) (with severity=ERROR). Check above errors for details");
+        }
+    }
+}

Added: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ValidatorSettings.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ValidatorSettings.java?rev=1868139&view=auto
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ValidatorSettings.java (added)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/ValidatorSettings.java Tue Oct  8 15:22:03 2019
@@ -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.filevault.maven.packaging;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.jackrabbit.vault.validation.spi.ValidationMessageSeverity;
+
+public class ValidatorSettings implements org.apache.jackrabbit.vault.validation.spi.ValidatorSettings {
+
+    @Inject
+    private final boolean isDisabled;
+    
+    private ValidationMessageSeverity defaultSeverity;
+
+    @Inject
+    private final Map<String, String> options;
+    
+    public ValidatorSettings() {
+        isDisabled = false;
+        options = new HashMap<>();
+    }
+    
+    public ValidatorSettings(ValidationMessageSeverity defaultSeverity) {
+        this();
+        this.defaultSeverity = defaultSeverity;
+    }
+
+    @Inject
+    public void setDefaultSeverity(String defaultSeverity) {
+        if (defaultSeverity != null) {
+            this.defaultSeverity = ValidationMessageSeverity.valueOf(defaultSeverity.toUpperCase());
+        }
+    }
+
+    protected String addOption(String key, String value) {
+        return options.put(key, value);
+    }
+
+    @Override
+    public ValidationMessageSeverity getDefaultSeverity() {
+        return defaultSeverity != null ? defaultSeverity : ValidationMessageSeverity.ERROR;
+    }
+
+    @Override
+    public Map<String, String> getOptions() {
+        return options;
+    }
+
+    @Override
+    public boolean isDisabled() {
+        return isDisabled;
+    }
+
+}

Modified: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/VaultMojo.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/VaultMojo.java?rev=1868139&r1=1868138&r2=1868139&view=diff
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/VaultMojo.java (original)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/VaultMojo.java Tue Oct  8 15:22:03 2019
@@ -16,8 +16,9 @@
  */
 package org.apache.jackrabbit.filevault.maven.packaging;
 
+import static org.codehaus.plexus.archiver.util.DefaultFileSet.fileSet;
+
 import java.io.File;
-import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -28,10 +29,8 @@ import java.util.Map;
 
 import javax.annotation.Nonnull;
 
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.jackrabbit.filevault.maven.packaging.impl.FileValidator;
 import org.apache.jackrabbit.vault.fs.api.PathFilterSet;
+import org.apache.jackrabbit.vault.util.Constants;
 import org.apache.jackrabbit.vault.util.PlatformNameFormat;
 import org.apache.maven.archiver.MavenArchiveConfiguration;
 import org.apache.maven.archiver.MavenArchiver;
@@ -44,18 +43,14 @@ import org.apache.maven.plugins.annotati
 import org.apache.maven.plugins.annotations.Mojo;
 import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.plugins.annotations.ResolutionScope;
-import org.codehaus.plexus.archiver.ArchiveEntry;
 import org.codehaus.plexus.archiver.Archiver;
 import org.codehaus.plexus.archiver.ArchiverException;
 import org.codehaus.plexus.archiver.FileSet;
 import org.codehaus.plexus.archiver.ResourceIterator;
-import org.codehaus.plexus.util.AbstractScanner;
 import org.codehaus.plexus.util.DirectoryScanner;
 import org.codehaus.plexus.util.FileUtils;
 import org.codehaus.plexus.util.StringUtils;
 
-import static org.codehaus.plexus.archiver.util.DefaultFileSet.fileSet;
-
 /**
  * Build a content package.
  */
@@ -64,42 +59,16 @@ import static org.codehaus.plexus.archiv
         defaultPhase = LifecyclePhase.PACKAGE,
         requiresDependencyResolution = ResolutionScope.COMPILE
 )
-public class VaultMojo extends AbstractPackageMojo {
+public class VaultMojo extends AbstractSourceAndMetadataPackageMojo {
 
     private static final String PACKAGE_TYPE = "zip";
 
-    private static final String PACKAGE_EXT = "." + PACKAGE_TYPE;
+    static final String PACKAGE_EXT = "." + PACKAGE_TYPE;
 
     @Component
     private ArtifactHandlerManager artifactHandlerManager;
 
     /**
-     * The directory containing the content to be packaged up into the content
-     * package.
-     *
-     * This property is deprecated; use jcrRootSourceDirectory instead.
-     */
-    @Deprecated
-    @Parameter
-    private File builtContentDirectory;
-
-    /**
-     * The directory that contains the jcr_root of the content. Multiple directories can be specified as a comma separated list,
-     * which will act as a search path and cause the plugin to look for the first existing directory.
-     */
-    @Parameter(
-            property = "vault.jcrRootSourceDirectory",
-            required = true,
-            defaultValue =
-                    "${project.basedir}/jcr_root," +
-                    "${project.basedir}/src/main/jcr_root," +
-                    "${project.basedir}/src/main/content/jcr_root," +
-                    "${project.basedir}/src/content/jcr_root," +
-                    "${project.build.outputDirectory}"
-    )
-    private File[] jcrRootSourceDirectory;
-    
-    /**
      * Set to {@code true} to fail the build in case of files are being contained in the {@code jcrRootSourceDirectory} 
      * which are not covered by the filter rules and therefore would not end up in the package.
      */
@@ -144,28 +113,12 @@ public class VaultMojo extends AbstractP
      * href="http://maven.apache.org/shared/maven-archiver/index.html">the
      * documentation for Maven Archiver</a>.
      * 
-     * All settings related to manifest are not relevant as this gets overwritten by the manifest in {@link AbstractPackageMojo#workDirectory}
+     * All settings related to manifest are not relevant as this gets overwritten by the manifest in {@link AbstractMetadataPackageMojo#workDirectory}
      */
     @Parameter
     private MavenArchiveConfiguration archive;
 
     /**
-     * The file name patterns to exclude in addition to the ones listed in
-     * {@link AbstractScanner#DEFAULTEXCLUDES}. The format of each pattern is described in {@link DirectoryScanner}.
-     * The comparison is against the path relative to the according filter root.
-     * Since this is hardly predictable it is recommended to use only filename/directory name patterns here 
-     * but not take into account file system hierarchies!
-     * <p>
-     * Each value is either a regex pattern if enclosed within {@code %regex[} and {@code ]}, otherwise an 
-     * <a href="https://ant.apache.org/manual/dirtasks.html#patterns">Ant pattern</a>.
-     */
-    @Parameter(property = "vault.excludes",
-               defaultValue="**/.vlt,**/.vltignore",
-               required = true)
-    private String[] excludes;
-
-
-    /**
      * Creates a {@link FileSet} for the archiver
      * @param directory the directory
      * @param prefix the prefix
@@ -204,21 +157,14 @@ public class VaultMojo extends AbstractP
 
         try {
             // find the meta-inf source directory
-            File metaInfDirectory = getMetaInfDir();
+            File metaInfDirectory = getMetaInfVaultSourceDirectory();
             // find the source directory
-            final File jcrSourceDirectory;
-            if (builtContentDirectory != null) {
-                getLog().warn("The 'builtContentDirectory' is deprecated. Please use the new 'jcrRootSourceDirectory' instead.");
-                jcrSourceDirectory = builtContentDirectory;
-            } else {
-                jcrSourceDirectory = getFirstExistingDirectory(jcrRootSourceDirectory);
-            }
+            final File jcrSourceDirectory = getJcrSourceDirectory();
             if (jcrSourceDirectory != null) {
                 getLog().info("packaging content from " + jcrSourceDirectory.getPath());
             }
-
             // retrieve filters
-            Filters filters = loadFilterFile();
+            Filters filters = loadGeneratedFilterFile();
             Map<String, File> embeddedFiles = getEmbeddedFilesMap();
 
             ContentPackageArchiver contentPackageArchiver = new ContentPackageArchiver();
@@ -249,11 +195,11 @@ public class VaultMojo extends AbstractP
                 // but ignore the roots that don't point to a directory
                 List<PathFilterSet> filterSets = filters.getFilterSets();
                 if (filterSets.isEmpty()) {
-                    contentPackageArchiver.addFileSet(createFileSet(jcrSourceDirectory, FileUtils.normalize(JCR_ROOT + prefix)));
+                    contentPackageArchiver.addFileSet(createFileSet(jcrSourceDirectory, FileUtils.normalize(Constants.ROOT_DIR + "/" + prefix)));
                 } else {
                     for (PathFilterSet filterSet : filterSets) {
                         String relPath = PlatformNameFormat.getPlatformPath(filterSet.getRoot());
-                        String rootPath = FileUtils.normalize(JCR_ROOT + prefix + relPath);
+                        String rootPath = FileUtils.normalize(Constants.ROOT_DIR + "/" + prefix + relPath);
 
                         // CQ-4204625 skip embedded files, will be added later in the proper way
                         if (embeddedFiles.containsKey(rootPath)) {
@@ -263,7 +209,7 @@ public class VaultMojo extends AbstractP
                         // check for full coverage aggregate
                         File fullCoverage = new File(jcrSourceDirectory, relPath + ".xml");
                         if (fullCoverage.isFile()) {
-                            rootPath = FileUtils.normalize(JCR_ROOT + prefix + relPath + ".xml");
+                            rootPath = FileUtils.normalize(Constants.ROOT_DIR + "/" + prefix + relPath + ".xml");
                             contentPackageArchiver.addFile(fullCoverage, rootPath);
                             continue;
                         }
@@ -282,11 +228,11 @@ public class VaultMojo extends AbstractP
 
                         // either parent node was covered by a full coverage aggregate
                         if (fullCoverage.isFile()) {
-                            rootPath = FileUtils.normalize(JCR_ROOT + prefix + relPath + ".xml");
+                            rootPath = FileUtils.normalize(Constants.ROOT_DIR + "/" + prefix + relPath + ".xml");
                             contentPackageArchiver.addFile(fullCoverage, rootPath);
                         } else {
                             // or a simple folder containing a ".content.xml"
-                            rootPath = FileUtils.normalize(JCR_ROOT + prefix + relPath);
+                            rootPath = FileUtils.normalize(Constants.ROOT_DIR + "/" + prefix + relPath);
                             // is the folder the filter root?
                             if (isFilterRootDirectory) {
                                 // then just include the full folder
@@ -318,8 +264,8 @@ public class VaultMojo extends AbstractP
                     }
                 }
 
-                // check for uncovered files
-                Collection<File> uncoveredFiles = getUncoveredFiles(jcrSourceDirectory, JCR_ROOT + prefix, contentPackageArchiver.getFiles().keySet(), null);
+                // check for uncovered files (i.e. files from the source which are not even added to the content package)
+                Collection<File> uncoveredFiles = getUncoveredFiles(jcrSourceDirectory, Constants.ROOT_DIR + "/" + prefix, contentPackageArchiver.getFiles().keySet(), null);
                 if (!uncoveredFiles.isEmpty()) {
                     for (File uncoveredFile : uncoveredFiles) {
                         getLog().warn("File " + uncoveredFile + " not covered by a filter rule and therefore not contained in the resulting package");
@@ -331,7 +277,9 @@ public class VaultMojo extends AbstractP
             }
 
             //NPR-14102 - Automated check for index definition
+            /*
             if (!allowIndexDefinitions) {
+                
                 FileValidator fileValidator = new FileValidator();
                 getLog().info("Scanning files for oak index definitions.");
                 for (ArchiveEntry entry: contentPackageArchiver.getFiles().values()) {
@@ -339,8 +287,7 @@ public class VaultMojo extends AbstractP
                         InputStream in = null;
                         try {
                             in = entry.getInputStream();
-                            // ArchiveEntry.name always contains platform-dependent separators, convert to forwards slashes as separator
-                            String sanitizedFileName = FilenameUtils.separatorsToUnix(entry.getName());
+                            
                             fileValidator.lookupIndexDefinitionInArtifact(in, sanitizedFileName);
                         } finally {
                             IOUtils.closeQuietly(in);
@@ -351,12 +298,12 @@ public class VaultMojo extends AbstractP
                     getLog().error(fileValidator.getMessageWithPathsOfIndexDef());
                     throw new MojoExecutionException("Package should not contain index definitions, because 'allowIndexDefinitions=false'.");
                 }
-            }
+            }*/
 
             MavenArchiver mavenArchiver = new MavenArchiver();
             mavenArchiver.setArchiver(contentPackageArchiver);
             mavenArchiver.setOutputFile(finalFile);
-            mavenArchiver.createArchive(null, project, getMavenArchiveConfiguration(getManifestFile()));
+            mavenArchiver.createArchive(null, project, getMavenArchiveConfiguration(getGeneratedManifestFile()));
 
             // set the file for the project's artifact and ensure the
             // artifact is correctly handled with the "zip" handler

Added: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/util/EnhancedBufferedInputStream.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/util/EnhancedBufferedInputStream.java?rev=1868139&view=auto
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/util/EnhancedBufferedInputStream.java (added)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/util/EnhancedBufferedInputStream.java Tue Oct  8 15:22:03 2019
@@ -0,0 +1,49 @@
+/*
+ * 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.filevault.maven.packaging.impl.util;
+
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+
+/**
+ * Similar to {@link BufferedInputStream} but allows to access the delegate via {@link #getDelegate()}.
+ */
+public class EnhancedBufferedInputStream extends BufferedInputStream {
+
+    private final InputStream delegate;
+    
+    public EnhancedBufferedInputStream(InputStream in, int size) {
+        super(in, size);
+        this.delegate = in;
+    }
+
+    public EnhancedBufferedInputStream(InputStream in) {
+        super(in);
+        this.delegate = in;
+    }
+
+    public InputStream getDelegate() {
+        return delegate;
+    }
+
+    public static InputStream tryUnwrap(InputStream input) {
+        while (input instanceof EnhancedBufferedInputStream) {
+            input = EnhancedBufferedInputStream.class.cast(input).getDelegate();
+        }
+        return input;
+    }
+}

Added: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/util/EnhancedBufferedOutputStream.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/util/EnhancedBufferedOutputStream.java?rev=1868139&view=auto
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/util/EnhancedBufferedOutputStream.java (added)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/impl/util/EnhancedBufferedOutputStream.java Tue Oct  8 15:22:03 2019
@@ -0,0 +1,50 @@
+/*
+ * 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.filevault.maven.packaging.impl.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.OutputStream;
+
+/**
+ * Similar to {@link BufferedInputStream} but allows to access the delegate via {@link #getDelegate()}.
+ */
+public class EnhancedBufferedOutputStream extends BufferedOutputStream {
+
+    private final OutputStream delegate;
+    
+    public EnhancedBufferedOutputStream(OutputStream out, int size) {
+        super(out, size);
+        this.delegate = out;
+    }
+
+    public EnhancedBufferedOutputStream(OutputStream out) {
+        super(out);
+        this.delegate = out;
+    }
+
+    public OutputStream getDelegate() {
+        return delegate;
+    }
+
+    public static OutputStream tryUnwrap(OutputStream output) {
+        while (output instanceof EnhancedBufferedOutputStream) {
+            output = EnhancedBufferedOutputStream.class.cast(output).getDelegate();
+        }
+        return output;
+    }
+}

Added: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/validator/impl/context/ArchiveValidationContextImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/validator/impl/context/ArchiveValidationContextImpl.java?rev=1868139&view=auto
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/validator/impl/context/ArchiveValidationContextImpl.java (added)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/validator/impl/context/ArchiveValidationContextImpl.java Tue Oct  8 15:22:03 2019
@@ -0,0 +1,94 @@
+/*
+ * 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.filevault.maven.packaging.validator.impl.context;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.Properties;
+
+import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter;
+import org.apache.jackrabbit.vault.fs.io.Archive;
+import org.apache.jackrabbit.vault.packaging.PackageInfo;
+import org.apache.jackrabbit.vault.packaging.PackageProperties;
+import org.apache.jackrabbit.vault.packaging.impl.PackagePropertiesImpl;
+import org.apache.jackrabbit.vault.validation.spi.ValidationContext;
+import org.apache.maven.plugin.logging.Log;
+
+
+/**
+ * Implements a validation context based on a given {@link Archive}.
+ */
+public class ArchiveValidationContextImpl extends PackagePropertiesImpl implements ValidationContext {
+
+    private final WorkspaceFilter filter;
+    private final Properties properties;
+    private final Path archivePath;
+    private final Collection<PackageInfo> resolvedDependencies;
+
+    /**
+     * 
+     * @param archive
+     * @param archivePath
+     * @param configuration
+     * @throws IOException 
+     */
+    public ArchiveValidationContextImpl(Archive archive, Path archivePath, DependencyResolver resolver, Collection<PackageInfo> resolvedDependencies, Log log) throws IOException {
+        this.archivePath = archivePath;
+        properties = archive.getMetaInf().getProperties();
+        if (properties == null) {
+            throw new IllegalStateException("Archive '" + archivePath + "' does not contain a properties.xml.");
+        }
+        this.filter = archive.getMetaInf().getFilter();
+        if (filter == null) {
+            throw new IllegalStateException("Archive '" + archivePath + "' does not contain a filter.xml.");
+        }
+        this.resolvedDependencies = resolver.resolve(getProperties().getDependencies(), resolvedDependencies, log);
+    }
+
+
+    @Override
+    protected Properties getPropertiesMap() {
+        return properties;
+    }
+
+    @Override
+    public PackageProperties getProperties() {
+        return this;
+    }
+
+    @Override
+    public WorkspaceFilter getFilter() {
+        return filter;
+    }
+
+    @Override
+    public ValidationContext getContainerValidationContext() {
+        return null;
+    }
+
+    public Path getPackageRootPath() {
+        return archivePath;
+    }
+
+
+    @Override
+    public Collection<PackageInfo> getDependenciesMetaInfo() {
+        return this.resolvedDependencies;
+    }
+
+}

Added: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/validator/impl/context/DependencyResolver.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/validator/impl/context/DependencyResolver.java?rev=1868139&view=auto
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/validator/impl/context/DependencyResolver.java (added)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/validator/impl/context/DependencyResolver.java Tue Oct  8 15:22:03 2019
@@ -0,0 +1,141 @@
+/*
+ * 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.filevault.maven.packaging.validator.impl.context;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.CheckForNull;
+
+import org.apache.jackrabbit.vault.packaging.Dependency;
+import org.apache.jackrabbit.vault.packaging.PackageInfo;
+import org.apache.jackrabbit.vault.packaging.VersionRange;
+import org.apache.jackrabbit.vault.packaging.impl.DefaultPackageInfo;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.RepositoryRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.artifact.resolver.ResolutionErrorHandler;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.repository.RepositorySystem;
+
+/**
+ * Allows to resolve a {@link Dependency} from the underlying Maven repository (first local, then remote).
+ */
+public class DependencyResolver {
+
+    private final RepositoryRequest repositoryRequest;
+    private final RepositorySystem repositorySystem;
+    private final ResolutionErrorHandler resolutionErrorHandler;
+    private final Map<Dependency, Artifact> mapPackageDependencyToMavenArtifact;
+
+    public DependencyResolver(RepositoryRequest repositoryRequest, RepositorySystem repositorySystem, ResolutionErrorHandler resolutionErrorHandler, Map<Dependency, Artifact> mapPackageDependencyToMavenArtifact) {
+        super();
+        this.repositoryRequest = repositoryRequest;
+        this.repositorySystem = repositorySystem;
+        this.resolutionErrorHandler = resolutionErrorHandler;
+        this.mapPackageDependencyToMavenArtifact = mapPackageDependencyToMavenArtifact;
+    }
+
+    public List<PackageInfo> resolve(Dependency[] dependencies, Collection<PackageInfo> potentiallyResolvedDependencies, Log log) throws IOException {
+        List<PackageInfo> resolvedDependencies = new LinkedList<>(potentiallyResolvedDependencies);
+        
+        // resolve dependencies
+        for (Dependency dependency : dependencies) {
+            boolean dependencyAlreadyResolved = false;
+            // is it already resolved?
+            for (PackageInfo resolvedDependency : resolvedDependencies) {
+                if (dependency.matches(resolvedDependency.getId())) {
+                    log.debug("Dependency is already resolved from project dependencies: " + dependency);
+                    dependencyAlreadyResolved = true;
+                    break;
+                }
+            }
+            if (!dependencyAlreadyResolved) {
+                log.info("Trying to resolve dependency '" + dependency + "' from Maven repository");
+                PackageInfo resolvedDependency = resolve(dependency, log);
+                if (resolvedDependency != null) {
+                    resolvedDependencies.add(resolvedDependency);
+                }
+            }
+        }
+        return resolvedDependencies;
+    }
+
+    public @CheckForNull PackageInfo resolve(Dependency dependency, Log log) throws IOException {
+        // resolving a version range is not supported with Maven API, but only with lower level Aether API (requires Maven 3.5 or newer)
+        // https://github.com/eclipse/aether-demo/blob/master/aether-demo-snippets/src/main/java/org/eclipse/aether/examples/FindAvailableVersions.java
+        // therefore do an best effort resolve instead
+        
+        File file = null;
+        final String groupId;
+        final String artifactId;
+        Artifact artifact = mapPackageDependencyToMavenArtifact.get(dependency);
+        // is it part of the mapping table?
+        if (artifact != null) {
+            groupId = artifact.getGroupId();
+            artifactId = artifact.getArtifactId();
+        } else {
+            groupId = dependency.getGroup();
+            artifactId = dependency.getName();
+        }
+        if (dependency.getRange().isLowInclusive()) {
+            file = resolve(groupId, artifactId, dependency.getRange().getLow().toString(), log);
+        }
+        if (file == null && dependency.getRange().isHighInclusive()) {
+            file = resolve(groupId, artifactId, dependency.getRange().getHigh().toString(), log);
+        }
+        if (file == null && VersionRange.INFINITE.equals(dependency.getRange())) {
+            file = resolve(groupId, artifactId, Artifact.LATEST_VERSION, log);
+        }
+        if (file == null) {
+            log.warn("Could not resolve dependency from any Maven Repository for dependency " + dependency);
+            return null;
+        }
+        return DefaultPackageInfo.read(file);
+    }
+
+    private @CheckForNull File resolve(String groupId, String artifactId, String version, Log log) {
+        Artifact artifact = repositorySystem.createArtifact(groupId, artifactId, version, "zip");
+        return resolve(artifact, log);
+    }
+
+    private @CheckForNull File resolve(Artifact artifact, Log log) {
+        ArtifactResolutionRequest resolutionRequest = new ArtifactResolutionRequest(repositoryRequest);
+        resolutionRequest.setArtifact(artifact);
+        ArtifactResolutionResult result = repositorySystem.resolve(resolutionRequest);
+        if (result.isSuccess()) {
+            log.debug("Successfully resolved artifact " + artifact.getArtifactId());
+            Artifact resolvedArtifact = result.getArtifacts().iterator().next();
+            return resolvedArtifact.getFile();
+        } else {
+            try {
+                resolutionErrorHandler.throwErrors(resolutionRequest, result);
+            } catch (ArtifactResolutionException e) {
+                log.warn("Could not resolve artifact '" + artifact +"': " + e.getMessage());
+                log.debug(e);
+            }
+            return null;
+        }
+        
+    }
+}

Added: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/validator/impl/context/DirectoryValidationContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/validator/impl/context/DirectoryValidationContext.java?rev=1868139&view=auto
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/validator/impl/context/DirectoryValidationContext.java (added)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/validator/impl/context/DirectoryValidationContext.java Tue Oct  8 15:22:03 2019
@@ -0,0 +1,122 @@
+/*
+ * 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.filevault.maven.packaging.validator.impl.context;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.filevault.maven.packaging.GenerateMetadataMojo;
+import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter;
+import org.apache.jackrabbit.vault.fs.config.ConfigurationException;
+import org.apache.jackrabbit.vault.fs.config.DefaultWorkspaceFilter;
+import org.apache.jackrabbit.vault.packaging.PackageId;
+import org.apache.jackrabbit.vault.packaging.PackageInfo;
+import org.apache.jackrabbit.vault.packaging.PackageProperties;
+import org.apache.jackrabbit.vault.packaging.PackageType;
+import org.apache.jackrabbit.vault.packaging.impl.DefaultPackageProperties;
+import org.apache.jackrabbit.vault.util.Constants;
+import org.apache.jackrabbit.vault.validation.spi.ValidationContext;
+import org.apache.maven.plugin.logging.Log;
+
+/**
+ * Validation context built from files in two directories:
+ * <ul>
+ *  <li>workDir, the directory in which the {@link GenerateMetadataMojo} has written all automatically generated files (must have name META-INF)
+ *  <li>metaInfDir, the directory in which meta inf files have been manually written (must have name META-INF)
+ * </ul>
+ */
+public class DirectoryValidationContext implements ValidationContext {
+
+    private final PackageProperties properties;
+    private final DefaultWorkspaceFilter filter;
+    private List<PackageInfo> resolvedDependencies;
+    
+    private static final Path RELATIVE_PROPERTIES_XML_PATH = Paths.get(Constants.VAULT_DIR, Constants.PROPERTIES_XML);
+
+    public DirectoryValidationContext(@Nonnull final File generatedMetaInfRootDirectory, final File metaInfRootDirectory, DependencyResolver resolver, Collection<PackageInfo> resolvedDependencies, @Nonnull final Log log) throws IOException, ConfigurationException {
+        Path propertiesPath = null;
+        if (!Constants.META_INF.equals(generatedMetaInfRootDirectory.getName())) {
+            throw new IllegalArgumentException("The workDir must end with 'META-INF' but is '" + generatedMetaInfRootDirectory+"'");
+        }
+        if (metaInfRootDirectory != null) {
+            if (!Constants.META_INF.equals(metaInfRootDirectory.getName())) {
+                throw new IllegalArgumentException("The metaInfRootDirectory must end with 'META-INF' but is '" + metaInfRootDirectory+"'");
+            }
+            propertiesPath = metaInfRootDirectory.toPath().resolve(Constants.VAULT_DIR).resolve(Constants.PROPERTIES_XML);
+        }
+        if (propertiesPath == null || !Files.exists(propertiesPath)) {
+            propertiesPath = generatedMetaInfRootDirectory.toPath().resolve(RELATIVE_PROPERTIES_XML_PATH);
+            if (!Files.exists(propertiesPath)) {
+                throw new IllegalStateException("No " + RELATIVE_PROPERTIES_XML_PATH + " found in either " +metaInfRootDirectory + " or " + generatedMetaInfRootDirectory);
+            }
+            log.debug("Using " + RELATIVE_PROPERTIES_XML_PATH + " from directory " + generatedMetaInfRootDirectory);
+        } else {
+            log.debug("Using " + RELATIVE_PROPERTIES_XML_PATH + " from directory " + metaInfRootDirectory);
+        }
+        properties = DefaultPackageProperties.fromFile(propertiesPath);
+        
+        // filter always comes from the workDir
+        filter = new DefaultWorkspaceFilter();
+        filter.load(new File(generatedMetaInfRootDirectory, Constants.VAULT_DIR +"/"+Constants.FILTER_XML));
+        
+        this.resolvedDependencies = resolver.resolve(getProperties().getDependencies(), resolvedDependencies, log);
+    }
+
+    @Override
+    public PackageProperties getProperties() {
+        return properties;
+    }
+
+    @Override
+    public WorkspaceFilter getFilter() {
+        return filter;
+    }
+
+    @Override
+    public ValidationContext getContainerValidationContext() {
+        return null;
+    }
+
+    @Override
+    public Path getPackageRootPath() {
+        return null;
+    }
+
+    @Override
+    public Collection<PackageInfo> getDependenciesMetaInfo() {
+        return resolvedDependencies;
+    }
+
+    @Override
+    public PackageId getId() {
+        return properties.getId();
+    }
+
+    @Override
+    public PackageType getPackageType() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+}
\ No newline at end of file

Added: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/validator/impl/context/SubPackageValidationContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/validator/impl/context/SubPackageValidationContext.java?rev=1868139&view=auto
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/validator/impl/context/SubPackageValidationContext.java (added)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/java/org/apache/jackrabbit/filevault/maven/packaging/validator/impl/context/SubPackageValidationContext.java Tue Oct  8 15:22:03 2019
@@ -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.filevault.maven.packaging.validator.impl.context;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+import org.apache.jackrabbit.vault.fs.io.Archive;
+import org.apache.jackrabbit.vault.validation.spi.ValidationContext;
+import org.apache.maven.plugin.logging.Log;
+
+public class SubPackageValidationContext extends ArchiveValidationContextImpl {
+
+    private final ValidationContext containerPackageContext;
+
+    public SubPackageValidationContext(ArchiveValidationContextImpl containerPackageContext, Archive archive, Path archivePath, DependencyResolver resolver, Log log) throws IOException {
+        super(archive, archivePath, resolver, containerPackageContext.getDependenciesMetaInfo(), log);
+        this.containerPackageContext = containerPackageContext;
+    }
+
+    @Override
+    public ValidationContext getContainerValidationContext() {
+        return containerPackageContext;
+    }
+
+}

Modified: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml?rev=1868139&r1=1868138&r2=1868139&view=diff
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml (original)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml Tue Oct  8 15:22:03 2019
@@ -31,6 +31,7 @@
             <pluginExecutionFilter>
                 <goals>
                     <goal>generate-metadata</goal>
+                    <goal>validate-files</goal>
                 </goals>
             </pluginExecutionFilter>
             <action>

Modified: jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/resources/META-INF/plexus/components.xml
URL: http://svn.apache.org/viewvc/jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/resources/META-INF/plexus/components.xml?rev=1868139&r1=1868138&r2=1868139&view=diff
==============================================================================
--- jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/resources/META-INF/plexus/components.xml (original)
+++ jackrabbit/commons/filevault-package-maven-plugin/trunk/src/main/resources/META-INF/plexus/components.xml Tue Oct  8 15:22:03 2019
@@ -32,13 +32,17 @@
                             <process-classes>
                                 org.apache.jackrabbit:filevault-package-maven-plugin:check-signature,
                                 org.apache.jackrabbit:filevault-package-maven-plugin:analyze-classes,
-                                org.apache.jackrabbit:filevault-package-maven-plugin:generate-metadata
+                                org.apache.jackrabbit:filevault-package-maven-plugin:generate-metadata,
+                                org.apache.jackrabbit:filevault-package-maven-plugin:validate-files
                             </process-classes>
                             <process-test-resources>org.apache.maven.plugins:maven-resources-plugin:testResources
                             </process-test-resources>
                             <test-compile>org.apache.maven.plugins:maven-compiler-plugin:testCompile</test-compile>
                             <test>org.apache.maven.plugins:maven-surefire-plugin:test</test>
-                            <package>org.apache.jackrabbit:filevault-package-maven-plugin:package</package>
+                            <package>
+                                org.apache.jackrabbit:filevault-package-maven-plugin:package,
+                                org.apache.jackrabbit:filevault-package-maven-plugin:validate-package
+                            </package>
                             <install>org.apache.maven.plugins:maven-install-plugin:install</install>
                             <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
                         </phases>



Mime
View raw message