You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2015/04/10 11:17:14 UTC

svn commit: r1672590 - in /sling/trunk/tooling/maven/slingstart-maven-plugin/src/main: java/org/apache/sling/maven/slingstart/ resources/META-INF/plexus/

Author: cziegeler
Date: Fri Apr 10 09:17:14 2015
New Revision: 1672590

URL: http://svn.apache.org/r1672590
Log:
Delay resolving of reactor projects until project is built

Added:
    sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/PrepareSlingStartMojo.java   (with props)
Modified:
    sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/AbstractSlingStartMojo.java
    sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/DependencyLifecycleParticipant.java
    sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/ModelUtils.java
    sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/PreparePackageMojo.java
    sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/resources/META-INF/plexus/components.xml

Modified: sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/AbstractSlingStartMojo.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/AbstractSlingStartMojo.java?rev=1672590&r1=1672589&r2=1672590&view=diff
==============================================================================
--- sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/AbstractSlingStartMojo.java (original)
+++ sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/AbstractSlingStartMojo.java Fri Apr 10 09:17:14 2015
@@ -28,7 +28,7 @@ import org.apache.maven.project.MavenPro
 public abstract class AbstractSlingStartMojo extends AbstractMojo {
 
     @Parameter(defaultValue="${basedir}/src/main/provisioning")
-    private File systemsDirectory;
+    private File modelDirectory;
 
     @Parameter(property = "project", readonly = true, required = true)
     protected MavenProject project;

Modified: sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/DependencyLifecycleParticipant.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/DependencyLifecycleParticipant.java?rev=1672590&r1=1672589&r2=1672590&view=diff
==============================================================================
--- sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/DependencyLifecycleParticipant.java (original)
+++ sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/DependencyLifecycleParticipant.java Fri Apr 10 09:17:14 2015
@@ -18,17 +18,15 @@ package org.apache.sling.maven.slingstar
 
 import java.io.File;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.maven.AbstractMavenLifecycleParticipant;
 import org.apache.maven.MavenExecutionException;
 import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.DefaultArtifact;
 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
-import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
-import org.apache.maven.artifact.resolver.ArtifactResolutionException;
 import org.apache.maven.artifact.resolver.ArtifactResolver;
-import org.apache.maven.artifact.versioning.VersionRange;
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.Plugin;
@@ -52,8 +50,6 @@ public class DependencyLifecycleParticip
 
     private static final String PLUGIN_ID = "slingstart-maven-plugin";
 
-    private static final String PROVIDED = "provided";
-
     @Requirement
     private Logger log;
 
@@ -70,69 +66,95 @@ public class DependencyLifecycleParticip
     @Override
     public void afterProjectsRead(final MavenSession session) throws MavenExecutionException {
         log.debug("Searching for slingstart projects...");
-            for (final MavenProject project : session.getProjects()) {
-                for (Plugin plugin : project.getBuild().getPlugins()) {
-                    if (plugin.getArtifactId().equals(PLUGIN_ID)) {
-                        try {
-                            addDependencies(artifactHandlerManager, resolver, log,
-                                    session, project, plugin);
-                        } catch (final Exception e) {
-                            throw new MavenExecutionException("Unable to determine plugin-based dependencies for project " + project, e);
-                        }
+        for (final MavenProject project : session.getProjects()) {
+            for (Plugin plugin : project.getBuild().getPlugins()) {
+                if (plugin.getArtifactId().equals(PLUGIN_ID)) {
+                    log.debug("Found potential slingstart project: " + project);
+                    try {
+                        addDependencies(artifactHandlerManager, resolver, log,
+                                session, project, plugin);
+                    } catch (final Exception e) {
+                        throw new MavenExecutionException("Unable to determine plugin-based dependencies for project " + project, e);
                     }
                 }
             }
+        }
     }
 
     public static void addDependencies(final ArtifactHandlerManager artifactHandlerManager,
             final ArtifactResolver resolver,
             final Logger log,
-            final MavenSession session, final MavenProject project, final Plugin plugin)
+            final MavenSession session,
+            final MavenProject project,
+            final Plugin plugin)
     throws Exception {
-        // check dependent projects first
-        final List<File> dependencies = new ArrayList<File>();
+        // get all projects of the current build
+        final Map<String, MavenProject> projectMap = new HashMap<String, MavenProject>();
+        for (final MavenProject p : session.getProjects()) {
+            projectMap.put(p.getGroupId() + ":" + p.getArtifactId() + ":" + p.getVersion(), p);
+        }
+
+        // check dependent projects first: slingstart or partial system
+        final List<Object> allDependencies = new ArrayList<Object>();
+        final List<File> resolvedModelDependencies = new ArrayList<File>();
         for(final Dependency d : project.getDependencies() ) {
             if ( d.getType().equals(BuildConstants.PACKAGING_SLINGSTART)
               || d.getType().equals(BuildConstants.PACKAGING_PARTIAL_SYSTEM)) {
-                final File modelFile = getSlingstartArtifact(artifactHandlerManager, resolver, project, session, d);
-                dependencies.add(modelFile);
+                // if it's a project from the current reactor build, we can't resolve it right now
+                final String key = d.getGroupId() + ":" + d.getArtifactId() + ":" + d.getVersion();
+                if ( projectMap.containsKey(key) ) {
+                    allDependencies.add(key + ":" + d.getClassifier() + ":" + d.getType());
+                } else {
+                    // "external" dependency, we can already resolve it
+                    final File modelFile = ModelUtils.getSlingstartArtifact(artifactHandlerManager, resolver, project, session, d);
+                    resolvedModelDependencies.add(modelFile);
+                    allDependencies.add(modelFile);
+                }
             }
         }
 
+        // read local model
         final String directory = nodeValue((Xpp3Dom) plugin.getConfiguration(),
-                "systemsDirectory", new File(project.getBasedir(), "src/main/provisioning").getAbsolutePath());
-        final Model model = ModelUtils.readFullModel(new File(directory), dependencies, project, session, log);
+                "modelDirectory", new File(project.getBasedir(), "src/main/provisioning").getAbsolutePath());
+        final Model model = ModelUtils.readFullModel(new File(directory), resolvedModelDependencies, project, session, log);
 
-        ModelUtils.storeRawModel(project, model);
+        ModelUtils.storeModelInfo(project, model, allDependencies);
 
+        // we have to create an effective model to add the dependencies
         final Model effectiveModel = ModelUtility.getEffectiveModel(model, null);
 
-        ModelUtils.storeEffectiveModel(project, effectiveModel);
-
         if ( project.getPackaging().equals(BuildConstants.PACKAGING_SLINGSTART ) ) {
             // start with base artifact
-            final org.apache.sling.provisioning.model.Artifact base = ModelUtils.getBaseArtifact(effectiveModel);
-            final String[] classifiers = new String[] {null, BuildConstants.CLASSIFIER_APP, BuildConstants.CLASSIFIER_WEBAPP};
-            for(final String c : classifiers) {
-                final Dependency dep = new Dependency();
-                dep.setGroupId(base.getGroupId());
-                dep.setArtifactId(base.getArtifactId());
-                dep.setVersion(base.getVersion());
-                dep.setType(base.getType());
-                dep.setClassifier(c);
-                if ( BuildConstants.CLASSIFIER_WEBAPP.equals(c) ) {
-                    dep.setType(BuildConstants.TYPE_WAR);
-                }
-                dep.setScope(PROVIDED);
+            final ModelUtils.SearchResult result = ModelUtils.findBaseArtifact(effectiveModel);
+            if ( result.artifact != null ) {
+                final String[] classifiers = new String[] {null, BuildConstants.CLASSIFIER_APP, BuildConstants.CLASSIFIER_WEBAPP};
+                for(final String c : classifiers) {
+                    final Dependency dep = new Dependency();
+                    dep.setGroupId(result.artifact.getGroupId());
+                    dep.setArtifactId(result.artifact.getArtifactId());
+                    dep.setVersion(result.artifact.getVersion());
+                    dep.setType(result.artifact.getType());
+                    dep.setClassifier(c);
+                    if ( BuildConstants.CLASSIFIER_WEBAPP.equals(c) ) {
+                        dep.setType(BuildConstants.TYPE_WAR);
+                    }
+                    dep.setScope(Artifact.SCOPE_PROVIDED);
 
-                log.debug("- adding dependency " + dep);
-                project.getDependencies().add(dep);
+                    log.debug("- adding dependency " + dep);
+                    project.getDependencies().add(dep);
+                }
             }
         }
-        addDependencies(effectiveModel, log, project);
+        addDependenciesFromModel(project, effectiveModel, log);
     }
 
-    private static void addDependencies(final Model model, final Logger log, final MavenProject project) {
+    /**
+     * Add all dependencies from the model
+     * @param project The project
+     * @param model The model
+     * @param log The logger
+     */
+    private static void addDependenciesFromModel(final MavenProject project, final Model model, final Logger log) {
         for(final Feature feature : model.getFeatures()) {
             // skip base
             if ( feature.getName().equals(ModelConstants.FEATURE_LAUNCHPAD) ) {
@@ -147,7 +169,7 @@ public class DependencyLifecycleParticip
                         dep.setVersion(a.getVersion());
                         dep.setType(a.getType());
                         dep.setClassifier(a.getClassifier());
-                        dep.setScope(PROVIDED);
+                        dep.setScope(Artifact.SCOPE_PROVIDED);
 
                         log.debug("- adding dependency " + dep);
                         project.getDependencies().add(dep);
@@ -157,29 +179,6 @@ public class DependencyLifecycleParticip
         }
     }
 
-    private static File getSlingstartArtifact(final ArtifactHandlerManager artifactHandlerManager,
-            final ArtifactResolver resolver,
-            final MavenProject project,
-            final MavenSession session,
-            final Dependency d)
-    throws MavenExecutionException {
-        final Artifact prjArtifact = new DefaultArtifact(d.getGroupId(),
-                d.getArtifactId(),
-                VersionRange.createFromVersion(d.getVersion()),
-                Artifact.SCOPE_PROVIDED,
-                d.getType(),
-                d.getClassifier(),
-                artifactHandlerManager.getArtifactHandler(d.getType()));
-        try {
-            resolver.resolve(prjArtifact, project.getRemoteArtifactRepositories(), session.getLocalRepository());
-        } catch (final ArtifactResolutionException e) {
-            throw new MavenExecutionException("Unable to get artifact for " + d, e);
-        } catch (final ArtifactNotFoundException e) {
-            throw new MavenExecutionException("Unable to get artifact for " + d, e);
-        }
-        return prjArtifact.getFile();
-    }
-
     private static String nodeValue(final Xpp3Dom config, final String name, final String defaultValue) {
         final Xpp3Dom node = (config == null ? null : config.getChild(name));
         if (node != null) {

Modified: sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/ModelUtils.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/ModelUtils.java?rev=1672590&r1=1672589&r2=1672590&view=diff
==============================================================================
--- sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/ModelUtils.java (original)
+++ sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/ModelUtils.java Fri Apr 10 09:17:14 2015
@@ -28,6 +28,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.maven.MavenExecutionException;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.DefaultArtifact;
 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
@@ -36,6 +37,7 @@ import org.apache.maven.artifact.resolve
 import org.apache.maven.artifact.resolver.ArtifactResolver;
 import org.apache.maven.artifact.versioning.VersionRange;
 import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Dependency;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.project.MavenProject;
 import org.apache.sling.provisioning.model.Feature;
@@ -50,33 +52,44 @@ import org.codehaus.plexus.logging.Logge
 
 public abstract class ModelUtils {
 
+    private static final String EXT_TXT = ".txt";
+    private static final String EXT_MODEL = ".model";
+
     /**
-     * Read all model files from the directory in alphabetical order
-     * @param logger
+     * Read all model files from the directory in alphabetical order.
+     * Only files ending with .txt or .model are read.
+     *
+     * @param startingModel The model into which the read models are merged or {@code null}
+     * @param modelDirectory The directory to scan for models
+     * @param project The current maven project
+     * @param session The current maven session
+     * @param logger The logger
      */
     private static Model readLocalModel(final Model startingModel,
-            final File systemsDirectory,
+            final File modelDirectory,
             final MavenProject project,
             final MavenSession session,
             final Logger logger)
     throws MojoExecutionException {
         final Model result = (startingModel != null ? startingModel : new Model());
         final List<String> candidates = new ArrayList<String>();
-        if ( systemsDirectory != null && systemsDirectory.exists() ) {
-            for(final File f : systemsDirectory.listFiles() ) {
-                if ( f.isFile() && f.getName().endsWith(".txt") && !f.getName().startsWith(".") ) {
-                    candidates.add(f.getName());
+        if ( modelDirectory != null && modelDirectory.exists() ) {
+            for(final File f : modelDirectory.listFiles() ) {
+                if ( f.isFile() && !f.getName().startsWith(".") ) {
+                    if ( f.getName().endsWith(EXT_TXT) || f.getName().endsWith(EXT_MODEL) ) {
+                        candidates.add(f.getName());
+                    }
                 }
             }
             Collections.sort(candidates);
         }
         if ( candidates.size() == 0 ) {
-            throw new MojoExecutionException("No model files found in " + systemsDirectory);
+            throw new MojoExecutionException("No model files found in " + modelDirectory);
         }
         for(final String name : candidates) {
             logger.debug("Reading model " + name + " in project " + project.getId());
             try {
-                final File f = new File(systemsDirectory, name);
+                final File f = new File(modelDirectory, name);
                 final FileReader reader = new FileReader(f);
                 try {
                     final Model current = ModelReader.read(reader, f.getAbsolutePath());
@@ -89,7 +102,7 @@ public abstract class ModelUtils {
                     IOUtils.closeQuietly(reader);
                 }
             } catch ( final IOException io) {
-                throw new MojoExecutionException("Unable to read " + name, io);
+                throw new MojoExecutionException("Unable to read model at " + name, io);
             }
         }
 
@@ -104,30 +117,32 @@ public abstract class ModelUtils {
     /**
      * Read the full model
      */
-    public static Model readFullModel(final File systemsDirectory,
+    public static Model readFullModel(final File modelDirectory,
             final List<File> dependentModels,
             final MavenProject project,
             final MavenSession session,
             final Logger logger)
     throws MojoExecutionException {
         try {
-            // check dependent models
+            // read dependent models
             Model depModel = null;
-            for(final File file : dependentModels) {
-                FileReader r = null;
-                try {
-                    r = new FileReader(file);
-                    if ( depModel == null ) {
-                        depModel = new Model();
+            if ( dependentModels != null ) {
+                for(final File file : dependentModels) {
+                    FileReader r = null;
+                    try {
+                        r = new FileReader(file);
+                        if ( depModel == null ) {
+                            depModel = new Model();
+                        }
+                        final Model readModel = ModelReader.read(r, file.getAbsolutePath());
+                        final Map<Traceable, String> errors = ModelUtility.validate(readModel);
+                        if (errors != null ) {
+                            throw new MojoExecutionException("Invalid model at " + file + " : " + errors);
+                        }
+                        ModelUtility.merge(depModel, readModel);
+                    } finally {
+                        IOUtils.closeQuietly(r);
                     }
-                    final Model readModel = ModelReader.read(r, file.getAbsolutePath());
-                    final Map<Traceable, String> errors = ModelUtility.validate(readModel);
-                    if (errors != null ) {
-                        throw new MojoExecutionException("Invalid model at " + file + " : " + errors);
-                    }
-                    ModelUtility.merge(depModel, readModel);
-                } finally {
-                    IOUtils.closeQuietly(r);
                 }
             }
             if ( depModel != null ) {
@@ -137,7 +152,7 @@ public abstract class ModelUtils {
                 }
             }
 
-            final Model result = readLocalModel(depModel, systemsDirectory, project, session, logger);
+            final Model result = readLocalModel(depModel, modelDirectory, project, session, logger);
 
             return result;
         } catch ( final IOException ioe) {
@@ -145,31 +160,69 @@ public abstract class ModelUtils {
         }
     }
 
-    public static org.apache.sling.provisioning.model.Artifact getBaseArtifact(final Model model) throws MojoExecutionException {
+    public static final class SearchResult {
+        public org.apache.sling.provisioning.model.Artifact artifact;
+        public String errorMessage;
+    }
+
+    public static SearchResult findBaseArtifact(final Model model) throws MojoExecutionException {
+        final SearchResult result = new SearchResult();
         final Feature base = model.getFeature(ModelConstants.FEATURE_LAUNCHPAD);
         if ( base == null ) {
-            throw new MojoExecutionException("No launchpad feature found.");
-        }
-        // get global run mode
-        final RunMode runMode = base.getRunMode(null);
-        if ( runMode == null ) {
-            throw new MojoExecutionException("No global run mode found in launchpad feature.");
-        }
-        if ( runMode.getArtifactGroups().isEmpty() ) {
-            throw new MojoExecutionException("No base artifacts defined.");
-        }
-        if ( runMode.getArtifactGroups().size() > 1 ) {
-            throw new MojoExecutionException("Base run mode should only have a single start level.");
-        }
-        org.apache.sling.provisioning.model.Artifact firstArtifact = null;
-        for(final org.apache.sling.provisioning.model.Artifact a : runMode.getArtifactGroups().get(0)) {
-            if ( firstArtifact == null ) {
-                firstArtifact = a;
+            result.errorMessage = "No launchpad feature found.";
+        } else {
+            // get global run mode
+            final RunMode runMode = base.getRunMode();
+            if ( runMode == null ) {
+                result.errorMessage = "No global run mode found in launchpad feature.";
             } else {
-                throw new MojoExecutionException("Base run mode should contain exactly one artifact.");
+                if ( runMode.getArtifactGroups().isEmpty() ) {
+                    result.errorMessage = "No base artifacts defined.";
+                } else if ( runMode.getArtifactGroups().size() > 1 ) {
+                    result.errorMessage = "Base run mode should only have a single start level.";
+                } else {
+                    org.apache.sling.provisioning.model.Artifact firstArtifact = null;
+                    for(final org.apache.sling.provisioning.model.Artifact a : runMode.getArtifactGroups().get(0)) {
+                        if ( firstArtifact == null ) {
+                            firstArtifact = a;
+                        } else {
+                            result.errorMessage = "Base run mode should contain exactly one artifact.";
+                            break;
+                        }
+                    }
+                    if ( firstArtifact == null ) {
+                        result.errorMessage = "No base artifacts defined.";
+                    }
+                    if ( result.errorMessage == null ) {
+                        result.artifact = firstArtifact;
+                    }
+                }
             }
         }
-        return firstArtifact;
+        return result;
+    }
+
+    public static File getSlingstartArtifact(final ArtifactHandlerManager artifactHandlerManager,
+            final ArtifactResolver resolver,
+            final MavenProject project,
+            final MavenSession session,
+            final Dependency d)
+    throws MavenExecutionException {
+        final Artifact prjArtifact = new DefaultArtifact(d.getGroupId(),
+                d.getArtifactId(),
+                VersionRange.createFromVersion(d.getVersion()),
+                Artifact.SCOPE_PROVIDED,
+                d.getType(),
+                d.getClassifier(),
+                artifactHandlerManager.getArtifactHandler(d.getType()));
+        try {
+            resolver.resolve(prjArtifact, project.getRemoteArtifactRepositories(), session.getLocalRepository());
+        } catch (final ArtifactResolutionException e) {
+            throw new MavenExecutionException("Unable to get artifact for " + d, e);
+        } catch (final ArtifactNotFoundException e) {
+            throw new MavenExecutionException("Unable to get artifact for " + d, e);
+        }
+        return prjArtifact.getFile();
     }
 
     /**
@@ -212,74 +265,120 @@ public abstract class ModelUtils {
     }
 
     private static final String RAW_MODEL_TXT = Model.class.getName() + "/raw.txt";
-    private static final String EFFECTIVE_MODEL_TXT = Model.class.getName() + "/effective.txt";
+    private static final String RAW_MODEL_DEPS = Model.class.getName() + "/raw.deps";
 
-    private static final String RAW_MODEL = Model.class.getName() + "/raw";
     private static final String EFFECTIVE_MODEL = Model.class.getName() + "/effective";
+    private static final String RAW_MODEL = Model.class.getName() + "/raw";
 
     /**
-     * Store the raw model in the project.
+     * Store the model info from the dependency lifecycle participant
      * @param project The maven project
-     * @param model The model
+     * @param model The local model
+     * @param dependencies The dependencies (either String or File objects)
      * @throws IOException If writing fails
      */
-    public static void storeRawModel(final MavenProject project, final Model model)
+    public static void storeModelInfo(final MavenProject project, final Model model, final List<Object> dependencies)
     throws IOException {
+        // we have to serialize as the dependency lifecycle participant uses a different class loader (!)
         final StringWriter w = new StringWriter();
         ModelWriter.write(w, model);
         project.setContextValue(RAW_MODEL_TXT, w.toString());
+        project.setContextValue(RAW_MODEL_DEPS, dependencies);
     }
 
-    /**
-     * Get the raw model from the project
-     * @param project The maven projet
-     * @return The raw model
-     * @throws MojoExecutionException If reading fails
-     */
-    public static Model getRawModel(final MavenProject project) throws MojoExecutionException {
-        Model result = (Model)project.getContextValue(RAW_MODEL);
-        if ( result == null ) {
-            final String contents = (String)project.getContextValue(RAW_MODEL_TXT);
+    public static void prepareModel(final MavenProject project,
+            final MavenSession session,
+            final ArtifactHandlerManager artifactHandlerManager,
+            final ArtifactResolver resolver)
+    throws MojoExecutionException {
+        final String contents = (String)project.getContextValue(RAW_MODEL_TXT);
+        final Model localModel;
+        try {
+            localModel = ModelReader.read(new StringReader(contents), null);
+        } catch ( final IOException ioe) {
+            throw new MojoExecutionException("Unable to read cached model.", ioe);
+        }
+        final List<File> modelDependencies = new ArrayList<File>();
+        @SuppressWarnings("unchecked")
+        final List<Object> localDeps = (List<Object>)project.getContextValue(RAW_MODEL_DEPS);
+        for(final Object o : localDeps) {
+            if ( o instanceof String ) {
+                final String[] info = ((String)o).split(":");
+                final Dependency dep = new Dependency();
+                dep.setGroupId(info[0]);
+                dep.setArtifactId(info[1]);
+                dep.setVersion(info[2]);
+                if ( info[3] != null && info[3].length() > 0 ) {
+                    dep.setClassifier(info[3]);
+                }
+                if ( info[4] != null && info[4].length() > 0 ) {
+                    dep.setType(info[4]);
+                }
+                try {
+                    modelDependencies.add(getSlingstartArtifact(artifactHandlerManager, resolver, project, session, dep));
+                } catch ( final MavenExecutionException mee) {
+                    throw new MojoExecutionException(mee.getMessage(), mee.getCause());
+                }
+            } else {
+                modelDependencies.add((File)o);
+            }
+        }
+        // read dependent models
+        Model depModel = null;
+        for(final File file : modelDependencies) {
+            FileReader r = null;
             try {
-                result = ModelReader.read(new StringReader(contents), null);
-                project.setContextValue(RAW_MODEL, result);
+                r = new FileReader(file);
+                if ( depModel == null ) {
+                    depModel = new Model();
+                }
+                final Model readModel = ModelReader.read(r, file.getAbsolutePath());
+                final Map<Traceable, String> errors = ModelUtility.validate(readModel);
+                if (errors != null ) {
+                    throw new MojoExecutionException("Invalid model at " + file + " : " + errors);
+                }
+                ModelUtility.merge(depModel, readModel);
             } catch ( final IOException ioe) {
-                throw new MojoExecutionException("Unable to read cached model.", ioe);
+                throw new MojoExecutionException("Unable to read model from " + file, ioe);
+            } finally {
+                IOUtils.closeQuietly(r);
             }
         }
-        return result;
+
+        final Model rawModel;
+        if ( depModel != null ) {
+            ModelUtility.merge(depModel, localModel);
+            final Map<Traceable, String> errors = ModelUtility.validate(depModel);
+            if (errors != null ) {
+                throw new MojoExecutionException("Invalid model : " + errors);
+            }
+            rawModel = depModel;
+        } else {
+            rawModel = localModel;
+        }
+
+        // store raw model
+        project.setContextValue(RAW_MODEL, rawModel);
+        // create and store effective model
+        final Model effectiveModel = ModelUtility.getEffectiveModel(rawModel, null);
+        project.setContextValue(EFFECTIVE_MODEL, effectiveModel);
     }
 
     /**
-     * Store the effective model in the project.
-     * @param project The maven project
-     * @param model The model
-     * @throws IOException If writing fails
+     * Get the effective model from the project
+     * @param project The maven projet
+     * @return The effective model
      */
-    public static void storeEffectiveModel(final MavenProject project, final Model model)
-    throws IOException {
-        final StringWriter w = new StringWriter();
-        ModelWriter.write(w, model);
-        project.setContextValue(EFFECTIVE_MODEL_TXT, w.toString());
+    public static Model getEffectiveModel(final MavenProject project) {
+        return (Model)project.getContextValue(EFFECTIVE_MODEL);
     }
 
     /**
-     * Get the effective model from the project
+     * Get the raw model from the project
      * @param project The maven projet
      * @return The raw model
-     * @throws MojoExecutionException If reading fails
      */
-    public static Model getEffectiveModel(final MavenProject project) throws MojoExecutionException {
-        Model result = (Model)project.getContextValue(EFFECTIVE_MODEL);
-        if ( result == null ) {
-            final String contents = (String)project.getContextValue(EFFECTIVE_MODEL_TXT);
-            try {
-                result = ModelUtility.getEffectiveModel(ModelReader.read(new StringReader(contents), null), null);
-                project.setContextValue(EFFECTIVE_MODEL, result);
-            } catch ( final IOException ioe) {
-                throw new MojoExecutionException("Unable to read cached model.", ioe);
-            }
-        }
-        return result;
+    public static Model getRawModel(final MavenProject project) {
+        return (Model)project.getContextValue(RAW_MODEL);
     }
 }

Modified: sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/PreparePackageMojo.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/PreparePackageMojo.java?rev=1672590&r1=1672589&r2=1672590&view=diff
==============================================================================
--- sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/PreparePackageMojo.java (original)
+++ sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/PreparePackageMojo.java Fri Apr 10 09:17:14 2015
@@ -323,7 +323,11 @@ public class PreparePackageMojo extends
      * Return the base artifact
      */
     private Artifact getBaseArtifact(final Model model, final String classifier, final String type) throws MojoExecutionException {
-        final org.apache.sling.provisioning.model.Artifact baseArtifact = ModelUtils.getBaseArtifact(model);
+        final ModelUtils.SearchResult result = ModelUtils.findBaseArtifact(model);
+        if ( result.errorMessage != null ) {
+            throw new MojoExecutionException(result.errorMessage);
+        }
+        final org.apache.sling.provisioning.model.Artifact baseArtifact = result.artifact;
 
         final Artifact a = ModelUtils.getArtifact(this.project,  this.mavenSession, this.artifactHandlerManager, this.resolver,
                 baseArtifact.getGroupId(),

Added: sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/PrepareSlingStartMojo.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/PrepareSlingStartMojo.java?rev=1672590&view=auto
==============================================================================
--- sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/PrepareSlingStartMojo.java (added)
+++ sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/PrepareSlingStartMojo.java Fri Apr 10 09:17:14 2015
@@ -0,0 +1,81 @@
+/*
+ * 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.sling.maven.slingstart;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+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.ResolutionScope;
+
+/**
+ * Prepares the project
+ *
+ */
+@Mojo(
+        name = "prepare",
+        defaultPhase = LifecyclePhase.VALIDATE,
+        requiresDependencyResolution = ResolutionScope.TEST,
+        threadSafe = true
+    )
+public class PrepareSlingStartMojo extends AbstractSlingStartMojo {
+
+    @Component
+    private ArtifactHandlerManager artifactHandlerManager;
+
+    /**
+     * Used to look up Artifacts in the remote repository.
+     *
+     */
+    @Component
+    private ArtifactResolver resolver;
+
+    @Override
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        ModelUtils.prepareModel(this.project, this.mavenSession, this.artifactHandlerManager, this.resolver);
+
+        if ( project.getPackaging().equals(BuildConstants.PACKAGING_SLINGSTART ) ) {
+            // add dependencies for base artifact
+            final ModelUtils.SearchResult result = ModelUtils.findBaseArtifact(ModelUtils.getEffectiveModel(project));
+            if ( result.artifact != null ) {
+                final String[] classifiers = new String[] {null, BuildConstants.CLASSIFIER_APP, BuildConstants.CLASSIFIER_WEBAPP};
+                for(final String c : classifiers) {
+                    final Dependency dep = new Dependency();
+                    dep.setGroupId(result.artifact.getGroupId());
+                    dep.setArtifactId(result.artifact.getArtifactId());
+                    dep.setVersion(result.artifact.getVersion());
+                    dep.setType(result.artifact.getType());
+                    dep.setClassifier(c);
+                    if ( BuildConstants.CLASSIFIER_WEBAPP.equals(c) ) {
+                        dep.setType(BuildConstants.TYPE_WAR);
+                    }
+                    dep.setScope(Artifact.SCOPE_PROVIDED);
+
+                    getLog().debug("Adding base dependency " + dep);
+                    project.getDependencies().add(dep);
+                }
+            } else {
+                throw new MojoExecutionException(result.errorMessage);
+            }
+        }
+    }
+}

Propchange: sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/PrepareSlingStartMojo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/PrepareSlingStartMojo.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Modified: sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/resources/META-INF/plexus/components.xml
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/resources/META-INF/plexus/components.xml?rev=1672590&r1=1672589&r2=1672590&view=diff
==============================================================================
--- sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/resources/META-INF/plexus/components.xml (original)
+++ sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/resources/META-INF/plexus/components.xml Fri Apr 10 09:17:14 2015
@@ -26,13 +26,12 @@
         <lifecycles>
           <lifecycle>
             <id>default</id>
-            <!-- START SNIPPET: bundle-lifecycle -->
             <phases>
+              <validate>org.apache.sling:slingstart-maven-plugin:prepare</validate>
               <package>org.apache.sling:slingstart-maven-plugin:attach-slingfeature</package>
               <install>org.apache.maven.plugins:maven-install-plugin:install</install>
               <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
             </phases>
-            <!-- END SNIPPET: bundle-lifecycle -->
           </lifecycle>
         </lifecycles>
       </configuration>
@@ -45,8 +44,8 @@
         <lifecycles>
           <lifecycle>
             <id>default</id>
-            <!-- START SNIPPET: bundle-lifecycle -->
             <phases>
+              <validate>org.apache.sling:slingstart-maven-plugin:prepare</validate>
               <process-resources>org.apache.maven.plugins:maven-resources-plugin:resources</process-resources>
               <compile>org.apache.maven.plugins:maven-compiler-plugin:compile</compile>
               <process-test-resources>
@@ -62,7 +61,6 @@
               <install>org.apache.maven.plugins:maven-install-plugin:install</install>
               <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
             </phases>
-            <!-- END SNIPPET: bundle-lifecycle -->
           </lifecycle>
         </lifecycles>
       </configuration>