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/10/19 12:29:13 UTC
svn commit: r1709384 - in
/sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart:
DependencyLifecycleParticipant.java ModelPreprocessor.java ProjectHelper.java
Author: cziegeler
Date: Mon Oct 19 10:29:12 2015
New Revision: 1709384
URL: http://svn.apache.org/viewvc?rev=1709384&view=rev
Log:
SLING-5170 : Make dependency handling code more reusable
Added:
sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/ModelPreprocessor.java (with props)
Modified:
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/ProjectHelper.java
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=1709384&r1=1709383&r2=1709384&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 Mon Oct 19 10:29:12 2015
@@ -16,44 +16,18 @@
*/
package org.apache.sling.maven.slingstart;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.io.IOUtils;
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;
import org.apache.maven.project.MavenProject;
-import org.apache.sling.provisioning.model.ArtifactGroup;
-import org.apache.sling.provisioning.model.Feature;
-import org.apache.sling.provisioning.model.Model;
-import org.apache.sling.provisioning.model.ModelConstants;
-import org.apache.sling.provisioning.model.ModelUtility;
-import org.apache.sling.provisioning.model.ModelUtility.ResolverOptions;
-import org.apache.sling.provisioning.model.RunMode;
-import org.apache.sling.provisioning.model.Traceable;
-import org.apache.sling.provisioning.model.io.ModelReader;
+import org.apache.sling.maven.slingstart.ModelPreprocessor.Environment;
+import org.apache.sling.maven.slingstart.ModelPreprocessor.ProjectInfo;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;
-import org.codehaus.plexus.util.xml.Xpp3Dom;
/**
* Maven lifecycle participant which adds the artifacts of the model to the dependencies.
@@ -76,25 +50,6 @@ public class DependencyLifecycleParticip
@Requirement
private ArtifactResolver resolver;
- public static final class ProjectInfo {
-
- public MavenProject project;
- public Plugin plugin;
- public Model localModel;
- public boolean done = false;
- public Model model;
- public final Map<org.apache.sling.provisioning.model.Artifact, Model> includedModels = new HashMap<org.apache.sling.provisioning.model.Artifact, Model>();
-
- }
-
- public static final class Environment {
- public ArtifactHandlerManager artifactHandlerManager;
- public ArtifactResolver resolver;
- public MavenSession session;
- public Logger logger;
- public final Map<String, ProjectInfo> modelProjects = new HashMap<String, ProjectInfo>();
- }
-
@Override
public void afterProjectsRead(final MavenSession session) throws MavenExecutionException {
final Environment env = new Environment();
@@ -122,379 +77,6 @@ public class DependencyLifecycleParticip
}
}
- addDependencies(env);
- }
-
- public static void addDependencies(final Environment env) throws MavenExecutionException {
- for(final ProjectInfo info : env.modelProjects.values()) {
- addDependencies(env, info);
- }
- }
-
- private static Model addDependencies(final Environment env, final ProjectInfo info)
- throws MavenExecutionException {
- if ( info.done == true ) {
- env.logger.debug("Return prepared model for " + info.project);
- return info.model;
- }
- // prevent recursion and multiple processing
- info.done = true;
- env.logger.debug("Processing project " + info.project);
-
- // read local model
- final String directory = nodeValue(info.plugin,
- "modelDirectory",
- new File(info.project.getBasedir(), "src/main/provisioning").getAbsolutePath());
- final String inlinedModel = nodeValue(info.plugin,
- "model", null);
- try {
- info.localModel = readLocalModel(info.project, inlinedModel, new File(directory), env.logger);
- } catch ( final IOException ioe) {
- throw new MavenExecutionException(ioe.getMessage(), ioe);
- }
-
- // prepare resolver options
- ResolverOptions resolverOptions = new ResolverOptions();
- if (nodeBooleanValue(info.plugin, "usePomVariables", false)) {
- resolverOptions.variableResolver(new PomVariableResolver(info.project));
- }
- if (nodeBooleanValue(info.plugin, "usePomDependencies", false)) {
- resolverOptions.artifactVersionResolver(new PomArtifactVersionResolver(info.project,
- nodeBooleanValue(info.plugin, "allowUnresolvedPomDependencies", false)));
- }
-
- // we have to create an effective model to add the dependencies
- final Model effectiveModel = ModelUtility.getEffectiveModel(info.localModel, resolverOptions);
-
- final List<Model> dependencies = searchSlingstartDependencies(env, info, info.localModel, effectiveModel);
- info.model = new Model();
- for(final Model d : dependencies) {
- ModelUtility.merge(info.model, d);
- }
- ModelUtility.merge(info.model, info.localModel);
- info.localModel = info.model;
- info.model = ModelUtility.getEffectiveModel(info.model, resolverOptions);
-
- final Map<Traceable, String> errors = ModelUtility.validate(info.model);
- if ( errors != null ) {
- throw new MavenExecutionException("Unable to create model file for " + info.project + " : " + errors, (File)null);
- }
-
- addDependenciesFromModel(env, info);
-
- try {
- ProjectHelper.storeProjectInfo(info);
- } catch ( final IOException ioe) {
- throw new MavenExecutionException(ioe.getMessage(), ioe);
- }
- return info.model;
- }
-
- /**
- * Add all dependencies from the model
- * @param project The project
- * @param model The model
- * @param log The logger
- * @throws MavenExecutionException
- */
- private static void addDependenciesFromModel(
- final Environment env,
- final ProjectInfo info)
- throws MavenExecutionException {
- if ( info.project.getPackaging().equals(BuildConstants.PACKAGING_SLINGSTART ) ) {
- // add base artifact if defined in current model
- final org.apache.sling.provisioning.model.Artifact baseArtifact = ModelUtils.findBaseArtifact(info.model);
-
- final String[] classifiers = new String[] {null, BuildConstants.CLASSIFIER_APP, BuildConstants.CLASSIFIER_WEBAPP};
- for(final String c : classifiers) {
- final Dependency dep = new Dependency();
- dep.setGroupId(baseArtifact.getGroupId());
- dep.setArtifactId(baseArtifact.getArtifactId());
- dep.setVersion(baseArtifact.getVersion());
- dep.setType(baseArtifact.getType());
- dep.setClassifier(c);
- if ( BuildConstants.CLASSIFIER_WEBAPP.equals(c) ) {
- dep.setType(BuildConstants.TYPE_WAR);
- }
- dep.setScope(Artifact.SCOPE_PROVIDED);
-
- info.project.getDependencies().add(dep);
- env.logger.debug("- adding base dependency " + ModelUtils.toString(dep));
- }
- }
-
- for(final Feature feature : info.model.getFeatures()) {
- // skip launchpad feature
- if ( feature.getName().equals(ModelConstants.FEATURE_LAUNCHPAD) ) {
- continue;
- }
- for(final RunMode runMode : feature.getRunModes()) {
- for(final ArtifactGroup group : runMode.getArtifactGroups()) {
- for(final org.apache.sling.provisioning.model.Artifact a : group) {
- final Dependency dep = new Dependency();
- dep.setGroupId(a.getGroupId());
- dep.setArtifactId(a.getArtifactId());
- dep.setVersion(a.getVersion());
- dep.setType(a.getType());
- dep.setClassifier(a.getClassifier());
-
- dep.setScope(Artifact.SCOPE_PROVIDED);
-
- env.logger.debug("- adding dependency " + ModelUtils.toString(dep));
- info.project.getDependencies().add(dep);
- }
- }
- }
- }
- }
-
- /**
- * Search for dependent slingstart/slingfeature artifacts and remove them from the effective model.
- * @throws MavenExecutionException
- */
- private static List<Model> searchSlingstartDependencies(
- final Environment env,
- final ProjectInfo info,
- final Model rawModel,
- final Model effectiveModel)
- throws MavenExecutionException {
- // slingstart or slingfeature
- final List<Model> dependencies = new ArrayList<Model>();
-
- for(final Feature feature : effectiveModel.getFeatures()) {
- for(final RunMode runMode : feature.getRunModes()) {
- for(final ArtifactGroup group : runMode.getArtifactGroups()) {
- final List<org.apache.sling.provisioning.model.Artifact> removeList = new ArrayList<org.apache.sling.provisioning.model.Artifact>();
- for(final org.apache.sling.provisioning.model.Artifact a : group) {
- if ( a.getType().equals(BuildConstants.PACKAGING_SLINGSTART)
- || a.getType().equals(BuildConstants.PACKAGING_PARTIAL_SYSTEM)) {
-
- final Dependency dep = new Dependency();
- dep.setGroupId(a.getGroupId());
- dep.setArtifactId(a.getArtifactId());
- dep.setVersion(a.getVersion());
- dep.setType(BuildConstants.PACKAGING_PARTIAL_SYSTEM);
- if ( a.getType().equals(BuildConstants.PACKAGING_SLINGSTART) ) {
- dep.setClassifier(BuildConstants.PACKAGING_PARTIAL_SYSTEM);
- } else {
- dep.setClassifier(a.getClassifier());
- }
- dep.setScope(Artifact.SCOPE_PROVIDED);
-
- env.logger.debug("- adding dependency " + ModelUtils.toString(dep));
- info.project.getDependencies().add(dep);
-
- // if it's a project from the current reactor build, we can't resolve it right now
- final String key = a.getGroupId() + ":" + a.getArtifactId();
- final ProjectInfo depInfo = env.modelProjects.get(key);
- if ( depInfo != null ) {
- env.logger.debug("Found reactor " + a.getType() + " dependency : " + a);
- final Model model = addDependencies(env, depInfo);
- if ( model == null ) {
- throw new MavenExecutionException("Recursive model dependency list including project " + info.project, (File)null);
- }
- dependencies.add(model);
- info.includedModels.put(a, depInfo.localModel);
-
- } else {
- env.logger.debug("Found external " + a.getType() + " dependency: " + a);
-
- // "external" dependency, we can already resolve it
- final File modelFile = resolveSlingstartArtifact(env, info.project, dep);
- FileReader r = null;
- try {
- r = new FileReader(modelFile);
- final Model model = ModelReader.read(r, modelFile.getAbsolutePath());
-
- info.includedModels.put(a, model);
-
- final Map<Traceable, String> errors = ModelUtility.validate(model);
- if ( errors != null ) {
- throw new MavenExecutionException("Unable to read model file from " + modelFile + " : " + errors, modelFile);
- }
- final Model fullModel = processSlingstartDependencies(env, info, dep, model);
-
- dependencies.add(fullModel);
- } catch ( final IOException ioe) {
- throw new MavenExecutionException("Unable to read model file from " + modelFile, ioe);
- } finally {
- try {
- if ( r != null ) {
- r.close();
- }
- } catch ( final IOException io) {
- // ignore
- }
- }
- }
-
- removeList.add(a);
- }
- }
- for(final org.apache.sling.provisioning.model.Artifact r : removeList) {
- group.remove(r);
- final Feature localModelFeature = rawModel.getFeature(feature.getName());
- if ( localModelFeature != null ) {
- final RunMode localRunMode = localModelFeature.getRunMode(runMode.getNames());
- if ( localRunMode != null ) {
- final ArtifactGroup localAG = localRunMode.getArtifactGroup(group.getStartLevel());
- if ( localAG != null ) {
- localAG.remove(r);
- }
- }
- }
- }
- }
- }
- }
-
- return dependencies;
- }
-
- private static Model processSlingstartDependencies(final Environment env, final ProjectInfo info, final Dependency dep, final Model rawModel)
- throws MavenExecutionException {
- env.logger.debug("Processing dependency " + dep);
-
- // we have to create an effective model to add the dependencies
- final Model effectiveModel = ModelUtility.getEffectiveModel(rawModel, new ResolverOptions());
-
- final List<Model> dependencies = searchSlingstartDependencies(env, info, rawModel, effectiveModel);
- Model mergingModel = new Model();
- for(final Model d : dependencies) {
- ModelUtility.merge(mergingModel, d);
- }
- ModelUtility.merge(mergingModel, rawModel);
-
- final Map<Traceable, String> errors = ModelUtility.validate(ModelUtility.getEffectiveModel(mergingModel, new ResolverOptions()));
- if ( errors != null ) {
- throw new MavenExecutionException("Unable to create model file for " + dep + " : " + errors, (File)null);
- }
-
- return mergingModel;
- }
-
- /**
- * Gets plugins configuration from POM (string parameter).
- * @param plugin Plugin
- * @param name Configuration parameter.
- * @param defaultValue Default value that is returned if parameter is not set
- * @return Parameter value or default value.
- */
- private static String nodeValue(final Plugin plugin, final String name, final String defaultValue) {
- final Xpp3Dom config = plugin == null ? null : (Xpp3Dom)plugin.getConfiguration();
- final Xpp3Dom node = (config == null ? null : config.getChild(name));
- if (node != null) {
- return node.getValue();
- } else {
- return defaultValue;
- }
- }
-
- /**
- * Gets plugins configuration from POM (boolean parameter).
- * @param plugin Plugin
- * @param name Configuration parameter.
- * @param defaultValue Default value that is returned if parameter is not set
- * @return Parameter value or default value.
- */
- private static boolean nodeBooleanValue(final Plugin plugin, final String name, final boolean defaultValue) {
- String booleanValue = nodeValue(plugin, name, Boolean.toString(defaultValue));
- return "true".equals(booleanValue.toLowerCase());
- }
-
- private static File resolveSlingstartArtifact(final Environment env,
- final MavenProject project,
- 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(),
- env.artifactHandlerManager.getArtifactHandler(d.getType()));
- try {
- env.resolver.resolve(prjArtifact, project.getRemoteArtifactRepositories(), env.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();
- }
-
- /**
- * Read all model files from the directory in alphabetical order.
- * Only files ending with .txt or .model are read.
- *
- * @param project The current maven project
- * @param modelDirectory The directory to scan for models
- * @param logger The logger
- */
- private static Model readLocalModel(
- final MavenProject project,
- final String inlinedModel,
- final File modelDirectory,
- final Logger logger)
- throws MavenExecutionException, IOException {
- final List<String> candidates = new ArrayList<String>();
- if ( modelDirectory != null && modelDirectory.exists() ) {
- for(final File f : modelDirectory.listFiles() ) {
- if ( f.isFile() && !f.getName().startsWith(".") ) {
- if ( f.getName().endsWith(".txt") || f.getName().endsWith(".model") ) {
- candidates.add(f.getName());
- }
- }
- }
- Collections.sort(candidates);
- }
- if ( candidates.size() == 0 && (inlinedModel == null || inlinedModel.trim().length() == 0) ) {
- throw new MavenExecutionException("No model files found in " + modelDirectory + ", and no model inlined in POM.", (File)null);
- }
- final Model result = new Model();
- if ( inlinedModel != null ) {
- logger.debug("Reading inlined model from project " + project.getId());
- try {
- final Reader reader = new StringReader(inlinedModel);
- try {
- final Model current = ModelReader.read(reader, "pom");
- final Map<Traceable, String> errors = ModelUtility.validate(current);
- if (errors != null ) {
- throw new MavenExecutionException("Invalid inlined model : " + errors, (File)null);
- }
- ModelUtility.merge(result, current, false);
- } finally {
- IOUtils.closeQuietly(reader);
- }
- } catch ( final IOException io) {
- throw new MavenExecutionException("Unable to read inlined model", io);
- }
- }
- for(final String name : candidates) {
- logger.debug("Reading model " + name + " in project " + project.getId());
- try {
- final File f = new File(modelDirectory, name);
- final FileReader reader = new FileReader(f);
- try {
- final Model current = ModelReader.read(reader, f.getAbsolutePath());
- final Map<Traceable, String> errors = ModelUtility.validate(current);
- if (errors != null ) {
- throw new MavenExecutionException("Invalid model at " + name + " : " + errors, (File)null);
- }
- ModelUtility.merge(result, current, false);
- } finally {
- IOUtils.closeQuietly(reader);
- }
- } catch ( final IOException io) {
- throw new MavenExecutionException("Unable to read model at " + name, io);
- }
- }
-
- final Map<Traceable, String> errors = ModelUtility.validate(result);
- if (errors != null ) {
- throw new MavenExecutionException("Invalid assembled model : " + errors, (File)null);
- }
-
- return result;
+ new ModelPreprocessor().addDependencies(env);
}
}
Added: sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/ModelPreprocessor.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/ModelPreprocessor.java?rev=1709384&view=auto
==============================================================================
--- sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/ModelPreprocessor.java (added)
+++ sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/ModelPreprocessor.java Mon Oct 19 10:29:12 2015
@@ -0,0 +1,466 @@
+/*
+ * 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 java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+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;
+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;
+import org.apache.maven.project.MavenProject;
+import org.apache.sling.provisioning.model.ArtifactGroup;
+import org.apache.sling.provisioning.model.Feature;
+import org.apache.sling.provisioning.model.Model;
+import org.apache.sling.provisioning.model.ModelConstants;
+import org.apache.sling.provisioning.model.ModelUtility;
+import org.apache.sling.provisioning.model.ModelUtility.ResolverOptions;
+import org.apache.sling.provisioning.model.RunMode;
+import org.apache.sling.provisioning.model.Traceable;
+import org.apache.sling.provisioning.model.io.ModelReader;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+public class ModelPreprocessor {
+
+ public static final class ProjectInfo {
+
+ public MavenProject project;
+ public Plugin plugin;
+ public Model localModel;
+ public boolean done = false;
+ public Model model;
+ public final Map<org.apache.sling.provisioning.model.Artifact, Model> includedModels = new HashMap<org.apache.sling.provisioning.model.Artifact, Model>();
+
+ }
+
+ public static final class Environment {
+ public ArtifactHandlerManager artifactHandlerManager;
+ public ArtifactResolver resolver;
+ public MavenSession session;
+ public Logger logger;
+ public final Map<String, ProjectInfo> modelProjects = new HashMap<String, ProjectInfo>();
+ }
+
+ public void addDependencies(final Environment env) throws MavenExecutionException {
+ for(final ProjectInfo info : env.modelProjects.values()) {
+ addDependencies(env, info);
+ }
+ }
+
+ private Model addDependencies(final Environment env, final ProjectInfo info)
+ throws MavenExecutionException {
+ if ( info.done == true ) {
+ env.logger.debug("Return prepared model for " + info.project);
+ return info.model;
+ }
+ // prevent recursion and multiple processing
+ info.done = true;
+ env.logger.debug("Processing project " + info.project);
+
+ // read local model
+ final String directory = nodeValue(info.plugin,
+ "modelDirectory",
+ new File(info.project.getBasedir(), "src/main/provisioning").getAbsolutePath());
+ final String inlinedModel = nodeValue(info.plugin,
+ "model", null);
+ try {
+ info.localModel = readLocalModel(info.project, inlinedModel, new File(directory), env.logger);
+ } catch ( final IOException ioe) {
+ throw new MavenExecutionException(ioe.getMessage(), ioe);
+ }
+
+ // prepare resolver options
+ ResolverOptions resolverOptions = new ResolverOptions();
+ if (nodeBooleanValue(info.plugin, "usePomVariables", false)) {
+ resolverOptions.variableResolver(new PomVariableResolver(info.project));
+ }
+ if (nodeBooleanValue(info.plugin, "usePomDependencies", false)) {
+ resolverOptions.artifactVersionResolver(new PomArtifactVersionResolver(info.project,
+ nodeBooleanValue(info.plugin, "allowUnresolvedPomDependencies", false)));
+ }
+
+ // we have to create an effective model to add the dependencies
+ final Model effectiveModel = ModelUtility.getEffectiveModel(info.localModel, resolverOptions);
+
+ final List<Model> dependencies = searchSlingstartDependencies(env, info, info.localModel, effectiveModel);
+ info.model = new Model();
+ for(final Model d : dependencies) {
+ this.mergeModels(info.model, d);
+ }
+ this.mergeModels(info.model, info.localModel);
+ info.localModel = info.model;
+ info.model = ModelUtility.getEffectiveModel(info.model, resolverOptions);
+
+ final Map<Traceable, String> errors = ModelUtility.validate(info.model);
+ if ( errors != null ) {
+ throw new MavenExecutionException("Unable to create model file for " + info.project + " : " + errors, (File)null);
+ }
+
+ addDependenciesFromModel(env, info);
+
+ try {
+ ProjectHelper.storeProjectInfo(info);
+ } catch ( final IOException ioe) {
+ throw new MavenExecutionException(ioe.getMessage(), ioe);
+ }
+ return info.model;
+ }
+
+ /**
+ * Add all dependencies from the model
+ * @param project The project
+ * @param model The model
+ * @param log The logger
+ * @throws MavenExecutionException
+ */
+ private void addDependenciesFromModel(
+ final Environment env,
+ final ProjectInfo info)
+ throws MavenExecutionException {
+ if ( info.project.getPackaging().equals(BuildConstants.PACKAGING_SLINGSTART ) ) {
+ // add base artifact if defined in current model
+ final org.apache.sling.provisioning.model.Artifact baseArtifact = ModelUtils.findBaseArtifact(info.model);
+
+ final String[] classifiers = new String[] {null, BuildConstants.CLASSIFIER_APP, BuildConstants.CLASSIFIER_WEBAPP};
+ for(final String c : classifiers) {
+ final Dependency dep = new Dependency();
+ dep.setGroupId(baseArtifact.getGroupId());
+ dep.setArtifactId(baseArtifact.getArtifactId());
+ dep.setVersion(baseArtifact.getVersion());
+ dep.setType(baseArtifact.getType());
+ dep.setClassifier(c);
+ if ( BuildConstants.CLASSIFIER_WEBAPP.equals(c) ) {
+ dep.setType(BuildConstants.TYPE_WAR);
+ }
+ dep.setScope(Artifact.SCOPE_PROVIDED);
+
+ info.project.getDependencies().add(dep);
+ env.logger.debug("- adding base dependency " + ModelUtils.toString(dep));
+ }
+ }
+
+ for(final Feature feature : info.model.getFeatures()) {
+ // skip launchpad feature
+ if ( feature.getName().equals(ModelConstants.FEATURE_LAUNCHPAD) ) {
+ continue;
+ }
+ for(final RunMode runMode : feature.getRunModes()) {
+ for(final ArtifactGroup group : runMode.getArtifactGroups()) {
+ for(final org.apache.sling.provisioning.model.Artifact a : group) {
+ final Dependency dep = new Dependency();
+ dep.setGroupId(a.getGroupId());
+ dep.setArtifactId(a.getArtifactId());
+ dep.setVersion(a.getVersion());
+ dep.setType(a.getType());
+ dep.setClassifier(a.getClassifier());
+
+ dep.setScope(Artifact.SCOPE_PROVIDED);
+
+ env.logger.debug("- adding dependency " + ModelUtils.toString(dep));
+ info.project.getDependencies().add(dep);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Search for dependent slingstart/slingfeature artifacts and remove them from the effective model.
+ * @throws MavenExecutionException
+ */
+ private List<Model> searchSlingstartDependencies(
+ final Environment env,
+ final ProjectInfo info,
+ final Model rawModel,
+ final Model effectiveModel)
+ throws MavenExecutionException {
+ // slingstart or slingfeature
+ final List<Model> dependencies = new ArrayList<Model>();
+
+ for(final Feature feature : effectiveModel.getFeatures()) {
+ for(final RunMode runMode : feature.getRunModes()) {
+ for(final ArtifactGroup group : runMode.getArtifactGroups()) {
+ final List<org.apache.sling.provisioning.model.Artifact> removeList = new ArrayList<org.apache.sling.provisioning.model.Artifact>();
+ for(final org.apache.sling.provisioning.model.Artifact a : group) {
+ if ( a.getType().equals(BuildConstants.PACKAGING_SLINGSTART)
+ || a.getType().equals(BuildConstants.PACKAGING_PARTIAL_SYSTEM)) {
+
+ final Dependency dep = new Dependency();
+ dep.setGroupId(a.getGroupId());
+ dep.setArtifactId(a.getArtifactId());
+ dep.setVersion(a.getVersion());
+ dep.setType(BuildConstants.PACKAGING_PARTIAL_SYSTEM);
+ if ( a.getType().equals(BuildConstants.PACKAGING_SLINGSTART) ) {
+ dep.setClassifier(BuildConstants.PACKAGING_PARTIAL_SYSTEM);
+ } else {
+ dep.setClassifier(a.getClassifier());
+ }
+ dep.setScope(Artifact.SCOPE_PROVIDED);
+
+ env.logger.debug("- adding dependency " + ModelUtils.toString(dep));
+ info.project.getDependencies().add(dep);
+
+ // if it's a project from the current reactor build, we can't resolve it right now
+ final String key = a.getGroupId() + ":" + a.getArtifactId();
+ final ProjectInfo depInfo = env.modelProjects.get(key);
+ if ( depInfo != null ) {
+ env.logger.debug("Found reactor " + a.getType() + " dependency : " + a);
+ final Model model = addDependencies(env, depInfo);
+ if ( model == null ) {
+ throw new MavenExecutionException("Recursive model dependency list including project " + info.project, (File)null);
+ }
+ dependencies.add(model);
+ info.includedModels.put(a, depInfo.localModel);
+
+ } else {
+ env.logger.debug("Found external " + a.getType() + " dependency: " + a);
+
+ // "external" dependency, we can already resolve it
+ final File modelFile = resolveSlingstartArtifact(env, info.project, dep);
+ FileReader r = null;
+ try {
+ r = new FileReader(modelFile);
+ final Model model = ModelReader.read(r, modelFile.getAbsolutePath());
+
+ info.includedModels.put(a, model);
+
+ final Map<Traceable, String> errors = ModelUtility.validate(model);
+ if ( errors != null ) {
+ throw new MavenExecutionException("Unable to read model file from " + modelFile + " : " + errors, modelFile);
+ }
+ final Model fullModel = processSlingstartDependencies(env, info, dep, model);
+
+ dependencies.add(fullModel);
+ } catch ( final IOException ioe) {
+ throw new MavenExecutionException("Unable to read model file from " + modelFile, ioe);
+ } finally {
+ try {
+ if ( r != null ) {
+ r.close();
+ }
+ } catch ( final IOException io) {
+ // ignore
+ }
+ }
+ }
+
+ removeList.add(a);
+ }
+ }
+ for(final org.apache.sling.provisioning.model.Artifact r : removeList) {
+ group.remove(r);
+ final Feature localModelFeature = rawModel.getFeature(feature.getName());
+ if ( localModelFeature != null ) {
+ final RunMode localRunMode = localModelFeature.getRunMode(runMode.getNames());
+ if ( localRunMode != null ) {
+ final ArtifactGroup localAG = localRunMode.getArtifactGroup(group.getStartLevel());
+ if ( localAG != null ) {
+ localAG.remove(r);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return dependencies;
+ }
+
+ private Model processSlingstartDependencies(final Environment env, final ProjectInfo info, final Dependency dep, final Model rawModel)
+ throws MavenExecutionException {
+ env.logger.debug("Processing dependency " + dep);
+
+ // we have to create an effective model to add the dependencies
+ final Model effectiveModel = ModelUtility.getEffectiveModel(rawModel, new ResolverOptions());
+
+ final List<Model> dependencies = searchSlingstartDependencies(env, info, rawModel, effectiveModel);
+ Model mergingModel = new Model();
+ for(final Model d : dependencies) {
+ this.mergeModels(mergingModel, d);
+ }
+ this.mergeModels(mergingModel, rawModel);
+
+ final Map<Traceable, String> errors = ModelUtility.validate(ModelUtility.getEffectiveModel(mergingModel, new ResolverOptions()));
+ if ( errors != null ) {
+ throw new MavenExecutionException("Unable to create model file for " + dep + " : " + errors, (File)null);
+ }
+
+ return mergingModel;
+ }
+
+ /**
+ * Gets plugins configuration from POM (string parameter).
+ * @param plugin Plugin
+ * @param name Configuration parameter.
+ * @param defaultValue Default value that is returned if parameter is not set
+ * @return Parameter value or default value.
+ */
+ private String nodeValue(final Plugin plugin, final String name, final String defaultValue) {
+ final Xpp3Dom config = plugin == null ? null : (Xpp3Dom)plugin.getConfiguration();
+ final Xpp3Dom node = (config == null ? null : config.getChild(name));
+ if (node != null) {
+ return node.getValue();
+ } else {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Gets plugins configuration from POM (boolean parameter).
+ * @param plugin Plugin
+ * @param name Configuration parameter.
+ * @param defaultValue Default value that is returned if parameter is not set
+ * @return Parameter value or default value.
+ */
+ private boolean nodeBooleanValue(final Plugin plugin, final String name, final boolean defaultValue) {
+ String booleanValue = nodeValue(plugin, name, Boolean.toString(defaultValue));
+ return "true".equals(booleanValue.toLowerCase());
+ }
+
+ private File resolveSlingstartArtifact(final Environment env,
+ final MavenProject project,
+ 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(),
+ env.artifactHandlerManager.getArtifactHandler(d.getType()));
+ try {
+ env.resolver.resolve(prjArtifact, project.getRemoteArtifactRepositories(), env.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();
+ }
+
+ /**
+ * Read all model files from the directory in alphabetical order.
+ * Only files ending with .txt or .model are read.
+ *
+ * @param project The current maven project
+ * @param modelDirectory The directory to scan for models
+ * @param logger The logger
+ */
+ protected Model readLocalModel(
+ final MavenProject project,
+ final String inlinedModel,
+ final File modelDirectory,
+ final Logger logger)
+ throws MavenExecutionException, IOException {
+ final List<String> candidates = new ArrayList<String>();
+ if ( modelDirectory != null && modelDirectory.exists() ) {
+ for(final File f : modelDirectory.listFiles() ) {
+ if ( f.isFile() && !f.getName().startsWith(".") ) {
+ if ( f.getName().endsWith(".txt") || f.getName().endsWith(".model") ) {
+ candidates.add(f.getName());
+ }
+ }
+ }
+ Collections.sort(candidates);
+ }
+ if ( candidates.size() == 0 && (inlinedModel == null || inlinedModel.trim().length() == 0) ) {
+ throw new MavenExecutionException("No model files found in " + modelDirectory + ", and no model inlined in POM.", (File)null);
+ }
+ final Model result = new Model();
+ if ( inlinedModel != null ) {
+ logger.debug("Reading inlined model from project " + project.getId());
+ try {
+ final Reader reader = new StringReader(inlinedModel);
+ try {
+ final Model current = ModelReader.read(reader, "pom");
+ final Map<Traceable, String> errors = ModelUtility.validate(current);
+ if (errors != null ) {
+ throw new MavenExecutionException("Invalid inlined model : " + errors, (File)null);
+ }
+ ModelUtility.merge(result, current, false);
+ } finally {
+ IOUtils.closeQuietly(reader);
+ }
+ } catch ( final IOException io) {
+ throw new MavenExecutionException("Unable to read inlined model", io);
+ }
+ }
+ for(final String name : candidates) {
+ logger.debug("Reading model " + name + " in project " + project.getId());
+ try {
+ final File f = new File(modelDirectory, name);
+ final FileReader reader = new FileReader(f);
+ try {
+ final Model current = ModelReader.read(reader, f.getAbsolutePath());
+ final Map<Traceable, String> errors = ModelUtility.validate(current);
+ if (errors != null ) {
+ throw new MavenExecutionException("Invalid model at " + name + " : " + errors, (File)null);
+ }
+ ModelUtility.merge(result, current, false);
+ } finally {
+ IOUtils.closeQuietly(reader);
+ }
+ } catch ( final IOException io) {
+ throw new MavenExecutionException("Unable to read model at " + name, io);
+ }
+ }
+
+ final Map<Traceable, String> errors = ModelUtility.validate(result);
+ if (errors != null ) {
+ throw new MavenExecutionException("Invalid assembled model : " + errors, (File)null);
+ }
+
+ return postProcessReadModel(result);
+ }
+
+ /**
+ * Hook to post process the local model
+ * @param result The read model
+ * @return The post processed model
+ */
+ protected Model postProcessReadModel(final Model result) throws MavenExecutionException {
+ return result;
+ }
+
+ /**
+ * Hook to change the merge behavior
+ * @param base The base model
+ * @param additional The additional model
+ */
+ protected void mergeModels(final Model base, final Model additional) throws MavenExecutionException {
+ ModelUtility.merge(base, additional);
+ }
+}
Propchange: sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/ModelPreprocessor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/ModelPreprocessor.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Modified: sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/ProjectHelper.java
URL: http://svn.apache.org/viewvc/sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/ProjectHelper.java?rev=1709384&r1=1709383&r2=1709384&view=diff
==============================================================================
--- sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/ProjectHelper.java (original)
+++ sling/trunk/tooling/maven/slingstart-maven-plugin/src/main/java/org/apache/sling/maven/slingstart/ProjectHelper.java Mon Oct 19 10:29:12 2015
@@ -48,7 +48,7 @@ public abstract class ProjectHelper {
* @param info The project info
* @throws IOException If writing fails
*/
- public static void storeProjectInfo(final DependencyLifecycleParticipant.ProjectInfo info)
+ public static void storeProjectInfo(final ModelPreprocessor.ProjectInfo info)
throws IOException {
// we have to serialize as the dependency lifecycle participant uses a different class loader (!)
final StringWriter w1 = new StringWriter();