Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'm2e-maven-runtime/org.eclipse.m2e.maven.runtime/src')
-rw-r--r--m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/README8
-rw-r--r--m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java178
-rw-r--r--m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/DefaultSchedules.java99
-rw-r--r--m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java94
-rw-r--r--m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecycleExecutionPlanCalculator.java695
-rw-r--r--m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/internal/LifecycleExecutionPlanCalculator.java67
-rw-r--r--m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/lifecycle/internal/LifecycleTaskSegmentCalculator.java61
-rw-r--r--m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.java236
-rw-r--r--m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java718
-rw-r--r--m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/java/org/sonatype/aether/connector/async/CompletionHandler.java388
-rw-r--r--m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/resources/OSGI-INF/l10n/bundle.properties2
-rw-r--r--m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/resources/about.html116
-rw-r--r--m2e-maven-runtime/org.eclipse.m2e.maven.runtime/src/main/resources/about_files/LICENSE-2.0.txt202
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 (&quot;Content&quot;). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 (&quot;EPL&quot;). 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, &quot;Program&quot; 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 (&quot;Redistributor&quot;) 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&rsquo;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 (&quot;ASL&quot;).
+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 (&quot;ASL&quot;) or Eclipse Public License Version 1.0 (&quot;EPL&quot;).
+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 (&quot;ASL&quot;).
+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 (&quot;ASL&quot;).
+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 (&quot;ASL&quot;).
+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 (&quot;ASL&quot;).
+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.

Back to the top