diff options
author | Igor Fedorenko | 2011-09-27 17:21:28 +0000 |
---|---|---|
committer | Igor Fedorenko | 2011-09-27 17:40:57 +0000 |
commit | a4df8a450b55b7d5ff59a4c9b85b31377e5ea81e (patch) | |
tree | 4abe6cad83388afeb15c4d6839795d506821a3b5 /m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src | |
parent | ba788d32d0f30a5dd549b3f3504effe79dda5299 (diff) | |
download | m2e-core-a4df8a450b55b7d5ff59a4c9b85b31377e5ea81e.tar.gz m2e-core-a4df8a450b55b7d5ff59a4c9b85b31377e5ea81e.tar.xz m2e-core-a4df8a450b55b7d5ff59a4c9b85b31377e5ea81e.zip |
moved m2e-maven-runtime back to m2e-core source tree
Signed-off-by: Igor Fedorenko <igor@ifedorenko.com>
Diffstat (limited to 'm2e-maven-runtime/org.eclipse.m2e.maven.runtime/src')
13 files changed, 2864 insertions, 0 deletions
diff --git a/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/README b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/README new file mode 100644 index 00000000..4ef4415d --- /dev/null +++ b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/README @@ -0,0 +1,8 @@ +The following changes were cherry-picked + +maven-3.0.3 (SNAPSHOT) +MNG-4988 API to calculate execution plan without full mojo execution configuration +MNG-5003 populate mojo descriptor with cached plugin realm + +aether-1.12 +AETHER-92 TransferCancelledException must interrupt the current download. diff --git a/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java new file mode 100644 index 00000000..a719a0c7 --- /dev/null +++ b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java @@ -0,0 +1,178 @@ +package org.apache.maven.lifecycle; + +/* + * 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. + */ + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator; +import org.apache.maven.lifecycle.internal.LifecycleStarter; +import org.apache.maven.lifecycle.internal.LifecycleTaskSegmentCalculator; +import org.apache.maven.lifecycle.internal.MojoDescriptorCreator; +import org.apache.maven.lifecycle.internal.MojoExecutor; +import org.apache.maven.lifecycle.internal.ProjectIndex; +import org.apache.maven.lifecycle.internal.TaskSegment; +import org.apache.maven.model.Plugin; +import org.apache.maven.plugin.InvalidPluginDescriptorException; +import org.apache.maven.plugin.MojoExecution; +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.descriptor.MojoDescriptor; +import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; +import org.apache.maven.plugin.version.PluginVersionResolutionException; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * A facade that provides lifecycle services to components outside maven core. + * + * Note that this component is not normally used from within core itself. + * + * @author Jason van Zyl + * @author Benjamin Bentmann + * @author Kristian Rosenvold + */ +@Component( role = LifecycleExecutor.class ) +public class DefaultLifecycleExecutor + implements LifecycleExecutor +{ + + @Requirement + private LifeCyclePluginAnalyzer lifeCyclePluginAnalyzer; + + @Requirement + private DefaultLifecycles defaultLifeCycles; + + @Requirement + private LifecycleTaskSegmentCalculator lifecycleTaskSegmentCalculator; + + @Requirement + private LifecycleExecutionPlanCalculator lifecycleExecutionPlanCalculator; + + @Requirement + private MojoExecutor mojoExecutor; + + @Requirement + private LifecycleStarter lifecycleStarter; + + + public void execute( MavenSession session ) + { + lifecycleStarter.execute( session ); + } + + @Requirement + private MojoDescriptorCreator mojoDescriptorCreator; + + // These methods deal with construction intact Plugin object that look like they come from a standard + // <plugin/> block in a Maven POM. We have to do some wiggling to pull the sources of information + // together and this really shows the problem of constructing a sensible default configuration but + // it's all encapsulated here so it appears normalized to the POM builder. + + // We are going to take the project packaging and find all plugin in the default lifecycle and create + // fully populated Plugin objects, including executions with goals and default configuration taken + // from the plugin.xml inside a plugin. + // + // TODO: This whole method could probably removed by injecting lifeCyclePluginAnalyzer straight into client site. + // TODO: But for some reason the whole plexus appcontext refuses to start when I try this. + + public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging ) + { + return lifeCyclePluginAnalyzer.getPluginsBoundByDefaultToAllLifecycles( packaging ); + } + + // USED BY MAVEN HELP PLUGIN + + @SuppressWarnings( { "UnusedDeclaration" } ) + @Deprecated + public Map<String, Lifecycle> getPhaseToLifecycleMap() + { + return defaultLifeCycles.getPhaseToLifecycleMap(); + } + + // NOTE: Backward-compat with maven-help-plugin:2.1 + + @SuppressWarnings( { "UnusedDeclaration" } ) + MojoDescriptor getMojoDescriptor( String task, MavenSession session, MavenProject project, String invokedVia, + boolean canUsePrefix, boolean isOptionalMojo ) + throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, + MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, + PluginVersionResolutionException + { + return mojoDescriptorCreator.getMojoDescriptor( task, session, project ); + } + + // Used by m2eclipse + + @SuppressWarnings( { "UnusedDeclaration" } ) + public MavenExecutionPlan calculateExecutionPlan( MavenSession session, boolean setup, String... tasks ) + throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, + MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, + PluginManagerException, LifecyclePhaseNotFoundException, LifecycleNotFoundException, + PluginVersionResolutionException + { + List<TaskSegment> taskSegments = + lifecycleTaskSegmentCalculator.calculateTaskSegments( session, Arrays.asList( tasks ) ); + + TaskSegment mergedSegment = new TaskSegment( false ); + + for ( TaskSegment taskSegment : taskSegments ) + { + mergedSegment.getTasks().addAll( taskSegment.getTasks() ); + } + + return lifecycleExecutionPlanCalculator.calculateExecutionPlan( session, session.getCurrentProject(), + mergedSegment.getTasks(), setup ); + } + + public MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks ) + throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, + MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, + PluginManagerException, LifecyclePhaseNotFoundException, LifecycleNotFoundException, + PluginVersionResolutionException + { + return calculateExecutionPlan( session, true, tasks ); + } + + // Site 3.x + public void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session ) + throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException, + PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, + LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException + { + lifecycleExecutionPlanCalculator.calculateForkedExecutions( mojoExecution, session ); + } + + + // Site 3.x + public List<MavenProject> executeForkedExecutions( MojoExecution mojoExecution, MavenSession session ) + throws LifecycleExecutionException + { + return mojoExecutor.executeForkedExecutions( mojoExecution, session, new ProjectIndex( session.getProjects() ) ); + } + +} diff --git a/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/DefaultSchedules.java b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/DefaultSchedules.java new file mode 100644 index 00000000..4c1fe571 --- /dev/null +++ b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/DefaultSchedules.java @@ -0,0 +1,99 @@ +package org.apache.maven.lifecycle; + +/* + * 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. + */ + +import org.apache.maven.lifecycle.internal.BuilderCommon; +import org.apache.maven.lifecycle.internal.ExecutionPlanItem; +import org.apache.maven.plugin.MojoExecution; +import org.apache.maven.project.MavenProject; + +import java.util.ArrayList; +import java.util.List; + +/** + * Defines scheduling information needed by weave mode. + * + * @since 3.0 + * @author Kristian Rosenvold + */ +public class DefaultSchedules +{ + List<Scheduling> schedules; + + @SuppressWarnings( { "UnusedDeclaration" } ) + public DefaultSchedules() + { + } + + public DefaultSchedules( List<Scheduling> schedules ) + { + this.schedules = schedules; + } + + public List<ExecutionPlanItem> createExecutionPlanItem( MavenProject mavenProject, List<MojoExecution> executions ) + { + BuilderCommon.attachToThread( mavenProject ); + + List<ExecutionPlanItem> result = new ArrayList<ExecutionPlanItem>(); + for ( MojoExecution mojoExecution : executions ) + { + String lifeCyclePhase = mojoExecution.getLifecyclePhase(); + final Scheduling scheduling = getScheduling( "default" ); + Schedule schedule = null; + if ( scheduling != null ) + { + schedule = scheduling.getSchedule( mojoExecution ); + if ( schedule == null ) + { + schedule = scheduling.getSchedule( lifeCyclePhase ); + } + } + result.add( new ExecutionPlanItem( mojoExecution, schedule ) ); + + } + return result; + } + + /** + * Gets scheduling associated with a given phase. + * <p/> + * This is part of the experimental weave mode and therefore not part of the public api. + * + * @param lifecyclePhaseName The name of the lifecycle phase + * @return Schecduling information related to phase + */ + + Scheduling getScheduling( String lifecyclePhaseName ) + { + for ( Scheduling schedule : schedules ) + { + if ( lifecyclePhaseName.equals( schedule.getLifecycle() ) ) + { + return schedule; + } + } + return null; + } + + public List<Scheduling> getSchedules() + { + return schedules; + } +}
\ No newline at end of file diff --git a/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java new file mode 100644 index 00000000..37b6e499 --- /dev/null +++ b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java @@ -0,0 +1,94 @@ +package org.apache.maven.lifecycle; + +/* + * 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. + */ + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Plugin; +import org.apache.maven.plugin.InvalidPluginDescriptorException; +import org.apache.maven.plugin.MojoExecution; +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.project.MavenProject; + +import java.util.List; +import java.util.Set; + +/** + * A facade that provides lifecycle services to components outside maven core. + * + * + * @author Jason van Zyl + */ +@SuppressWarnings( { "UnusedDeclaration" } ) +public interface LifecycleExecutor +{ + + // USED BY MAVEN HELP PLUGIN + @Deprecated + String ROLE = LifecycleExecutor.class.getName(); + + // For a given project packaging find all the plugins that are bound to any registered + // lifecycles. The project builder needs to now what default plugin information needs to be + // merged into POM being built. Once the POM builder has this plugin information, versions can be assigned + // by the POM builder because they will have to be defined in plugin management. Once this is setComplete then it + // can be passed back so that the default configuraiton information can be populated. + // + // We need to know the specific version so that we can lookup the right version of the plugin descriptor + // which tells us what the default configuration is. + // + + /** + * @return The plugins bound to the lifecycles of the specified packaging or {@code null} if the packaging is + * unknown. + */ + Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging ); + + MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks ) + throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, + MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, + PluginManagerException, LifecyclePhaseNotFoundException, LifecycleNotFoundException, + PluginVersionResolutionException; + + MavenExecutionPlan calculateExecutionPlan( MavenSession session, boolean setup, String... tasks ) + throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, + MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, + PluginManagerException, LifecyclePhaseNotFoundException, LifecycleNotFoundException, + PluginVersionResolutionException; + + void execute( MavenSession session ); + + // used by the site plugin 3.x + void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session ) + throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException, + PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, + LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException; + + + // used by the site plugin 3.x + List<MavenProject> executeForkedExecutions( MojoExecution mojoExecution, MavenSession session ) + throws LifecycleExecutionException; + + +} diff --git a/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java new file mode 100644 index 00000000..b28e6c01 --- /dev/null +++ b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java @@ -0,0 +1,695 @@ +/* + * 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.maven.lifecycle.internal; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.lifecycle.DefaultLifecycles; +import org.apache.maven.lifecycle.DefaultSchedules; +import org.apache.maven.lifecycle.Lifecycle; +import org.apache.maven.lifecycle.LifecycleNotFoundException; +import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException; +import org.apache.maven.lifecycle.MavenExecutionPlan; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginExecution; +import org.apache.maven.plugin.BuildPluginManager; +import org.apache.maven.plugin.InvalidPluginDescriptorException; +import org.apache.maven.plugin.MojoExecution; +import org.apache.maven.plugin.MojoNotFoundException; +import org.apache.maven.plugin.PluginDescriptorParsingException; +import org.apache.maven.plugin.PluginNotFoundException; +import org.apache.maven.plugin.PluginResolutionException; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.Parameter; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.plugin.lifecycle.Execution; +import org.apache.maven.plugin.lifecycle.Phase; +import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; +import org.apache.maven.plugin.version.PluginVersionResolutionException; +import org.apache.maven.plugin.version.PluginVersionResolver; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; +import org.codehaus.plexus.util.StringUtils; +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +/** + * @since 3.0 + * @author Benjamin Bentmann + * @author Kristian Rosenvold (Extract class) + * <p/> + * NOTE: This class is not part of any public api and can be changed or deleted without prior notice. + */ +@Component( role = LifecycleExecutionPlanCalculator.class ) +public class DefaultLifecycleExecutionPlanCalculator + implements LifecycleExecutionPlanCalculator +{ + @Requirement + private PluginVersionResolver pluginVersionResolver; + + @Requirement + private BuildPluginManager pluginManager; + + @Requirement + private DefaultLifecycles defaultLifeCycles; + + @Requirement + private DefaultSchedules defaultSchedules; + + @Requirement + private MojoDescriptorCreator mojoDescriptorCreator; + + @Requirement + private LifecyclePluginResolver lifecyclePluginResolver; + + @SuppressWarnings( { "UnusedDeclaration" } ) + public DefaultLifecycleExecutionPlanCalculator() + { + } + + public DefaultLifecycleExecutionPlanCalculator( BuildPluginManager pluginManager, + DefaultLifecycles defaultLifeCycles, + MojoDescriptorCreator mojoDescriptorCreator, + LifecyclePluginResolver lifecyclePluginResolver, + DefaultSchedules defaultSchedules ) + { + this.pluginManager = pluginManager; + this.defaultLifeCycles = defaultLifeCycles; + this.mojoDescriptorCreator = mojoDescriptorCreator; + this.lifecyclePluginResolver = lifecyclePluginResolver; + this.defaultSchedules = defaultSchedules; + } + + public MavenExecutionPlan calculateExecutionPlan( MavenSession session, MavenProject project, List<Object> tasks, boolean setup ) + throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException, + PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException, + NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException + { + lifecyclePluginResolver.resolveMissingPluginVersions( project, session ); + + final List<MojoExecution> executions = calculateMojoExecutions( session, project, tasks ); + + if ( setup ) + { + setupMojoExecutions( session, project, executions ); + } + + final List<ExecutionPlanItem> planItem = defaultSchedules.createExecutionPlanItem( project, executions ); + + return new MavenExecutionPlan( planItem, defaultLifeCycles ); + } + + public MavenExecutionPlan calculateExecutionPlan( MavenSession session, MavenProject project, List<Object> tasks ) + throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException, + PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException, + NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException + { + return calculateExecutionPlan( session, project, tasks, true ); + } + + private void setupMojoExecutions( MavenSession session, MavenProject project, List<MojoExecution> mojoExecutions ) + throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, + MojoNotFoundException, InvalidPluginDescriptorException, NoPluginFoundForPrefixException, + LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException + { + for ( MojoExecution mojoExecution : mojoExecutions ) + { + setupMojoExecution( session, project, mojoExecution ); + } + } + + public void setupMojoExecution( MavenSession session, MavenProject project, MojoExecution mojoExecution ) + throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, + MojoNotFoundException, InvalidPluginDescriptorException, NoPluginFoundForPrefixException, + LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException + { + MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); + + if ( mojoDescriptor == null ) + { + mojoDescriptor = + pluginManager.getMojoDescriptor( mojoExecution.getPlugin(), mojoExecution.getGoal(), + project.getRemotePluginRepositories(), + session.getRepositorySession() ); + + mojoExecution.setMojoDescriptor( mojoDescriptor ); + } + + populateMojoExecutionConfiguration( project, mojoExecution, + MojoExecution.Source.CLI.equals( mojoExecution.getSource() ) ); + + finalizeMojoConfiguration( mojoExecution ); + + calculateForkedExecutions( mojoExecution, session, project, new HashSet<MojoDescriptor>() ); + } + + public List<MojoExecution> calculateMojoExecutions( MavenSession session, MavenProject project, + List<Object> tasks ) + throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, + MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, + PluginVersionResolutionException, LifecyclePhaseNotFoundException + { + final List<MojoExecution> mojoExecutions = new ArrayList<MojoExecution>(); + + for ( Object task : tasks ) + { + if ( task instanceof GoalTask ) + { + String pluginGoal = ( (GoalTask) task ).pluginGoal; + + MojoDescriptor mojoDescriptor = mojoDescriptorCreator.getMojoDescriptor( pluginGoal, session, project ); + + MojoExecution mojoExecution = + new MojoExecution( mojoDescriptor, "default-cli", MojoExecution.Source.CLI ); + + mojoExecutions.add( mojoExecution ); + } + else if ( task instanceof LifecycleTask ) + { + String lifecyclePhase = ( (LifecycleTask) task ).getLifecyclePhase(); + + Map<String, List<MojoExecution>> phaseToMojoMapping = + calculateLifecycleMappings( session, project, lifecyclePhase ); + + for ( List<MojoExecution> mojoExecutionsFromLifecycle : phaseToMojoMapping.values() ) + { + mojoExecutions.addAll( mojoExecutionsFromLifecycle ); + } + } + else + { + throw new IllegalStateException( "unexpected task " + task ); + } + } + return mojoExecutions; + } + + private Map<String, List<MojoExecution>> calculateLifecycleMappings( MavenSession session, MavenProject project, + String lifecyclePhase ) + throws LifecyclePhaseNotFoundException, PluginNotFoundException, PluginResolutionException, + PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException + { + /* + * Determine the lifecycle that corresponds to the given phase. + */ + + Lifecycle lifecycle = defaultLifeCycles.get( lifecyclePhase ); + + if ( lifecycle == null ) + { + throw new LifecyclePhaseNotFoundException( + "Unknown lifecycle phase \"" + lifecyclePhase + "\". You must specify a valid lifecycle phase" + + " or a goal in the format <plugin-prefix>:<goal> or" + + " <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: " + + defaultLifeCycles.getLifecyclePhaseList() + ".", lifecyclePhase ); + } + + /* + * Initialize mapping from lifecycle phase to bound mojos. The key set of this map denotes the phases the caller + * is interested in, i.e. all phases up to and including the specified phase. + */ + + Map<String, Map<Integer, List<MojoExecution>>> mappings = + new LinkedHashMap<String, Map<Integer, List<MojoExecution>>>(); + + for ( String phase : lifecycle.getPhases() ) + { + Map<Integer, List<MojoExecution>> phaseBindings = new TreeMap<Integer, List<MojoExecution>>(); + + mappings.put( phase, phaseBindings ); + + if ( phase.equals( lifecyclePhase ) ) + { + break; + } + } + + /* + * Grab plugin executions that are bound to the selected lifecycle phases from project. The effective model of + * the project already contains the plugin executions induced by the project's packaging type. Remember, all + * phases of interest and only those are in the lifecyle mapping, if a phase has no value in the map, we are not + * interested in any of the executions bound to it. + */ + + for ( Plugin plugin : project.getBuild().getPlugins() ) + { + for ( PluginExecution execution : plugin.getExecutions() ) + { + // if the phase is specified then I don't have to go fetch the plugin yet and pull it down + // to examine the phase it is associated to. + if ( execution.getPhase() != null ) + { + Map<Integer, List<MojoExecution>> phaseBindings = mappings.get( execution.getPhase() ); + if ( phaseBindings != null ) + { + for ( String goal : execution.getGoals() ) + { + MojoExecution mojoExecution = new MojoExecution( plugin, goal, execution.getId() ); + mojoExecution.setLifecyclePhase( execution.getPhase() ); + addMojoExecution( phaseBindings, mojoExecution, execution.getPriority() ); + } + } + } + // if not then i need to grab the mojo descriptor and look at the phase that is specified + else + { + for ( String goal : execution.getGoals() ) + { + MojoDescriptor mojoDescriptor = + pluginManager.getMojoDescriptor( plugin, goal, project.getRemotePluginRepositories(), + session.getRepositorySession() ); + + Map<Integer, List<MojoExecution>> phaseBindings = mappings.get( mojoDescriptor.getPhase() ); + if ( phaseBindings != null ) + { + MojoExecution mojoExecution = new MojoExecution( mojoDescriptor, execution.getId() ); + mojoExecution.setLifecyclePhase( mojoDescriptor.getPhase() ); + addMojoExecution( phaseBindings, mojoExecution, execution.getPriority() ); + } + } + } + } + } + + Map<String, List<MojoExecution>> lifecycleMappings = new LinkedHashMap<String, List<MojoExecution>>(); + + for ( Map.Entry<String, Map<Integer, List<MojoExecution>>> entry : mappings.entrySet() ) + { + List<MojoExecution> mojoExecutions = new ArrayList<MojoExecution>(); + + for ( List<MojoExecution> executions : entry.getValue().values() ) + { + mojoExecutions.addAll( executions ); + } + + lifecycleMappings.put( entry.getKey(), mojoExecutions ); + } + + return lifecycleMappings; + } + + private void addMojoExecution( Map<Integer, List<MojoExecution>> phaseBindings, MojoExecution mojoExecution, + int priority ) + { + List<MojoExecution> mojoExecutions = phaseBindings.get( priority ); + + if ( mojoExecutions == null ) + { + mojoExecutions = new ArrayList<MojoExecution>(); + phaseBindings.put( priority, mojoExecutions ); + } + + mojoExecutions.add( mojoExecution ); + } + + private void populateMojoExecutionConfiguration( MavenProject project, MojoExecution mojoExecution, + boolean allowPluginLevelConfig ) + { + String g = mojoExecution.getGroupId(); + + String a = mojoExecution.getArtifactId(); + + Plugin plugin = findPlugin( g, a, project.getBuildPlugins() ); + + if ( plugin == null && project.getPluginManagement() != null ) + { + plugin = findPlugin( g, a, project.getPluginManagement().getPlugins() ); + } + + if ( plugin != null ) + { + PluginExecution pluginExecution = + findPluginExecution( mojoExecution.getExecutionId(), plugin.getExecutions() ); + + Xpp3Dom pomConfiguration = null; + + if ( pluginExecution != null ) + { + pomConfiguration = (Xpp3Dom) pluginExecution.getConfiguration(); + } + else if ( allowPluginLevelConfig ) + { + pomConfiguration = (Xpp3Dom) plugin.getConfiguration(); + } + + Xpp3Dom mojoConfiguration = ( pomConfiguration != null ) ? new Xpp3Dom( pomConfiguration ) : null; + + mojoConfiguration = Xpp3Dom.mergeXpp3Dom( mojoExecution.getConfiguration(), mojoConfiguration ); + + mojoExecution.setConfiguration( mojoConfiguration ); + } + } + + private Plugin findPlugin( String groupId, String artifactId, Collection<Plugin> plugins ) + { + for ( Plugin plugin : plugins ) + { + if ( artifactId.equals( plugin.getArtifactId() ) && groupId.equals( plugin.getGroupId() ) ) + { + return plugin; + } + } + + return null; + } + + private PluginExecution findPluginExecution( String executionId, Collection<PluginExecution> executions ) + { + if ( StringUtils.isNotEmpty( executionId ) ) + { + for ( PluginExecution execution : executions ) + { + if ( executionId.equals( execution.getId() ) ) + { + return execution; + } + } + } + + return null; + } + + /** + * Post-processes the effective configuration for the specified mojo execution. This step discards all parameters + * from the configuration that are not applicable to the mojo and injects the default values for any missing + * parameters. + * + * @param mojoExecution The mojo execution whose configuration should be finalized, must not be {@code null}. + */ + private void finalizeMojoConfiguration( MojoExecution mojoExecution ) + { + MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); + + Xpp3Dom executionConfiguration = mojoExecution.getConfiguration(); + if ( executionConfiguration == null ) + { + executionConfiguration = new Xpp3Dom( "configuration" ); + } + + Xpp3Dom defaultConfiguration = getMojoConfiguration( mojoDescriptor ); + + Xpp3Dom finalConfiguration = new Xpp3Dom( "configuration" ); + + if ( mojoDescriptor.getParameters() != null ) + { + for ( Parameter parameter : mojoDescriptor.getParameters() ) + { + Xpp3Dom parameterConfiguration = executionConfiguration.getChild( parameter.getName() ); + + if ( parameterConfiguration == null ) + { + parameterConfiguration = executionConfiguration.getChild( parameter.getAlias() ); + } + + Xpp3Dom parameterDefaults = defaultConfiguration.getChild( parameter.getName() ); + + parameterConfiguration = + Xpp3Dom.mergeXpp3Dom( parameterConfiguration, parameterDefaults, Boolean.TRUE ); + + if ( parameterConfiguration != null ) + { + parameterConfiguration = new Xpp3Dom( parameterConfiguration, parameter.getName() ); + + if ( StringUtils.isEmpty( parameterConfiguration.getAttribute( "implementation" ) ) && + StringUtils.isNotEmpty( parameter.getImplementation() ) ) + { + parameterConfiguration.setAttribute( "implementation", parameter.getImplementation() ); + } + + finalConfiguration.addChild( parameterConfiguration ); + } + } + } + + mojoExecution.setConfiguration( finalConfiguration ); + } + + private Xpp3Dom getMojoConfiguration( MojoDescriptor mojoDescriptor ) + { + return MojoDescriptorCreator.convert( mojoDescriptor ); + } + + public void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session ) + throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException, + PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, + LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException + { + calculateForkedExecutions( mojoExecution, session, session.getCurrentProject(), new HashSet<MojoDescriptor>() ); + } + + private void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session, MavenProject project, + Collection<MojoDescriptor> alreadyForkedExecutions ) + throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException, + PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, + LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException + { + MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); + + if ( !mojoDescriptor.isForking() ) + { + return; + } + + if ( !alreadyForkedExecutions.add( mojoDescriptor ) ) + { + return; + } + + List<MavenProject> forkedProjects = + LifecycleDependencyResolver.getProjects( project, session, mojoDescriptor.isAggregator() ); + + for ( MavenProject forkedProject : forkedProjects ) + { + if ( forkedProject != project ) + { + lifecyclePluginResolver.resolveMissingPluginVersions( forkedProject, session ); + } + + List<MojoExecution> forkedExecutions; + + if ( StringUtils.isNotEmpty( mojoDescriptor.getExecutePhase() ) ) + { + forkedExecutions = + calculateForkedLifecycle( mojoExecution, session, forkedProject, alreadyForkedExecutions ); + } + else + { + forkedExecutions = + calculateForkedGoal( mojoExecution, session, forkedProject, alreadyForkedExecutions ); + } + + mojoExecution.setForkedExecutions( BuilderCommon.getKey( forkedProject ), forkedExecutions ); + } + + alreadyForkedExecutions.remove( mojoDescriptor ); + } + + private List<MojoExecution> calculateForkedLifecycle( MojoExecution mojoExecution, MavenSession session, + MavenProject project, + Collection<MojoDescriptor> alreadyForkedExecutions ) + throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException, + PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, + LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException + { + MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); + + String forkedPhase = mojoDescriptor.getExecutePhase(); + + Map<String, List<MojoExecution>> lifecycleMappings = + calculateLifecycleMappings( session, project, forkedPhase ); + + for ( List<MojoExecution> forkedExecutions : lifecycleMappings.values() ) + { + for ( MojoExecution forkedExecution : forkedExecutions ) + { + if ( forkedExecution.getMojoDescriptor() == null ) + { + MojoDescriptor forkedMojoDescriptor = + pluginManager.getMojoDescriptor( forkedExecution.getPlugin(), forkedExecution.getGoal(), + project.getRemotePluginRepositories(), + session.getRepositorySession() ); + + forkedExecution.setMojoDescriptor( forkedMojoDescriptor ); + } + + populateMojoExecutionConfiguration( project, forkedExecution, false ); + } + } + + injectLifecycleOverlay( lifecycleMappings, mojoExecution, session, project ); + + List<MojoExecution> mojoExecutions = new ArrayList<MojoExecution>(); + + for ( List<MojoExecution> forkedExecutions : lifecycleMappings.values() ) + { + for ( MojoExecution forkedExecution : forkedExecutions ) + { + if ( !alreadyForkedExecutions.contains( forkedExecution.getMojoDescriptor() ) ) + { + finalizeMojoConfiguration( forkedExecution ); + + calculateForkedExecutions( forkedExecution, session, project, alreadyForkedExecutions ); + + mojoExecutions.add( forkedExecution ); + } + } + } + + return mojoExecutions; + } + + private void injectLifecycleOverlay( Map<String, List<MojoExecution>> lifecycleMappings, + MojoExecution mojoExecution, MavenSession session, MavenProject project ) + throws PluginDescriptorParsingException, LifecycleNotFoundException, MojoNotFoundException, + PluginNotFoundException, PluginResolutionException, NoPluginFoundForPrefixException, + InvalidPluginDescriptorException, PluginVersionResolutionException + { + MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); + + PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor(); + + String forkedLifecycle = mojoDescriptor.getExecuteLifecycle(); + + if ( StringUtils.isEmpty( forkedLifecycle ) ) + { + return; + } + + org.apache.maven.plugin.lifecycle.Lifecycle lifecycleOverlay; + + try + { + lifecycleOverlay = pluginDescriptor.getLifecycleMapping( forkedLifecycle ); + } + catch ( IOException e ) + { + throw new PluginDescriptorParsingException( pluginDescriptor.getPlugin(), pluginDescriptor.getSource(), e ); + } + catch ( XmlPullParserException e ) + { + throw new PluginDescriptorParsingException( pluginDescriptor.getPlugin(), pluginDescriptor.getSource(), e ); + } + + if ( lifecycleOverlay == null ) + { + throw new LifecycleNotFoundException( forkedLifecycle ); + } + + for ( Phase phase : lifecycleOverlay.getPhases() ) + { + List<MojoExecution> forkedExecutions = lifecycleMappings.get( phase.getId() ); + + if ( forkedExecutions != null ) + { + for ( Execution execution : phase.getExecutions() ) + { + for ( String goal : execution.getGoals() ) + { + MojoDescriptor forkedMojoDescriptor; + + if ( goal.indexOf( ':' ) < 0 ) + { + forkedMojoDescriptor = pluginDescriptor.getMojo( goal ); + if ( forkedMojoDescriptor == null ) + { + throw new MojoNotFoundException( goal, pluginDescriptor ); + } + } + else + { + forkedMojoDescriptor = mojoDescriptorCreator.getMojoDescriptor( goal, session, project ); + } + + MojoExecution forkedExecution = + new MojoExecution( forkedMojoDescriptor, mojoExecution.getExecutionId() ); + + Xpp3Dom forkedConfiguration = (Xpp3Dom) execution.getConfiguration(); + + forkedExecution.setConfiguration( forkedConfiguration ); + + populateMojoExecutionConfiguration( project, forkedExecution, true ); + + forkedExecutions.add( forkedExecution ); + } + } + + Xpp3Dom phaseConfiguration = (Xpp3Dom) phase.getConfiguration(); + + if ( phaseConfiguration != null ) + { + for ( MojoExecution forkedExecution : forkedExecutions ) + { + Xpp3Dom forkedConfiguration = forkedExecution.getConfiguration(); + + forkedConfiguration = Xpp3Dom.mergeXpp3Dom( phaseConfiguration, forkedConfiguration ); + + forkedExecution.setConfiguration( forkedConfiguration ); + } + } + } + } + } + // org.apache.maven.plugins:maven-remote-resources-plugin:1.0:process + //TODO: take repo mans into account as one may be aggregating prefixes of many + //TODO: collect at the root of the repository, read the one at the root, and fetch remote if something is missing + // or the user forces the issue + + private List<MojoExecution> calculateForkedGoal( MojoExecution mojoExecution, MavenSession session, + MavenProject project, + Collection<MojoDescriptor> alreadyForkedExecutions ) + throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException, + PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, + LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException + { + MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); + + PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor(); + + String forkedGoal = mojoDescriptor.getExecuteGoal(); + + MojoDescriptor forkedMojoDescriptor = pluginDescriptor.getMojo( forkedGoal ); + if ( forkedMojoDescriptor == null ) + { + throw new MojoNotFoundException( forkedGoal, pluginDescriptor ); + } + + if ( alreadyForkedExecutions.contains( forkedMojoDescriptor ) ) + { + return Collections.emptyList(); + } + + MojoExecution forkedExecution = new MojoExecution( forkedMojoDescriptor, forkedGoal ); + + populateMojoExecutionConfiguration( project, forkedExecution, true ); + + finalizeMojoConfiguration( forkedExecution ); + + calculateForkedExecutions( forkedExecution, session, project, alreadyForkedExecutions ); + + return Collections.singletonList( forkedExecution ); + } + + +} diff --git a/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculator.java b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculator.java new file mode 100644 index 00000000..7d35b102 --- /dev/null +++ b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculator.java @@ -0,0 +1,67 @@ +package org.apache.maven.lifecycle.internal; + +/* + * 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. + */ + +import org.apache.maven.execution.MavenSession; +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.MojoNotFoundException; +import org.apache.maven.plugin.PluginDescriptorParsingException; +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.project.MavenProject; + +import java.util.List; + +/** + * @since 3.0 + * @author Benjamin Bentmann + * @author Kristian Rosenvold (extract interface only) + * <p/> + */ +public interface LifecycleExecutionPlanCalculator +{ + MavenExecutionPlan calculateExecutionPlan( MavenSession session, MavenProject project, List<Object> tasks ) + throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException, + PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException, + NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException; + + MavenExecutionPlan calculateExecutionPlan( MavenSession session, MavenProject project, List<Object> tasks, + boolean setup ) + throws PluginNotFoundException, PluginResolutionException, LifecyclePhaseNotFoundException, + PluginDescriptorParsingException, MojoNotFoundException, InvalidPluginDescriptorException, + NoPluginFoundForPrefixException, LifecycleNotFoundException, PluginVersionResolutionException; + + void calculateForkedExecutions( MojoExecution mojoExecution, MavenSession session ) + throws MojoNotFoundException, PluginNotFoundException, PluginResolutionException, + PluginDescriptorParsingException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, + LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException; + + void setupMojoExecution( MavenSession session, MavenProject project, MojoExecution mojoExecution ) + throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, + MojoNotFoundException, InvalidPluginDescriptorException, NoPluginFoundForPrefixException, + LifecyclePhaseNotFoundException, LifecycleNotFoundException, PluginVersionResolutionException; + +} diff --git a/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculator.java b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculator.java new file mode 100644 index 00000000..113a5ab3 --- /dev/null +++ b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculator.java @@ -0,0 +1,61 @@ +package org.apache.maven.lifecycle.internal; + +/* + * 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. + */ + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.lifecycle.LifecycleNotFoundException; +import org.apache.maven.lifecycle.LifecyclePhaseNotFoundException; +import org.apache.maven.plugin.InvalidPluginDescriptorException; +import org.apache.maven.plugin.MojoNotFoundException; +import org.apache.maven.plugin.PluginDescriptorParsingException; +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 java.util.List; + +/** + * Calculates the task segments in the build + * + * @since 3.0 + * @author Benjamin Bentmann + * @author Jason van Zyl + * @author jdcasey + * @author Kristian Rosenvold (extracted interface) + * <p/> + * NOTE: This interface is not part of any public api and can be changed or deleted without prior notice. + */ + +public interface LifecycleTaskSegmentCalculator +{ + List<TaskSegment> calculateTaskSegments( MavenSession session ) + throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, + MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, + PluginVersionResolutionException, LifecyclePhaseNotFoundException, LifecycleNotFoundException; + + public List<TaskSegment> calculateTaskSegments( MavenSession session, List<String> tasks ) + throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException, + MojoNotFoundException, NoPluginFoundForPrefixException, InvalidPluginDescriptorException, + PluginVersionResolutionException; + + boolean requiresProject( MavenSession session ); + +} diff --git a/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.java b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.java new file mode 100644 index 00000000..da0673af --- /dev/null +++ b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.java @@ -0,0 +1,236 @@ +package org.apache.maven.model.inheritance; + +/* + * 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. + */ + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.apache.maven.model.Model; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginContainer; +import org.apache.maven.model.ReportPlugin; +import org.apache.maven.model.Reporting; +import org.apache.maven.model.building.ModelBuildingRequest; +import org.apache.maven.model.building.ModelProblemCollector; +import org.apache.maven.model.merge.MavenModelMerger; +import org.codehaus.plexus.component.annotations.Component; + +/** + * Handles inheritance of model values. + * + * @author Benjamin Bentmann + */ +@Component( role = InheritanceAssembler.class ) +public class DefaultInheritanceAssembler + implements InheritanceAssembler +{ + + private InheritanceModelMerger merger = new InheritanceModelMerger(); + + public void assembleModelInheritance( Model child, Model parent, ModelBuildingRequest request, + ModelProblemCollector problems ) + { + Map<Object, Object> hints = new HashMap<Object, Object>(); + hints.put( MavenModelMerger.CHILD_PATH_ADJUSTMENT, getChildPathAdjustment( child, parent ) ); + merger.merge( child, parent, false, hints ); + } + + /** + * Calculates the relative path from the base directory of the parent to the parent directory of the base directory + * of the child. The general idea is to adjust inherited URLs to match the project layout (in SCM). This calculation + * is only a heuristic based on our conventions. In detail, the algo relies on the following assumptions. The parent + * uses aggregation and refers to the child via the modules section. The module path to the child is considered to + * point at the POM rather than its base directory if the path ends with ".xml" (ignoring case). The name of the + * child's base directory matches the artifact id of the child. Note that for the sake of independence from the user + * environment, the filesystem is intentionally not used for the calculation. + * + * @param child The child model, must not be <code>null</code>. + * @param parent The parent model, may be <code>null</code>. + * @return The path adjustment, can be empty but never <code>null</code>. + */ + private String getChildPathAdjustment( Model child, Model parent ) + { + String adjustment = ""; + + if ( parent != null ) + { + String childArtifactId = child.getArtifactId(); + + for ( String module : parent.getModules() ) + { + module = module.replace( '\\', '/' ); + + if ( module.regionMatches( true, module.length() - 4, ".xml", 0, 4 ) ) + { + module = module.substring( 0, module.lastIndexOf( '/' ) + 1 ); + } + + String moduleName = module; + if ( moduleName.endsWith( "/" ) ) + { + moduleName = moduleName.substring( 0, moduleName.length() - 1 ); + } + + int lastSlash = moduleName.lastIndexOf( '/' ); + + moduleName = moduleName.substring( lastSlash + 1 ); + + if ( moduleName.equals( childArtifactId ) && lastSlash >= 0 ) + { + adjustment = module.substring( 0, lastSlash ); + break; + } + } + } + + return adjustment; + } + + private static class InheritanceModelMerger + extends MavenModelMerger + { + + @Override + protected void mergePluginContainer_Plugins( PluginContainer target, PluginContainer source, + boolean sourceDominant, Map<Object, Object> context ) + { + List<Plugin> src = source.getPlugins(); + if ( !src.isEmpty() ) + { + List<Plugin> tgt = target.getPlugins(); + Map<Object, Plugin> master = new LinkedHashMap<Object, Plugin>( src.size() * 2 ); + + for ( Plugin element : src ) + { + if ( element.isInherited() || !element.getExecutions().isEmpty() ) + { + // NOTE: Enforce recursive merge to trigger merging/inheritance logic for executions + Plugin plugin = new Plugin(); + plugin.setLocation( "", element.getLocation( "" ) ); + plugin.setGroupId( null ); + mergePlugin( plugin, element, sourceDominant, context ); + + Object key = getPluginKey( element ); + + master.put( key, plugin ); + } + } + + Map<Object, List<Plugin>> predecessors = new LinkedHashMap<Object, List<Plugin>>(); + List<Plugin> pending = new ArrayList<Plugin>(); + for ( Plugin element : tgt ) + { + Object key = getPluginKey( element ); + Plugin existing = master.get( key ); + if ( existing != null ) + { + mergePlugin( element, existing, sourceDominant, context ); + + master.put( key, element ); + + if ( !pending.isEmpty() ) + { + predecessors.put( key, pending ); + pending = new ArrayList<Plugin>(); + } + } + else + { + pending.add( element ); + } + } + + List<Plugin> result = new ArrayList<Plugin>( src.size() + tgt.size() ); + for ( Map.Entry<Object, Plugin> entry : master.entrySet() ) + { + List<Plugin> pre = predecessors.get( entry.getKey() ); + if ( pre != null ) + { + result.addAll( pre ); + } + result.add( entry.getValue() ); + } + result.addAll( pending ); + + target.setPlugins( result ); + } + } + + @Override + protected void mergePlugin( Plugin target, Plugin source, boolean sourceDominant, Map<Object, Object> context ) + { + if ( source.isInherited() ) + { + mergeConfigurationContainer( target, source, sourceDominant, context ); + } + mergePlugin_GroupId( target, source, sourceDominant, context ); + mergePlugin_ArtifactId( target, source, sourceDominant, context ); + mergePlugin_Version( target, source, sourceDominant, context ); + mergePlugin_Extensions( target, source, sourceDominant, context ); + mergePlugin_Dependencies( target, source, sourceDominant, context ); + mergePlugin_Executions( target, source, sourceDominant, context ); + } + + @Override + protected void mergeReporting_Plugins( Reporting target, Reporting source, boolean sourceDominant, + Map<Object, Object> context ) + { + List<ReportPlugin> src = source.getPlugins(); + if ( !src.isEmpty() ) + { + List<ReportPlugin> tgt = target.getPlugins(); + Map<Object, ReportPlugin> merged = + new LinkedHashMap<Object, ReportPlugin>( ( src.size() + tgt.size() ) * 2 ); + + for ( ReportPlugin element : src ) + { + Object key = getReportPluginKey( element ); + if ( element.isInherited() ) + { + // NOTE: Enforce recursive merge to trigger merging/inheritance logic for executions as well + ReportPlugin plugin = new ReportPlugin(); + plugin.setLocation( "", element.getLocation( "" ) ); + plugin.setGroupId( null ); + mergeReportPlugin( plugin, element, sourceDominant, context ); + + merged.put( key, plugin ); + } + } + + for ( ReportPlugin element : tgt ) + { + Object key = getReportPluginKey( element ); + ReportPlugin existing = merged.get( key ); + if ( existing != null ) + { + mergeReportPlugin( element, existing, sourceDominant, context ); + } + merged.put( key, element ); + } + + target.setPlugins( new ArrayList<ReportPlugin>( merged.values() ) ); + } + } + } + +} diff --git a/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java new file mode 100644 index 00000000..9c646b75 --- /dev/null +++ b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java @@ -0,0 +1,718 @@ +package org.apache.maven.plugin.internal; + +/* + * 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. + */ + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.io.Reader; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.jar.JarFile; +import java.util.zip.ZipEntry; + +import org.apache.maven.RepositoryUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.classrealm.ClassRealmManager; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Plugin; +import org.apache.maven.monitor.logging.DefaultLog; +import org.apache.maven.plugin.ContextEnabled; +import org.apache.maven.plugin.DebugConfigurationListener; +import org.apache.maven.plugin.InvalidPluginDescriptorException; +import org.apache.maven.plugin.MavenPluginManager; +import org.apache.maven.plugin.MavenPluginValidator; +import org.apache.maven.plugin.Mojo; +import org.apache.maven.plugin.MojoExecution; +import org.apache.maven.plugin.MojoNotFoundException; +import org.apache.maven.plugin.PluginConfigurationException; +import org.apache.maven.plugin.PluginContainerException; +import org.apache.maven.plugin.PluginDescriptorCache; +import org.apache.maven.plugin.PluginDescriptorParsingException; +import org.apache.maven.plugin.PluginIncompatibleException; +import org.apache.maven.plugin.PluginParameterException; +import org.apache.maven.plugin.PluginParameterExpressionEvaluator; +import org.apache.maven.plugin.PluginRealmCache; +import org.apache.maven.plugin.PluginResolutionException; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.Parameter; +import org.apache.maven.plugin.descriptor.PluginDescriptor; +import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder; +import org.apache.maven.project.MavenProject; +import org.apache.maven.rtinfo.RuntimeInformation; +import org.codehaus.plexus.PlexusContainer; +import org.codehaus.plexus.classworlds.realm.ClassRealm; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; +import org.codehaus.plexus.component.composition.CycleDetectedInComponentGraphException; +import org.codehaus.plexus.component.configurator.ComponentConfigurationException; +import org.codehaus.plexus.component.configurator.ComponentConfigurator; +import org.codehaus.plexus.component.configurator.ConfigurationListener; +import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException; +import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator; +import org.codehaus.plexus.component.repository.ComponentDescriptor; +import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException; +import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import org.codehaus.plexus.configuration.PlexusConfiguration; +import org.codehaus.plexus.configuration.PlexusConfigurationException; +import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; +import org.codehaus.plexus.logging.Logger; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.ReaderFactory; +import org.codehaus.plexus.util.StringUtils; +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.sonatype.aether.RepositorySystemSession; +import org.sonatype.aether.graph.DependencyFilter; +import org.sonatype.aether.graph.DependencyNode; +import org.sonatype.aether.repository.RemoteRepository; +import org.sonatype.aether.util.filter.AndDependencyFilter; +import org.sonatype.aether.util.graph.PreorderNodeListGenerator; + +/** + * Provides basic services to manage Maven plugins and their mojos. This component is kept general in its design such + * that the plugins/mojos can be used in arbitrary contexts. In particular, the mojos can be used for ordinary build + * plugins as well as special purpose plugins like reports. + * + * @since 3.0 + * @author Benjamin Bentmann + */ +@Component( role = MavenPluginManager.class ) +public class DefaultMavenPluginManager + implements MavenPluginManager +{ + + @Requirement + private Logger logger; + + @Requirement + private PlexusContainer container; + + @Requirement + private ClassRealmManager classRealmManager; + + @Requirement + private PluginDescriptorCache pluginDescriptorCache; + + @Requirement + private PluginRealmCache pluginRealmCache; + + @Requirement + private PluginDependenciesResolver pluginDependenciesResolver; + + @Requirement + private RuntimeInformation runtimeInformation; + + private PluginDescriptorBuilder builder = new PluginDescriptorBuilder(); + + public synchronized PluginDescriptor getPluginDescriptor( Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session ) + throws PluginResolutionException, PluginDescriptorParsingException, InvalidPluginDescriptorException + { + PluginDescriptorCache.Key cacheKey = pluginDescriptorCache.createKey( plugin, repositories, session ); + + PluginDescriptor pluginDescriptor = pluginDescriptorCache.get( cacheKey ); + + if ( pluginDescriptor == null ) + { + org.sonatype.aether.artifact.Artifact artifact = + pluginDependenciesResolver.resolve( plugin, repositories, session ); + + Artifact pluginArtifact = RepositoryUtils.toArtifact( artifact ); + + pluginDescriptor = extractPluginDescriptor( pluginArtifact, plugin ); + + pluginDescriptor.setRequiredMavenVersion( artifact.getProperty( "requiredMavenVersion", null ) ); + + pluginDescriptorCache.put( cacheKey, pluginDescriptor ); + } + + pluginDescriptor.setPlugin( plugin ); + + return pluginDescriptor; + } + + private PluginDescriptor extractPluginDescriptor( Artifact pluginArtifact, Plugin plugin ) + throws PluginDescriptorParsingException, InvalidPluginDescriptorException + { + PluginDescriptor pluginDescriptor = null; + + File pluginFile = pluginArtifact.getFile(); + + try + { + if ( pluginFile.isFile() ) + { + JarFile pluginJar = new JarFile( pluginFile, false ); + try + { + ZipEntry pluginDescriptorEntry = pluginJar.getEntry( getPluginDescriptorLocation() ); + + if ( pluginDescriptorEntry != null ) + { + InputStream is = pluginJar.getInputStream( pluginDescriptorEntry ); + + pluginDescriptor = parsePluginDescriptor( is, plugin, pluginFile.getAbsolutePath() ); + } + } + finally + { + pluginJar.close(); + } + } + else + { + File pluginXml = new File( pluginFile, getPluginDescriptorLocation() ); + + if ( pluginXml.isFile() ) + { + InputStream is = new BufferedInputStream( new FileInputStream( pluginXml ) ); + try + { + pluginDescriptor = parsePluginDescriptor( is, plugin, pluginXml.getAbsolutePath() ); + } + finally + { + IOUtil.close( is ); + } + } + } + + if ( pluginDescriptor == null ) + { + throw new IOException( "No plugin descriptor found at " + getPluginDescriptorLocation() ); + } + } + catch ( IOException e ) + { + throw new PluginDescriptorParsingException( plugin, pluginFile.getAbsolutePath(), e ); + } + + MavenPluginValidator validator = new MavenPluginValidator( pluginArtifact ); + + validator.validate( pluginDescriptor ); + + if ( validator.hasErrors() ) + { + throw new InvalidPluginDescriptorException( "Invalid plugin descriptor for " + plugin.getId() + " (" + + pluginFile + ")", validator.getErrors() ); + } + + pluginDescriptor.setPluginArtifact( pluginArtifact ); + + return pluginDescriptor; + } + + private String getPluginDescriptorLocation() + { + return "META-INF/maven/plugin.xml"; + } + + private PluginDescriptor parsePluginDescriptor( InputStream is, Plugin plugin, String descriptorLocation ) + throws PluginDescriptorParsingException + { + try + { + Reader reader = ReaderFactory.newXmlReader( is ); + + PluginDescriptor pluginDescriptor = builder.build( reader, descriptorLocation ); + + return pluginDescriptor; + } + catch ( IOException e ) + { + throw new PluginDescriptorParsingException( plugin, descriptorLocation, e ); + } + catch ( PlexusConfigurationException e ) + { + throw new PluginDescriptorParsingException( plugin, descriptorLocation, e ); + } + } + + public MojoDescriptor getMojoDescriptor( Plugin plugin, String goal, List<RemoteRepository> repositories, + RepositorySystemSession session ) + throws MojoNotFoundException, PluginResolutionException, PluginDescriptorParsingException, + InvalidPluginDescriptorException + { + PluginDescriptor pluginDescriptor = getPluginDescriptor( plugin, repositories, session ); + + MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( goal ); + + if ( mojoDescriptor == null ) + { + throw new MojoNotFoundException( goal, pluginDescriptor ); + } + + return mojoDescriptor; + } + + public void checkRequiredMavenVersion( PluginDescriptor pluginDescriptor ) + throws PluginIncompatibleException + { + String requiredMavenVersion = pluginDescriptor.getRequiredMavenVersion(); + if ( StringUtils.isNotBlank( requiredMavenVersion ) ) + { + try + { + if ( !runtimeInformation.isMavenVersion( requiredMavenVersion ) ) + { + throw new PluginIncompatibleException( pluginDescriptor.getPlugin(), "The plugin " + + pluginDescriptor.getId() + " requires Maven version " + requiredMavenVersion ); + } + } + catch ( RuntimeException e ) + { + logger.warn( "Could not verify plugin's Maven prerequisite: " + e.getMessage() ); + } + } + } + + public synchronized void setupPluginRealm( PluginDescriptor pluginDescriptor, MavenSession session, + ClassLoader parent, List<String> imports, DependencyFilter filter ) + throws PluginResolutionException, PluginContainerException + { + Plugin plugin = pluginDescriptor.getPlugin(); + + MavenProject project = session.getCurrentProject(); + + PluginRealmCache.Key cacheKey = + pluginRealmCache.createKey( plugin, parent, imports, filter, project.getRemotePluginRepositories(), + session.getRepositorySession() ); + + PluginRealmCache.CacheRecord cacheRecord = pluginRealmCache.get( cacheKey ); + + if ( cacheRecord != null ) + { + pluginDescriptor.setClassRealm( cacheRecord.realm ); + pluginDescriptor.setArtifacts( new ArrayList<Artifact>( cacheRecord.artifacts ) ); + for ( ComponentDescriptor<?> componentDescriptor : pluginDescriptor.getComponents() ) + { + componentDescriptor.setRealm( cacheRecord.realm ); + } + } + else + { + createPluginRealm( pluginDescriptor, session, parent, imports, filter ); + + cacheRecord = + pluginRealmCache.put( cacheKey, pluginDescriptor.getClassRealm(), pluginDescriptor.getArtifacts() ); + } + + pluginRealmCache.register( project, cacheRecord ); + } + + private void createPluginRealm( PluginDescriptor pluginDescriptor, MavenSession session, ClassLoader parent, + List<String> imports, DependencyFilter filter ) + throws PluginResolutionException, PluginContainerException + { + Plugin plugin = pluginDescriptor.getPlugin(); + + if ( plugin == null ) + { + throw new IllegalArgumentException( "incomplete plugin descriptor, plugin missing" ); + } + + Artifact pluginArtifact = pluginDescriptor.getPluginArtifact(); + + if ( pluginArtifact == null ) + { + throw new IllegalArgumentException( "incomplete plugin descriptor, plugin artifact missing" ); + } + + MavenProject project = session.getCurrentProject(); + + DependencyFilter dependencyFilter = project.getExtensionDependencyFilter(); + dependencyFilter = AndDependencyFilter.newInstance( dependencyFilter, filter ); + + DependencyNode root = + pluginDependenciesResolver.resolve( plugin, RepositoryUtils.toArtifact( pluginArtifact ), dependencyFilter, + project.getRemotePluginRepositories(), session.getRepositorySession() ); + + PreorderNodeListGenerator nlg = new PreorderNodeListGenerator(); + root.accept( nlg ); + + List<Artifact> exposedPluginArtifacts = new ArrayList<Artifact>( nlg.getNodes().size() ); + RepositoryUtils.toArtifacts( exposedPluginArtifacts, Collections.singleton( root ), + Collections.<String> emptyList(), null ); + for ( Iterator<Artifact> it = exposedPluginArtifacts.iterator(); it.hasNext(); ) + { + Artifact artifact = it.next(); + if ( artifact.getFile() == null ) + { + it.remove(); + } + } + + List<org.sonatype.aether.artifact.Artifact> pluginArtifacts = nlg.getArtifacts( true ); + + Map<String, ClassLoader> foreignImports = calcImports( project, parent, imports ); + + ClassRealm pluginRealm = + classRealmManager.createPluginRealm( plugin, parent, null, foreignImports, pluginArtifacts ); + + pluginDescriptor.setClassRealm( pluginRealm ); + pluginDescriptor.setArtifacts( exposedPluginArtifacts ); + + try + { + for ( ComponentDescriptor<?> componentDescriptor : pluginDescriptor.getComponents() ) + { + componentDescriptor.setRealm( pluginRealm ); + container.addComponentDescriptor( componentDescriptor ); + } + + container.discoverComponents( pluginRealm ); + } + catch ( PlexusConfigurationException e ) + { + throw new PluginContainerException( plugin, pluginRealm, "Error in component graph of plugin " + + plugin.getId() + ": " + e.getMessage(), e ); + } + catch ( CycleDetectedInComponentGraphException e ) + { + throw new PluginContainerException( plugin, pluginRealm, "Error in component graph of plugin " + + plugin.getId() + ": " + e.getMessage(), e ); + } + } + + private Map<String, ClassLoader> calcImports( MavenProject project, ClassLoader parent, List<String> imports ) + { + Map<String, ClassLoader> foreignImports = new HashMap<String, ClassLoader>(); + + ClassLoader projectRealm = project.getClassRealm(); + if ( projectRealm != null ) + { + foreignImports.put( "", projectRealm ); + } + else + { + foreignImports.put( "", classRealmManager.getMavenApiRealm() ); + } + + if ( parent != null && imports != null ) + { + for ( String parentImport : imports ) + { + foreignImports.put( parentImport, parent ); + } + } + + return foreignImports; + } + + public <T> T getConfiguredMojo( Class<T> mojoInterface, MavenSession session, MojoExecution mojoExecution ) + throws PluginConfigurationException, PluginContainerException + { + MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); + + PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor(); + + ClassRealm pluginRealm = pluginDescriptor.getClassRealm(); + + if ( logger.isDebugEnabled() ) + { + logger.debug( "Configuring mojo " + mojoDescriptor.getId() + " from plugin realm " + pluginRealm ); + } + + // We are forcing the use of the plugin realm for all lookups that might occur during + // the lifecycle that is part of the lookup. Here we are specifically trying to keep + // lookups that occur in contextualize calls in line with the right realm. + ClassRealm oldLookupRealm = container.setLookupRealm( pluginRealm ); + + ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader( pluginRealm ); + + try + { + T mojo; + + try + { + mojo = container.lookup( mojoInterface, mojoDescriptor.getRoleHint() ); + } + catch ( ComponentLookupException e ) + { + Throwable cause = e.getCause(); + while ( cause != null && !( cause instanceof LinkageError ) + && !( cause instanceof ClassNotFoundException ) ) + { + cause = cause.getCause(); + } + + if ( ( cause instanceof NoClassDefFoundError ) || ( cause instanceof ClassNotFoundException ) ) + { + ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 ); + PrintStream ps = new PrintStream( os ); + ps.println( "Unable to load the mojo '" + mojoDescriptor.getGoal() + "' in the plugin '" + + pluginDescriptor.getId() + "'. A required class is missing: " + cause.getMessage() ); + pluginRealm.display( ps ); + + throw new PluginContainerException( mojoDescriptor, pluginRealm, os.toString(), cause ); + } + else if ( cause instanceof LinkageError ) + { + ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 ); + PrintStream ps = new PrintStream( os ); + ps.println( "Unable to load the mojo '" + mojoDescriptor.getGoal() + "' in the plugin '" + + pluginDescriptor.getId() + "' due to an API incompatibility: " + e.getClass().getName() + + ": " + cause.getMessage() ); + pluginRealm.display( ps ); + + throw new PluginContainerException( mojoDescriptor, pluginRealm, os.toString(), cause ); + } + + throw new PluginContainerException( mojoDescriptor, pluginRealm, "Unable to load the mojo '" + + mojoDescriptor.getGoal() + "' (or one of its required components) from the plugin '" + + pluginDescriptor.getId() + "'", e ); + } + + if ( mojo instanceof ContextEnabled ) + { + MavenProject project = session.getCurrentProject(); + + Map<String, Object> pluginContext = session.getPluginContext( pluginDescriptor, project ); + + if ( pluginContext != null ) + { + pluginContext.put( "project", project ); + + pluginContext.put( "pluginDescriptor", pluginDescriptor ); + + ( (ContextEnabled) mojo ).setPluginContext( pluginContext ); + } + } + + if ( mojo instanceof Mojo ) + { + ( (Mojo) mojo ).setLog( new DefaultLog( logger ) ); + } + + Xpp3Dom dom = mojoExecution.getConfiguration(); + + PlexusConfiguration pomConfiguration; + + if ( dom == null ) + { + pomConfiguration = new XmlPlexusConfiguration( "configuration" ); + } + else + { + pomConfiguration = new XmlPlexusConfiguration( dom ); + } + + ExpressionEvaluator expressionEvaluator = new PluginParameterExpressionEvaluator( session, mojoExecution ); + + populatePluginFields( mojo, mojoDescriptor, pluginRealm, pomConfiguration, expressionEvaluator ); + + return mojo; + } + finally + { + Thread.currentThread().setContextClassLoader( oldClassLoader ); + container.setLookupRealm( oldLookupRealm ); + } + } + + private void populatePluginFields( Object mojo, MojoDescriptor mojoDescriptor, ClassRealm pluginRealm, + PlexusConfiguration configuration, ExpressionEvaluator expressionEvaluator ) + throws PluginConfigurationException + { + ComponentConfigurator configurator = null; + + String configuratorId = mojoDescriptor.getComponentConfigurator(); + + if ( StringUtils.isEmpty( configuratorId ) ) + { + configuratorId = "basic"; + } + + try + { + // TODO: could the configuration be passed to lookup and the configurator known to plexus via the descriptor + // so that this method could entirely be handled by a plexus lookup? + configurator = container.lookup( ComponentConfigurator.class, configuratorId ); + + ConfigurationListener listener = new DebugConfigurationListener( logger ); + + ValidatingConfigurationListener validator = + new ValidatingConfigurationListener( mojo, mojoDescriptor, listener ); + + logger.debug( "Configuring mojo '" + mojoDescriptor.getId() + "' with " + configuratorId + + " configurator -->" ); + + configurator.configureComponent( mojo, configuration, expressionEvaluator, pluginRealm, validator ); + + logger.debug( "-- end configuration --" ); + + Collection<Parameter> missingParameters = validator.getMissingParameters(); + if ( !missingParameters.isEmpty() ) + { + if ( "basic".equals( configuratorId ) ) + { + throw new PluginParameterException( mojoDescriptor, new ArrayList<Parameter>( missingParameters ) ); + } + else + { + /* + * NOTE: Other configurators like the map-oriented one don't call into the listener, so do it the + * hard way. + */ + validateParameters( mojoDescriptor, configuration, expressionEvaluator ); + } + } + } + catch ( ComponentConfigurationException e ) + { + String message = "Unable to parse configuration of mojo " + mojoDescriptor.getId(); + if ( e.getFailedConfiguration() != null ) + { + message += " for parameter " + e.getFailedConfiguration().getName(); + } + message += ": " + e.getMessage(); + + throw new PluginConfigurationException( mojoDescriptor.getPluginDescriptor(), message, e ); + } + catch ( ComponentLookupException e ) + { + throw new PluginConfigurationException( mojoDescriptor.getPluginDescriptor(), + "Unable to retrieve component configurator " + configuratorId + + " for configuration of mojo " + mojoDescriptor.getId(), e ); + } + catch ( NoClassDefFoundError e ) + { + ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 ); + PrintStream ps = new PrintStream( os ); + ps.println( "A required class was missing during configuration of mojo " + mojoDescriptor.getId() + ": " + + e.getMessage() ); + pluginRealm.display( ps ); + + throw new PluginConfigurationException( mojoDescriptor.getPluginDescriptor(), os.toString(), e ); + } + catch ( LinkageError e ) + { + ByteArrayOutputStream os = new ByteArrayOutputStream( 1024 ); + PrintStream ps = new PrintStream( os ); + ps.println( "An API incompatibility was encountered during configuration of mojo " + mojoDescriptor.getId() + + ": " + e.getClass().getName() + ": " + e.getMessage() ); + pluginRealm.display( ps ); + + throw new PluginConfigurationException( mojoDescriptor.getPluginDescriptor(), os.toString(), e ); + } + finally + { + if ( configurator != null ) + { + try + { + container.release( configurator ); + } + catch ( ComponentLifecycleException e ) + { + logger.debug( "Failed to release mojo configurator - ignoring." ); + } + } + } + } + + private void validateParameters( MojoDescriptor mojoDescriptor, PlexusConfiguration configuration, + ExpressionEvaluator expressionEvaluator ) + throws ComponentConfigurationException, PluginParameterException + { + if ( mojoDescriptor.getParameters() == null ) + { + return; + } + + List<Parameter> invalidParameters = new ArrayList<Parameter>(); + + for ( Parameter parameter : mojoDescriptor.getParameters() ) + { + if ( !parameter.isRequired() ) + { + continue; + } + + Object value = null; + + PlexusConfiguration config = configuration.getChild( parameter.getName(), false ); + if ( config != null ) + { + String expression = config.getValue( null ); + + try + { + value = expressionEvaluator.evaluate( expression ); + + if ( value == null ) + { + value = config.getAttribute( "default-value", null ); + } + } + catch ( ExpressionEvaluationException e ) + { + String msg = + "Error evaluating the expression '" + expression + "' for configuration value '" + + configuration.getName() + "'"; + throw new ComponentConfigurationException( configuration, msg, e ); + } + } + + if ( value == null && ( config == null || config.getChildCount() <= 0 ) ) + { + invalidParameters.add( parameter ); + } + } + + if ( !invalidParameters.isEmpty() ) + { + throw new PluginParameterException( mojoDescriptor, invalidParameters ); + } + } + + public void releaseMojo( Object mojo, MojoExecution mojoExecution ) + { + if ( mojo != null ) + { + try + { + container.release( mojo ); + } + catch ( ComponentLifecycleException e ) + { + String goalExecId = mojoExecution.getGoal(); + + if ( mojoExecution.getExecutionId() != null ) + { + goalExecId += " {execution: " + mojoExecution.getExecutionId() + "}"; + } + + logger.debug( "Error releasing mojo for " + goalExecId, e ); + } + } + } + +} diff --git a/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/sonatype/aether/connector/async/CompletionHandler.java b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/sonatype/aether/connector/async/CompletionHandler.java new file mode 100644 index 00000000..8b13300d --- /dev/null +++ b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/sonatype/aether/connector/async/CompletionHandler.java @@ -0,0 +1,388 @@ +package org.sonatype.aether.connector.async; + +/******************************************************************************* + * Copyright (c) 2010-2011 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * and Apache License v2.0 which accompanies this distribution. + * The Eclipse Public License is available at + * http://www.eclipse.org/legal/epl-v10.html + * The Apache License v2.0 is available at + * http://www.apache.org/licenses/LICENSE-2.0.html + * You may elect to redistribute this code under either of these licenses. + *******************************************************************************/ + +import com.ning.http.client.AsyncHandler; +import com.ning.http.client.AsyncHttpClient; +import com.ning.http.client.HttpResponseBodyPart; +import com.ning.http.client.HttpResponseHeaders; +import com.ning.http.client.HttpResponseStatus; +import com.ning.http.client.ProgressAsyncHandler; +import com.ning.http.client.Response; +import org.sonatype.aether.spi.log.Logger; +import org.sonatype.aether.transfer.TransferCancelledException; +import org.sonatype.aether.transfer.TransferEvent; +import org.sonatype.aether.transfer.TransferListener; +import org.sonatype.aether.transfer.TransferResource; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.nio.ByteBuffer; +import java.util.Collections; +import java.util.Iterator; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; + +/** + * An {@link AsyncHandler} for handling asynchronous download an upload. + * + * @author Jeanfrancois Arcand + */ +class CompletionHandler + implements ProgressAsyncHandler<Response> +{ + private final Logger logger; + + private HttpResponseStatus status; + + private HttpResponseHeaders headers; + + private final ConcurrentLinkedQueue<TransferListener> listeners = new ConcurrentLinkedQueue<TransferListener>(); + + private final AsyncHttpClient httpClient; + + private final AtomicLong byteTransfered = new AtomicLong(); + + private final AtomicReference<Throwable> exception = new AtomicReference<Throwable>(); + + private final TransferResource transferResource; + + private final TransferEvent.RequestType requestType; + + public CompletionHandler( TransferResource transferResource, AsyncHttpClient httpClient, Logger logger, + TransferEvent.RequestType requestType ) + { + this.httpClient = httpClient; + this.transferResource = transferResource; + this.logger = logger; + this.requestType = requestType; + } + + public STATE onHeaderWriteCompleted() + { + if ( TransferEvent.RequestType.PUT.equals( requestType ) ) + { + byteTransfered.set( 0 ); + try + { + fireTransferStarted(); + } + catch ( TransferCancelledException e ) + { + return STATE.ABORT; + } + } + return STATE.CONTINUE; + } + + public STATE onContentWriteCompleted() + { + return STATE.CONTINUE; + } + + public STATE onContentWriteProgress( long amount, long current, long total ) + { + return STATE.CONTINUE; + } + + /** + * {@inheritDoc} + */ + /* @Override */ + public STATE onBodyPartReceived( final HttpResponseBodyPart content ) + throws Exception + { + try + { + fireTransferProgressed( content.getBodyPartBytes() ); + } + catch ( TransferCancelledException e ) + { + return STATE.ABORT; + } + catch ( Exception ex ) + { + if ( logger.isDebugEnabled() ) + { + logger.debug( "", ex ); + } + } + return STATE.CONTINUE; + } + + /** + * {@inheritDoc} + */ + /* @Override */ + public STATE onStatusReceived( final HttpResponseStatus status ) + throws Exception + { + this.status = status; + + if ( !TransferEvent.RequestType.PUT.equals( requestType ) ) + { + if ( status.getStatusCode() >= 200 && status.getStatusCode() < 300 ) + { + try + { + fireTransferStarted(); + } + catch ( TransferCancelledException e ) + { + return STATE.ABORT; + } + } + } + + return ( status.getStatusCode() == HttpURLConnection.HTTP_NOT_FOUND ? STATE.ABORT : STATE.CONTINUE ); + } + + /** + * {@inheritDoc} + */ + /* @Override */ + public STATE onHeadersReceived( final HttpResponseHeaders headers ) + throws Exception + { + this.headers = headers; + return STATE.CONTINUE; + } + + /** + * {@inheritDoc} + */ + /* @Override */ + public final Response onCompleted() + throws Exception + { + // The connection has timed out + if ( status == null ) + { + throw new TransferException( "Invalid AHC State. Response will possibly gets corrupted." ); + } + return onCompleted( httpClient.getProvider().prepareResponse( status, headers, + Collections.<HttpResponseBodyPart> emptyList() ) ); + } + + /** + * {@inheritDoc} + */ + /* @Override */ + public void onThrowable( Throwable t ) + { + exception.set( t ); + } + + /** + * Invoked once the HTTP response has been fully read. + * + * @param response The {@link com.ning.http.client.Response} + * @return Type of the value that will be returned by the associated {@link java.util.concurrent.Future} + */ + public Response onCompleted( Response response ) + throws Exception + { + if ( response != null && response.hasResponseStatus() && response.getStatusCode() >= HttpURLConnection.HTTP_OK + && response.getStatusCode() <= HttpURLConnection.HTTP_CREATED ) + { + fireTransferSucceeded( response ); + } + return response; + } + + void fireTransferProgressed( final byte[] buffer ) + throws TransferCancelledException + { + fireTransferProgressed( ByteBuffer.wrap( buffer ) ); + } + + void fireTransferProgressed( final ByteBuffer buffer ) + throws TransferCancelledException + { + final long bytesTransferred = byteTransfered.addAndGet( buffer.remaining() ); + + final TransferEvent transferEvent = new AsyncTransferEvent() + { + + public EventType getType() + { + return TransferEvent.EventType.PROGRESSED; + } + + public long getTransferredBytes() + { + return bytesTransferred; + } + + public ByteBuffer getDataBuffer() + { + return buffer.asReadOnlyBuffer(); + } + + public int getDataLength() + { + return buffer.remaining(); + } + + }; + + for ( Iterator<TransferListener> iter = listeners.iterator(); iter.hasNext(); ) + { + final TransferListener listener = iter.next(); + listener.transferProgressed( transferEvent ); + } + } + + void fireTransferSucceeded( final Response response ) + throws IOException + { + final long bytesTransferred = byteTransfered.get(); + + final TransferEvent transferEvent = new AsyncTransferEvent() + { + + public EventType getType() + { + return TransferEvent.EventType.SUCCEEDED; + } + + public long getTransferredBytes() + { + return bytesTransferred; + } + + }; + + for ( Iterator<TransferListener> iter = listeners.iterator(); iter.hasNext(); ) + { + final TransferListener listener = iter.next(); + listener.transferSucceeded( transferEvent ); + } + } + + void fireTransferFailed() + throws IOException + { + final long bytesTransferred = byteTransfered.get(); + + final TransferEvent transferEvent = new AsyncTransferEvent() + { + + public EventType getType() + { + return TransferEvent.EventType.FAILED; + } + + public long getTransferredBytes() + { + return bytesTransferred; + } + + }; + + for ( Iterator<TransferListener> iter = listeners.iterator(); iter.hasNext(); ) + { + final TransferListener listener = iter.next(); + listener.transferFailed( transferEvent ); + + } + } + + void fireTransferStarted() + throws TransferCancelledException + { + final TransferEvent transferEvent = new AsyncTransferEvent() + { + + public EventType getType() + { + return TransferEvent.EventType.STARTED; + } + + public long getTransferredBytes() + { + return 0; + } + + }; + + for ( Iterator<TransferListener> iter = listeners.iterator(); iter.hasNext(); ) + { + final TransferListener listener = iter.next(); + listener.transferStarted( transferEvent ); + } + } + + public boolean addTransferListener( TransferListener listener ) + { + if ( listener == null ) + { + return false; + } + return listeners.offer( listener ); + } + + public boolean removeTransferListener( TransferListener listener ) + { + if ( listener == null ) + { + return false; + } + return listeners.remove( listener ); + } + + protected HttpResponseStatus status() + { + return status; + } + + abstract class AsyncTransferEvent + implements TransferEvent + { + + public RequestType getRequestType() + { + return requestType; + } + + public TransferResource getResource() + { + return transferResource; + } + + public ByteBuffer getDataBuffer() + { + return null; + } + + public int getDataLength() + { + return 0; + } + + public Exception getException() + { + return ( Exception.class.isAssignableFrom( exception.get().getClass() ) ? Exception.class.cast( exception.get() ) + : new Exception( exception.get() ) ); + } + + @Override + public String toString() + { + return getRequestType() + " " + getType() + " " + getResource(); + } + + } + +} diff --git a/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/resources/OSGI-INF/l10n/bundle.properties b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/resources/OSGI-INF/l10n/bundle.properties new file mode 100644 index 00000000..75173c38 --- /dev/null +++ b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/resources/OSGI-INF/l10n/bundle.properties @@ -0,0 +1,2 @@ +Bundle-Vendor = Eclipse.org - m2e +Bundle-Name = Embedded Maven Runtime Bundle
\ No newline at end of file diff --git a/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/resources/about.html b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/resources/about.html new file mode 100644 index 00000000..2ec54b51 --- /dev/null +++ b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/resources/about.html @@ -0,0 +1,116 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> +<title>About</title> +</head> +<body lang="EN-US"> +<h2>About This Content</h2> + +<p>June, 6 2011</p> +<h3>License</h3> + +<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>. +For purposes of the EPL, "Program" will mean the Content.</p> + +<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p> + +<h3>Third Party Content</h3> + +<p> +The Content includes items that have been sourced from third parties as set out below. If you +did not receive this Content directly from the Eclipse Foundation, the following is provided +for informational purposes only, and you should look to the Redistributor’s license for +terms and conditions of use. +</p> + +<h4>Maven 3.0.2</h4> +<p> +The plug-in includes software developed by The Apache Software Foundation as part of the Maven project. +Your use of Maven 3.0.2 in binary code form contained in the plug-in is subject to the terms and conditions of the +The Apache Software License, Version 2.0 ("ASL"). +A copy of the ASL is available at <a href="http://maven.apache.org/license.html">http://maven.apache.org/license.html</a>. +(a local copy can be found <a href="about_files/LICENSE-2.0.txt">here</a>) +</p> +<p>The original binaries and source are available at the <a href="http://maven.org">Maven Central Repository</a>. + +<h4>Aether 1.11</h4> +<p> +The plug-in includes software developed by Sonatype, Inc. +Your use of Aether 1.11 in binary code form contained in the plug-in is subject to the terms and conditions of the +The Apache Software License, Version 2.0 ("ASL") or Eclipse Public License Version 1.0 ("EPL"). +A copy of the ASL is available at <a href="http://maven.apache.org/license.html">http://maven.apache.org/license.html</a>. +(a local copy can be found <a href="about_files/LICENSE-2.0.txt">here</a>) +</p> +<p>The original binaries are available at the <a href="http://maven.org">Maven Central Repository</a>. + + +<h4>Sisu 2.0.0 and Sisu Guice 2.9.4</h4> +<p> +The plug-in includes software developed by Sonatype, Inc. +Your use of Sisu 2.0.0 and Sisu Guice 2.9.4 in binary code form contained in the plug-in is subject to the terms and conditions of the +The Apache Software License, Version 2.0 ("ASL"). +A copy of the ASL is available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>. +(a local copy can be found <a href="about_files/LICENSE-2.0.txt">here</a>) +</p> +<p>The original binaries are available at the <a href="http://maven.org">Maven Central Repository</a>. + + + + +<h4>Sisu 2.0.0 and Sisu Guice 2.9.4</h4> +<p> +The plug-in includes software developed by Sonatype, Inc. +Your use of Sisu 2.0.0 and Sisu Guice 2.9.4 in binary code form contained in the plug-in is subject to the terms and conditions of the +The Apache Software License, Version 2.0 ("ASL"). +A copy of the ASL is available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>. +(a local copy can be found <a href="about_files/LICENSE-2.0.txt">here</a>) +</p> +<p>The original binaries are available at the <a href="http://maven.org">Maven Central Repository</a>. + + + +<h4>javax.inject 1.0</h4> +This plug-in includes the package "javax.inject" from the atinject project, which is +licensed under the Apache 2.0 license, available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>. +(a local copy can be found <a href="about_files/LICENSE-2.0.txt">here</a>) +</p> +<p>The source for the bundle is available from +the atinject website at <a + href="http://code.google.com/p/atinject/">http://code.google.com/p/atinject/</a>.</p> + + +<h4>Apache Commons Command Line Interface 1.2</h4> +<p> +The plug-in includes software developed by The Apache Software Foundation as part of the Apache Commons project. +Your use of Apache Commons Command Line Interface 1.2 in binary code form contained in the plug-in is subject to the terms and conditions of the +The Apache Software License, Version 2.0 ("ASL"). +A copy of the ASL is available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>. +(a local copy can be found <a href="about_files/LICENSE-2.0.txt">here</a>) +</p> +<p>The original binaries and source are available at the <a href="http://maven.org">Maven Central Repository</a>. + + + +<h4>Plexus Build API 0.0.7</h4> +<p> +The plug-in includes software developed by Sonatype, Inc. +Your use of Plexus Build API 0.0.7 in binary code form contained in the plug-in is subject to the terms and conditions of the +The Apache Software License, Version 2.0 ("ASL"). +A copy of the ASL is available at <a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>. +(a local copy can be found <a href="about_files/LICENSE-2.0.txt">here</a>) +</p> +<p>The original binaries are available at the <a href="http://maven.org">Maven Central Repository</a>. + + +</body> +</html>
\ No newline at end of file diff --git a/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/resources/about_files/LICENSE-2.0.txt b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/resources/about_files/LICENSE-2.0.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/resources/about_files/LICENSE-2.0.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. |