diff --git a/maven-plugin-api/pom.xml b/maven-plugin-api/pom.xml
index e81dc04077..fa0eafcebd 100644
--- a/maven-plugin-api/pom.xml
+++ b/maven-plugin-api/pom.xml
@@ -37,4 +37,16 @@ under the License.
test
+
+
+
+ org.codehaus.modello
+ modello-maven-plugin
+
+ src/main/mdo/lifecycle.mdo
+ 1.0.0
+
+
+
+
diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/DuplicateMojoDescriptorException.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/DuplicateMojoDescriptorException.java
new file mode 100644
index 0000000000..26aeb9533e
--- /dev/null
+++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/DuplicateMojoDescriptorException.java
@@ -0,0 +1,31 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * 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.
+ */
+
+public class DuplicateMojoDescriptorException
+ extends InvalidPluginDescriptorException
+{
+
+ public DuplicateMojoDescriptorException( String goalPrefix, String goal, String existingImplementation, String newImplementation )
+ {
+ super( "Goal: " + goal + " already exists in the plugin descriptor for prefix: " + goalPrefix + "\nExisting implementation is: " + existingImplementation + "\nConflicting implementation is: " + newImplementation );
+ }
+
+}
diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/DuplicateParameterException.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/DuplicateParameterException.java
new file mode 100644
index 0000000000..4cad9b7c01
--- /dev/null
+++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/DuplicateParameterException.java
@@ -0,0 +1,31 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * 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.
+ */
+
+public class DuplicateParameterException
+ extends InvalidPluginDescriptorException
+{
+
+ public DuplicateParameterException( String message )
+ {
+ super( message );
+ }
+
+}
diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/InvalidParameterException.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/InvalidParameterException.java
new file mode 100644
index 0000000000..9988436e4a
--- /dev/null
+++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/InvalidParameterException.java
@@ -0,0 +1,39 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * 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.
+ */
+
+/**
+ * @author Jason van Zyl
+ * @version $Id: InvalidParameterException.java,v 1.1 2005/02/20 16:25:21
+ * jdcasey Exp $
+ */
+public class InvalidParameterException
+ extends InvalidPluginDescriptorException
+{
+ public InvalidParameterException( String element, int i )
+ {
+ super( "The " + element + " element in parameter # " + i + " is invalid. It cannot be null." );
+ }
+
+ public InvalidParameterException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+}
\ No newline at end of file
diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/InvalidPluginDescriptorException.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/InvalidPluginDescriptorException.java
new file mode 100644
index 0000000000..4b8e739772
--- /dev/null
+++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/InvalidPluginDescriptorException.java
@@ -0,0 +1,38 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * 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.codehaus.plexus.configuration.PlexusConfigurationException;
+
+public class InvalidPluginDescriptorException
+ extends PlexusConfigurationException
+{
+
+ public InvalidPluginDescriptorException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public InvalidPluginDescriptorException( String message )
+ {
+ super( message );
+ }
+
+}
diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/MojoDescriptor.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/MojoDescriptor.java
new file mode 100644
index 0000000000..1620ec6873
--- /dev/null
+++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/MojoDescriptor.java
@@ -0,0 +1,455 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * 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.plugin.Mojo;
+import org.codehaus.plexus.component.repository.ComponentDescriptor;
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The bean containing the mojo descriptor.
+ *
+ * @todo is there a need for the delegation of MavenMojoDescriptor to this? Why not just extend ComponentDescriptor here?
+ */
+public class MojoDescriptor
+ extends ComponentDescriptor
+ implements Cloneable
+{
+ public static String MAVEN_PLUGIN = "maven-plugin";
+
+ public static final String SINGLE_PASS_EXEC_STRATEGY = "once-per-session";
+
+ public static final String MULTI_PASS_EXEC_STRATEGY = "always";
+
+ private static final String DEFAULT_INSTANTIATION_STRATEGY = "per-lookup";
+
+ private static final String DEFAULT_LANGUAGE = "java";
+
+ private List parameters;
+
+ private Map parameterMap;
+
+ private String executionStrategy = SINGLE_PASS_EXEC_STRATEGY;
+
+ private String goal;
+
+ private String phase;
+
+ private String since;
+
+ private String executePhase;
+
+ private String executeGoal;
+
+ private String executeLifecycle;
+
+ private String deprecated;
+
+ private boolean aggregator = false;
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ private String dependencyResolutionRequired = null;
+
+ private boolean projectRequired = true;
+
+ private boolean onlineRequired = false;
+
+ private PlexusConfiguration mojoConfiguration;
+
+ private PluginDescriptor pluginDescriptor;
+
+ private boolean inheritedByDefault = true;
+
+ private boolean directInvocationOnly = false;
+
+ private boolean requiresReports = false;
+
+ public MojoDescriptor()
+ {
+ setInstantiationStrategy( DEFAULT_INSTANTIATION_STRATEGY );
+ setComponentFactory( DEFAULT_LANGUAGE );
+ }
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ public String getLanguage()
+ {
+ return getComponentFactory();
+ }
+
+ public void setLanguage( String language )
+ {
+ setComponentFactory( language );
+ }
+
+ public String getDeprecated()
+ {
+ return deprecated;
+ }
+
+ public void setDeprecated( String deprecated )
+ {
+ this.deprecated = deprecated;
+ }
+
+ public List getParameters()
+ {
+ return parameters;
+ }
+
+ public void setParameters( List parameters )
+ throws DuplicateParameterException
+ {
+ for ( Iterator it = parameters.iterator(); it.hasNext(); )
+ {
+ Parameter parameter = (Parameter) it.next();
+ addParameter( parameter );
+ }
+ }
+
+ public void addParameter( Parameter parameter )
+ throws DuplicateParameterException
+ {
+ if ( parameters != null && parameters.contains( parameter ) )
+ {
+ throw new DuplicateParameterException( parameter.getName() +
+ " has been declared multiple times in mojo with goal: " + getGoal() + " (implementation: " +
+ getImplementation() + ")" );
+ }
+ else
+ {
+ if ( parameters == null )
+ {
+ parameters = new LinkedList();
+ }
+
+ parameters.add( parameter );
+ }
+ }
+
+ public Map getParameterMap()
+ {
+ if ( parameterMap == null )
+ {
+ parameterMap = new HashMap();
+
+ if ( parameters != null )
+ {
+ for ( Iterator iterator = parameters.iterator(); iterator.hasNext(); )
+ {
+ Parameter pd = (Parameter) iterator.next();
+
+ parameterMap.put( pd.getName(), pd );
+ }
+ }
+ }
+
+ return parameterMap;
+ }
+
+ // ----------------------------------------------------------------------
+ // Dependency requirement
+ // ----------------------------------------------------------------------
+
+ public void setDependencyResolutionRequired( String requiresDependencyResolution )
+ {
+ this.dependencyResolutionRequired = requiresDependencyResolution;
+ }
+
+ public String isDependencyResolutionRequired()
+ {
+ return dependencyResolutionRequired;
+ }
+
+ // ----------------------------------------------------------------------
+ // Project requirement
+ // ----------------------------------------------------------------------
+
+ public void setProjectRequired( boolean requiresProject )
+ {
+ this.projectRequired = requiresProject;
+ }
+
+ public boolean isProjectRequired()
+ {
+ return projectRequired;
+ }
+
+ // ----------------------------------------------------------------------
+ // Online vs. Offline requirement
+ // ----------------------------------------------------------------------
+
+ public void setOnlineRequired( boolean requiresOnline )
+ {
+ this.onlineRequired = requiresOnline;
+ }
+
+ // blech! this isn't even intelligible as a method name. provided for
+ // consistency...
+ public boolean isOnlineRequired()
+ {
+ return onlineRequired;
+ }
+
+ // more english-friendly method...keep the code clean! :)
+ public boolean requiresOnline()
+ {
+ return onlineRequired;
+ }
+
+ public String getPhase()
+ {
+ return phase;
+ }
+
+ public void setPhase( String phase )
+ {
+ this.phase = phase;
+ }
+
+ public String getSince()
+ {
+ return since;
+ }
+
+ public void setSince( String since )
+ {
+ this.since = since;
+ }
+
+ public String getGoal()
+ {
+ return goal;
+ }
+
+ public void setGoal( String goal )
+ {
+ this.goal = goal;
+ }
+
+ public String getExecutePhase()
+ {
+ return executePhase;
+ }
+
+ public void setExecutePhase( String executePhase )
+ {
+ this.executePhase = executePhase;
+ }
+
+ public boolean alwaysExecute()
+ {
+ return MULTI_PASS_EXEC_STRATEGY.equals( executionStrategy );
+ }
+
+ public String getExecutionStrategy()
+ {
+ return executionStrategy;
+ }
+
+ public void setExecutionStrategy( String executionStrategy )
+ {
+ this.executionStrategy = executionStrategy;
+ }
+
+ public PlexusConfiguration getMojoConfiguration()
+ {
+ if ( mojoConfiguration == null )
+ {
+ mojoConfiguration = new XmlPlexusConfiguration( "configuration" );
+ }
+ return mojoConfiguration;
+ }
+
+ public void setMojoConfiguration( PlexusConfiguration mojoConfiguration )
+ {
+ this.mojoConfiguration = mojoConfiguration;
+ }
+
+ public String getRole()
+ {
+ return Mojo.ROLE;
+ }
+
+ public String getRoleHint()
+ {
+ return getId();
+ }
+
+ public String getId()
+ {
+ return getPluginDescriptor().getId() + ":" + getGoal();
+ }
+
+ public String getFullGoalName()
+ {
+ return getPluginDescriptor().getGoalPrefix() + ":" + getGoal();
+ }
+
+ public String getComponentType()
+ {
+ return MAVEN_PLUGIN;
+ }
+
+ public PluginDescriptor getPluginDescriptor()
+ {
+ return pluginDescriptor;
+ }
+
+ public void setPluginDescriptor( PluginDescriptor pluginDescriptor )
+ {
+ this.pluginDescriptor = pluginDescriptor;
+ }
+
+ public boolean isInheritedByDefault()
+ {
+ return inheritedByDefault;
+ }
+
+ public void setInheritedByDefault( boolean inheritedByDefault )
+ {
+ this.inheritedByDefault = inheritedByDefault;
+ }
+
+ public boolean equals( Object object )
+ {
+ if ( this == object )
+ {
+ return true;
+ }
+
+ if ( object instanceof MojoDescriptor )
+ {
+ MojoDescriptor other = (MojoDescriptor) object;
+
+ if ( !compareObjects( getPluginDescriptor(), other.getPluginDescriptor() ) )
+ {
+ return false;
+ }
+
+ if ( !compareObjects( getGoal(), other.getGoal() ) )
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ private boolean compareObjects( Object first, Object second )
+ {
+ if ( ( first == null && second != null ) || ( first != null && second == null ) )
+ {
+ return false;
+ }
+
+ if ( !first.equals( second ) )
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public int hashCode()
+ {
+ int result = 1;
+
+ String goal = getGoal();
+
+ if ( goal != null )
+ {
+ result += goal.hashCode();
+ }
+
+ PluginDescriptor pd = getPluginDescriptor();
+
+ if ( pd != null )
+ {
+ result -= pd.hashCode();
+ }
+
+ return result;
+ }
+
+ public String getExecuteLifecycle()
+ {
+ return executeLifecycle;
+ }
+
+ public void setExecuteLifecycle( String executeLifecycle )
+ {
+ this.executeLifecycle = executeLifecycle;
+ }
+
+ public void setAggregator( boolean aggregator )
+ {
+ this.aggregator = aggregator;
+ }
+
+ public boolean isAggregator()
+ {
+ return aggregator;
+ }
+
+ public boolean isDirectInvocationOnly()
+ {
+ return directInvocationOnly;
+ }
+
+ public void setDirectInvocationOnly( boolean directInvocationOnly )
+ {
+ this.directInvocationOnly = directInvocationOnly;
+ }
+
+ public boolean isRequiresReports()
+ {
+ return requiresReports;
+ }
+
+ public void setRequiresReports( boolean requiresReports )
+ {
+ this.requiresReports = requiresReports;
+ }
+
+ public void setExecuteGoal( String executeGoal )
+ {
+ this.executeGoal = executeGoal;
+ }
+
+ public String getExecuteGoal()
+ {
+ return executeGoal;
+ }
+}
diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Parameter.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Parameter.java
new file mode 100644
index 0000000000..ecb61f2cf0
--- /dev/null
+++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Parameter.java
@@ -0,0 +1,190 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * 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.
+ */
+
+/**
+ * @author Jason van Zyl
+ * @version $Id$
+ */
+public class Parameter
+{
+ private String alias;
+
+ private String name;
+
+ private String type;
+
+ private boolean required;
+
+ private boolean editable = true;
+
+ private String description;
+
+ private String expression;
+
+ private String deprecated;
+
+ private String defaultValue;
+
+ private String implementation;
+
+ private Requirement requirement;
+
+ private String since;
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName( String name )
+ {
+ this.name = name;
+ }
+
+ public String getType()
+ {
+ return type;
+ }
+
+ public void setType( String type )
+ {
+ this.type = type;
+ }
+
+ public boolean isRequired()
+ {
+ return required;
+ }
+
+ public void setRequired( boolean required )
+ {
+ this.required = required;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public void setDescription( String description )
+ {
+ this.description = description;
+ }
+
+ public String getExpression()
+ {
+ return expression;
+ }
+
+ public void setExpression( String expression )
+ {
+ this.expression = expression;
+ }
+
+ public String getDeprecated()
+ {
+ return deprecated;
+ }
+
+ public void setDeprecated( String deprecated )
+ {
+ this.deprecated = deprecated;
+ }
+
+ public int hashCode()
+ {
+ return name.hashCode();
+ }
+
+ public boolean equals( Object other )
+ {
+ return ( other instanceof Parameter ) && getName().equals( ( (Parameter) other ).getName() );
+ }
+
+ public String getAlias()
+ {
+ return alias;
+ }
+
+ public void setAlias( String alias )
+ {
+ this.alias = alias;
+ }
+
+ public boolean isEditable()
+ {
+ return editable;
+ }
+
+ public void setEditable( boolean editable )
+ {
+ this.editable = editable;
+ }
+
+ public void setDefaultValue( String defaultValue )
+ {
+ this.defaultValue = defaultValue;
+ }
+
+ public String getDefaultValue()
+ {
+ return defaultValue;
+ }
+
+ public String toString()
+ {
+ return "Mojo parameter [name: \'" + getName() + "\'; alias: \'" + getAlias() + "\']";
+ }
+
+ public Requirement getRequirement()
+ {
+ return requirement;
+ }
+
+ public void setRequirement( Requirement requirement )
+ {
+ this.requirement = requirement;
+ }
+
+ public String getImplementation()
+ {
+ return implementation;
+ }
+
+ public void setImplementation( String implementation )
+ {
+ this.implementation = implementation;
+ }
+
+ public String getSince()
+ {
+ return since;
+ }
+
+ public void setSince( String since )
+ {
+ this.since = since;
+ }
+}
diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java
new file mode 100644
index 0000000000..3663b1a0bb
--- /dev/null
+++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptor.java
@@ -0,0 +1,362 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * 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.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.plugin.lifecycle.Lifecycle;
+import org.apache.maven.plugin.lifecycle.LifecycleConfiguration;
+import org.apache.maven.plugin.lifecycle.io.xpp3.LifecycleMappingsXpp3Reader;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.component.repository.ComponentSetDescriptor;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Jason van Zyl
+ * @version $Id$
+ */
+public class PluginDescriptor
+ extends ComponentSetDescriptor
+{
+ private String groupId;
+
+ private String artifactId;
+
+ private String version;
+
+ private String goalPrefix;
+
+ private String source;
+
+ private boolean inheritedByDefault = true;
+
+ private List artifacts;
+
+ private Map lifecycleMappings;
+
+ private ClassRealm classRealm;
+
+ // calculated on-demand.
+ private Map artifactMap;
+
+ private Set introducedDependencyArtifacts;
+
+ private String name;
+
+ private String description;
+
+ private Artifact pluginArtifact;
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ public List getMojos()
+ {
+ return getComponents();
+ }
+
+ public void addMojo( MojoDescriptor mojoDescriptor )
+ throws DuplicateMojoDescriptorException
+ {
+ MojoDescriptor existing = null;
+ // this relies heavily on the equals() and hashCode() for ComponentDescriptor,
+ // which uses role:roleHint for identity...and roleHint == goalPrefix:goal.
+ // role does not vary for Mojos.
+ List mojos = getComponents();
+
+ if ( mojos != null && mojos.contains( mojoDescriptor ) )
+ {
+ int indexOf = mojos.indexOf( mojoDescriptor );
+
+ existing = (MojoDescriptor) mojos.get( indexOf );
+ }
+
+ if ( existing != null )
+ {
+ throw new DuplicateMojoDescriptorException( getGoalPrefix(), mojoDescriptor.getGoal(), existing
+ .getImplementation(), mojoDescriptor.getImplementation() );
+ }
+ else
+ {
+ addComponentDescriptor( mojoDescriptor );
+ }
+ }
+
+ public String getGroupId()
+ {
+ return groupId;
+ }
+
+ public void setGroupId( String groupId )
+ {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId()
+ {
+ return artifactId;
+ }
+
+ public void setArtifactId( String artifactId )
+ {
+ this.artifactId = artifactId;
+ }
+
+ // ----------------------------------------------------------------------
+ // Dependencies
+ // ----------------------------------------------------------------------
+
+ public static String constructPluginKey( String groupId, String artifactId, String version )
+ {
+ return groupId + ":" + artifactId + ":" + version;
+ }
+
+ public String getPluginLookupKey()
+ {
+ return groupId + ":" + artifactId;
+ }
+
+ public String getId()
+ {
+ return constructPluginKey( groupId, artifactId, version );
+ }
+
+ public static String getDefaultPluginArtifactId( String id )
+ {
+ return "maven-" + id + "-plugin";
+ }
+
+ public static String getDefaultPluginGroupId()
+ {
+ return "org.apache.maven.plugins";
+ }
+
+ /**
+ * Parse maven-...-plugin.
+ *
+ * @todo move to plugin-tools-api as a default only
+ */
+ public static String getGoalPrefixFromArtifactId( String artifactId )
+ {
+ if ( "maven-plugin-plugin".equals( artifactId ) )
+ {
+ return "plugin";
+ }
+ else
+ {
+ return artifactId.replaceAll( "-?maven-?", "" ).replaceAll( "-?plugin-?", "" );
+ }
+ }
+
+ public String getGoalPrefix()
+ {
+ return goalPrefix;
+ }
+
+ public void setGoalPrefix( String goalPrefix )
+ {
+ this.goalPrefix = goalPrefix;
+ }
+
+ public void setVersion( String version )
+ {
+ this.version = version;
+ }
+
+ public String getVersion()
+ {
+ return version;
+ }
+
+ public void setSource( String source )
+ {
+ this.source = source;
+ }
+
+ public String getSource()
+ {
+ return source;
+ }
+
+ public boolean isInheritedByDefault()
+ {
+ return inheritedByDefault;
+ }
+
+ public void setInheritedByDefault( boolean inheritedByDefault )
+ {
+ this.inheritedByDefault = inheritedByDefault;
+ }
+
+ public List getArtifacts()
+ {
+ return artifacts;
+ }
+
+ public void setArtifacts( List artifacts )
+ {
+ this.artifacts = artifacts;
+
+ // clear the calculated artifactMap
+ artifactMap = null;
+ }
+
+ public Map getArtifactMap()
+ {
+ if ( artifactMap == null )
+ {
+ artifactMap = ArtifactUtils.artifactMapByVersionlessId( getArtifacts() );
+ }
+
+ return artifactMap;
+ }
+
+ public boolean equals( Object object )
+ {
+ if ( this == object )
+ {
+ return true;
+ }
+
+ return getId().equals( ( (PluginDescriptor) object ).getId() );
+ }
+
+ public int hashCode()
+ {
+ return 10 + getId().hashCode();
+ }
+
+ public MojoDescriptor getMojo( String goal )
+ {
+ // TODO: could we use a map? Maybe if the parent did that for components too, as this is too vulnerable to
+ // changes above not being propogated to the map
+
+ MojoDescriptor mojoDescriptor = null;
+ for ( Iterator i = getMojos().iterator(); i.hasNext() && mojoDescriptor == null; )
+ {
+ MojoDescriptor desc = (MojoDescriptor) i.next();
+ if ( goal.equals( desc.getGoal() ) )
+ {
+ mojoDescriptor = desc;
+ }
+ }
+ return mojoDescriptor;
+ }
+
+ public Lifecycle getLifecycleMapping( String lifecycle )
+ throws IOException, XmlPullParserException
+ {
+ if ( lifecycleMappings == null )
+ {
+ LifecycleMappingsXpp3Reader reader = new LifecycleMappingsXpp3Reader();
+ InputStreamReader r = null;
+ LifecycleConfiguration config;
+
+ try
+ {
+ InputStream resourceAsStream = classRealm.getResourceAsStream( "/META-INF/maven/lifecycle.xml" );
+ if ( resourceAsStream == null )
+ {
+ throw new FileNotFoundException( "Unable to find /META-INF/maven/lifecycle.xml in the plugin" );
+ }
+ r = new InputStreamReader( resourceAsStream );
+ config = reader.read( r, true );
+ }
+ finally
+ {
+ IOUtil.close( r );
+ }
+
+ Map map = new HashMap();
+
+ for ( Iterator i = config.getLifecycles().iterator(); i.hasNext(); )
+ {
+ Lifecycle l = (Lifecycle) i.next();
+ map.put( l.getId(), l );
+ }
+
+ lifecycleMappings = map;
+ }
+ return (Lifecycle) lifecycleMappings.get( lifecycle );
+ }
+
+ public void setClassRealm( ClassRealm classRealm )
+ {
+ this.classRealm = classRealm;
+ }
+
+ public ClassRealm getClassRealm()
+ {
+ return classRealm;
+ }
+
+ public void setIntroducedDependencyArtifacts( Set introducedDependencyArtifacts )
+ {
+ this.introducedDependencyArtifacts = introducedDependencyArtifacts;
+ }
+
+ public Set getIntroducedDependencyArtifacts()
+ {
+ return introducedDependencyArtifacts != null ? introducedDependencyArtifacts : Collections.EMPTY_SET;
+ }
+
+ public void setName( String name )
+ {
+ this.name = name;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setDescription( String description )
+ {
+ this.description = description;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public Artifact getPluginArtifact()
+ {
+ return pluginArtifact;
+ }
+
+ public void setPluginArtifact( Artifact pluginArtifact )
+ {
+ this.pluginArtifact = pluginArtifact;
+ }
+}
diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilder.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilder.java
new file mode 100644
index 0000000000..dec99a6710
--- /dev/null
+++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/PluginDescriptorBuilder.java
@@ -0,0 +1,341 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * 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.codehaus.plexus.component.repository.ComponentDependency;
+import org.codehaus.plexus.component.repository.ComponentRequirement;
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+import org.codehaus.plexus.configuration.PlexusConfigurationException;
+import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
+import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Jason van Zyl
+ * @version $Id$
+ */
+public class PluginDescriptorBuilder
+{
+ public PluginDescriptor build( Reader reader )
+ throws PlexusConfigurationException
+ {
+ return build( reader, null );
+ }
+
+ public PluginDescriptor build( Reader reader, String source )
+ throws PlexusConfigurationException
+ {
+ PlexusConfiguration c = buildConfiguration( reader );
+
+ PluginDescriptor pluginDescriptor = new PluginDescriptor();
+
+ pluginDescriptor.setSource( source );
+ pluginDescriptor.setGroupId( c.getChild( "groupId" ).getValue() );
+ pluginDescriptor.setArtifactId( c.getChild( "artifactId" ).getValue() );
+ pluginDescriptor.setVersion( c.getChild( "version" ).getValue() );
+ pluginDescriptor.setGoalPrefix( c.getChild( "goalPrefix" ).getValue() );
+
+ pluginDescriptor.setName( c.getChild( "name" ).getValue() );
+ pluginDescriptor.setDescription( c.getChild( "description" ).getValue() );
+
+ String isolatedRealm = c.getChild( "isolatedRealm" ).getValue();
+
+ if ( isolatedRealm != null )
+ {
+ pluginDescriptor.setIsolatedRealm( Boolean.valueOf( isolatedRealm ).booleanValue() );
+ }
+
+ String inheritedByDefault = c.getChild( "inheritedByDefault" ).getValue();
+
+ if ( inheritedByDefault != null )
+ {
+ pluginDescriptor.setInheritedByDefault( Boolean.valueOf( inheritedByDefault ).booleanValue() );
+ }
+
+ // ----------------------------------------------------------------------
+ // Components
+ // ----------------------------------------------------------------------
+
+ PlexusConfiguration[] mojoConfigurations = c.getChild( "mojos" ).getChildren( "mojo" );
+
+ for ( int i = 0; i < mojoConfigurations.length; i++ )
+ {
+ PlexusConfiguration component = mojoConfigurations[i];
+
+ MojoDescriptor mojoDescriptor = buildComponentDescriptor( component, pluginDescriptor );
+
+ pluginDescriptor.addMojo( mojoDescriptor );
+ }
+
+ // ----------------------------------------------------------------------
+ // Dependencies
+ // ----------------------------------------------------------------------
+
+ PlexusConfiguration[] dependencyConfigurations = c.getChild( "dependencies" ).getChildren( "dependency" );
+
+ List dependencies = new ArrayList();
+
+ for ( int i = 0; i < dependencyConfigurations.length; i++ )
+ {
+ PlexusConfiguration d = dependencyConfigurations[i];
+
+ ComponentDependency cd = new ComponentDependency();
+
+ cd.setArtifactId( d.getChild( "artifactId" ).getValue() );
+
+ cd.setGroupId( d.getChild( "groupId" ).getValue() );
+
+ cd.setType( d.getChild( "type" ).getValue() );
+
+ cd.setVersion( d.getChild( "version" ).getValue() );
+
+ dependencies.add( cd );
+ }
+
+ pluginDescriptor.setDependencies( dependencies );
+
+ return pluginDescriptor;
+ }
+
+ public MojoDescriptor buildComponentDescriptor( PlexusConfiguration c, PluginDescriptor pluginDescriptor )
+ throws PlexusConfigurationException
+ {
+ MojoDescriptor mojo = new MojoDescriptor();
+ mojo.setPluginDescriptor( pluginDescriptor );
+
+ mojo.setGoal( c.getChild( "goal" ).getValue() );
+
+ mojo.setImplementation( c.getChild( "implementation" ).getValue() );
+
+ PlexusConfiguration langConfig = c.getChild( "language" );
+
+ if ( langConfig != null )
+ {
+ mojo.setLanguage( langConfig.getValue() );
+ }
+
+ PlexusConfiguration configuratorConfig = c.getChild( "configurator" );
+
+ if ( configuratorConfig != null )
+ {
+ mojo.setComponentConfigurator( configuratorConfig.getValue() );
+ }
+
+ PlexusConfiguration composerConfig = c.getChild( "composer" );
+
+ if ( composerConfig != null )
+ {
+ mojo.setComponentComposer( composerConfig.getValue() );
+ }
+
+ String since = c.getChild( "since" ).getValue();
+
+ if ( since != null )
+ {
+ mojo.setSince( since );
+ }
+
+ String phase = c.getChild( "phase" ).getValue();
+
+ if ( phase != null )
+ {
+ mojo.setPhase( phase );
+ }
+
+ String executePhase = c.getChild( "executePhase" ).getValue();
+
+ if ( executePhase != null )
+ {
+ mojo.setExecutePhase( executePhase );
+ }
+
+ String executeMojo = c.getChild( "executeGoal" ).getValue();
+
+ if ( executeMojo != null )
+ {
+ mojo.setExecuteGoal( executeMojo );
+ }
+
+ String executeLifecycle = c.getChild( "executeLifecycle" ).getValue();
+
+ if ( executeLifecycle != null )
+ {
+ mojo.setExecuteLifecycle( executeLifecycle );
+ }
+
+ mojo.setInstantiationStrategy( c.getChild( "instantiationStrategy" ).getValue() );
+
+ mojo.setDescription( c.getChild( "description" ).getValue() );
+
+ String dependencyResolution = c.getChild( "requiresDependencyResolution" ).getValue();
+
+ if ( dependencyResolution != null )
+ {
+ mojo.setDependencyResolutionRequired( dependencyResolution );
+ }
+
+ String directInvocationOnly = c.getChild( "requiresDirectInvocation" ).getValue();
+
+ if ( directInvocationOnly != null )
+ {
+ mojo.setDirectInvocationOnly( Boolean.valueOf( directInvocationOnly ).booleanValue() );
+ }
+
+ String requiresProject = c.getChild( "requiresProject" ).getValue();
+
+ if ( requiresProject != null )
+ {
+ mojo.setProjectRequired( Boolean.valueOf( requiresProject ).booleanValue() );
+ }
+
+ String requiresReports = c.getChild( "requiresReports" ).getValue();
+
+ if ( requiresReports != null )
+ {
+ mojo.setRequiresReports( Boolean.valueOf( requiresReports ).booleanValue() );
+ }
+
+ String aggregator = c.getChild( "aggregator" ).getValue();
+
+ if ( aggregator != null )
+ {
+ mojo.setAggregator( Boolean.valueOf( aggregator ).booleanValue() );
+ }
+
+ String requiresOnline = c.getChild( "requiresOnline" ).getValue();
+
+ if ( requiresOnline != null )
+ {
+ mojo.setOnlineRequired( Boolean.valueOf( requiresOnline ).booleanValue() );
+ }
+
+ String inheritedByDefault = c.getChild( "inheritedByDefault" ).getValue();
+
+ if ( inheritedByDefault != null )
+ {
+ mojo.setInheritedByDefault( Boolean.valueOf( inheritedByDefault ).booleanValue() );
+ }
+
+ // ----------------------------------------------------------------------
+ // Parameters
+ // ----------------------------------------------------------------------
+
+ PlexusConfiguration[] parameterConfigurations = c.getChild( "parameters" ).getChildren( "parameter" );
+
+ List parameters = new ArrayList();
+
+ for ( int i = 0; i < parameterConfigurations.length; i++ )
+ {
+ PlexusConfiguration d = parameterConfigurations[i];
+
+ Parameter parameter = new Parameter();
+
+ parameter.setName( d.getChild( "name" ).getValue() );
+
+ parameter.setAlias( d.getChild( "alias" ).getValue() );
+
+ parameter.setType( d.getChild( "type" ).getValue() );
+
+ String required = d.getChild( "required" ).getValue();
+
+ parameter.setRequired( Boolean.valueOf( required ).booleanValue() );
+
+ PlexusConfiguration editableConfig = d.getChild( "editable" );
+
+ // we need the null check for pre-build legacy plugins...
+ if ( editableConfig != null )
+ {
+ String editable = d.getChild( "editable" ).getValue();
+
+ parameter.setEditable( editable == null || Boolean.valueOf( editable ).booleanValue() );
+ }
+
+ parameter.setDescription( d.getChild( "description" ).getValue() );
+
+ parameter.setDeprecated( d.getChild( "deprecated" ).getValue() );
+
+ parameter.setImplementation( d.getChild( "implementation" ).getValue() );
+
+ parameters.add( parameter );
+ }
+
+ mojo.setParameters( parameters );
+
+ // TODO: this should not need to be handed off...
+
+ // ----------------------------------------------------------------------
+ // Configuration
+ // ----------------------------------------------------------------------
+
+ mojo.setMojoConfiguration( c.getChild( "configuration" ) );
+
+ // TODO: Go back to this when we get the container ready to configure mojos...
+ // mojo.setConfiguration( c.getChild( "configuration" ) );
+
+ // ----------------------------------------------------------------------
+ // Requirements
+ // ----------------------------------------------------------------------
+
+ PlexusConfiguration[] requirements = c.getChild( "requirements" ).getChildren( "requirement" );
+
+ for ( int i = 0; i < requirements.length; i++ )
+ {
+ PlexusConfiguration requirement = requirements[i];
+
+ ComponentRequirement cr = new ComponentRequirement();
+
+ cr.setRole( requirement.getChild( "role" ).getValue() );
+
+ cr.setRoleHint( requirement.getChild( "role-hint" ).getValue() );
+
+ cr.setFieldName( requirement.getChild( "field-name" ).getValue() );
+
+ mojo.addRequirement( cr );
+ }
+
+ return mojo;
+ }
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ public PlexusConfiguration buildConfiguration( Reader configuration )
+ throws PlexusConfigurationException
+ {
+ try
+ {
+ return new XmlPlexusConfiguration( Xpp3DomBuilder.build( configuration ) );
+ }
+ catch ( IOException e )
+ {
+ throw new PlexusConfigurationException( "Error creating configuration", e );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new PlexusConfigurationException( "Error creating configuration", e );
+ }
+ }
+}
diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Requirement.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Requirement.java
new file mode 100644
index 0000000000..9306408c0a
--- /dev/null
+++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/descriptor/Requirement.java
@@ -0,0 +1,55 @@
+package org.apache.maven.plugin.descriptor;
+
+/*
+ * 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.
+ */
+
+/**
+ * Describes a component requirement.
+ *
+ * @author Brett Porter
+ * @version $Id$
+ */
+public class Requirement
+{
+ private final String role;
+
+ private final String roleHint;
+
+ public Requirement( String role )
+ {
+ this.role = role;
+ this.roleHint = null;
+ }
+
+ public Requirement( String role, String roleHint )
+ {
+ this.role = role;
+ this.roleHint = roleHint;
+ }
+
+ public String getRole()
+ {
+ return role;
+ }
+
+ public String getRoleHint()
+ {
+ return roleHint;
+ }
+}
diff --git a/maven-plugin-api/src/main/mdo/lifecycle.mdo b/maven-plugin-api/src/main/mdo/lifecycle.mdo
new file mode 100644
index 0000000000..c70b57aa25
--- /dev/null
+++ b/maven-plugin-api/src/main/mdo/lifecycle.mdo
@@ -0,0 +1,125 @@
+
+
+
+ lifecycle-mappings
+ LifecycleMappings
+
+
+
+ package
+ org.apache.maven.plugin.lifecycle
+
+
+
+
+ LifecycleConfiguration
+ 1.0.0
+ Root element of the lifecycle.xml file.
+
+
+ lifecycles
+ 1.0.0
+
+ Lifecycle
+ *
+
+
+
+
+
+ Lifecycle
+ 1.0.0
+
+
+
+ id
+ true
+ 1.0.0
+ String
+ The ID of this lifecycle, for identification in the mojo descriptor.
+
+
+ phases
+ 1.0.0
+ The phase mappings for this lifecycle.
+
+ Phase
+ *
+
+
+
+
+
+ Phase
+ 1.0.0
+ A phase mapping definition.
+
+
+ id
+ true
+ 1.0.0
+ String
+ The ID of this phase, eg <code>generate-sources</code>.
+
+
+ executions
+ 1.0.0
+ The goals to execute within the phase.
+
+ Execution
+ *
+
+
+
+ configuration
+ 1.0.0
+ DOM
+ Configuration to pass to all goals run in this phase.
+
+
+
+
+ Execution
+ 1.0.0
+ A set of goals to execute.
+
+
+ configuration
+ 1.0.0
+ DOM
+ Configuration to pass to the goals.
+
+
+ goals
+ 1.0.0
+ The goals to execute.
+
+ String
+ *
+
+
+
+
+
+
diff --git a/maven-plugin-api/src/test/java/org/apache/maven/plugin/lifecycle/LifecycleXpp3ReaderTest.java b/maven-plugin-api/src/test/java/org/apache/maven/plugin/lifecycle/LifecycleXpp3ReaderTest.java
new file mode 100644
index 0000000000..5f393c78e7
--- /dev/null
+++ b/maven-plugin-api/src/test/java/org/apache/maven/plugin/lifecycle/LifecycleXpp3ReaderTest.java
@@ -0,0 +1,57 @@
+package org.apache.maven.plugin.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 junit.framework.TestCase;
+import org.apache.maven.plugin.lifecycle.io.xpp3.LifecycleMappingsXpp3Reader;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+/**
+ * Test the lifecycle reader.
+ *
+ * @author Brett Porter
+ * @version $Id$
+ */
+public class LifecycleXpp3ReaderTest
+ extends TestCase
+{
+ public void testLifecycleReader()
+ throws IOException, XmlPullParserException
+ {
+ LifecycleMappingsXpp3Reader reader = new LifecycleMappingsXpp3Reader();
+ LifecycleConfiguration config = reader.read( new InputStreamReader( getClass().getResourceAsStream( "/lifecycle.xml" ) ) );
+ assertEquals( "check number of lifecycles", 1, config.getLifecycles().size() );
+ Lifecycle l = (Lifecycle) config.getLifecycles().iterator().next();
+ assertEquals( "check id", "clover", l.getId() );
+ assertEquals( "check number of phases", 1, l.getPhases().size() );
+ Phase p = (Phase) l.getPhases().iterator().next();
+ assertEquals( "check id", "generate-sources", p.getId() );
+ assertEquals( "check number of executions", 1, p.getExecutions().size() );
+ Execution e = (Execution) p.getExecutions().iterator().next();
+ assertEquals( "check configuration", "true", ((Xpp3Dom) e.getConfiguration()).getChild( "debug" ).getValue() );
+ assertEquals( "check number of goals", 1, e.getGoals().size() );
+ String g = (String) e.getGoals().iterator().next();
+ assertEquals( "check goal", "clover:compiler", g );
+ }
+}
diff --git a/maven-plugin-api/src/test/resources/lifecycle.xml b/maven-plugin-api/src/test/resources/lifecycle.xml
new file mode 100644
index 0000000000..ebec589255
--- /dev/null
+++ b/maven-plugin-api/src/test/resources/lifecycle.xml
@@ -0,0 +1,39 @@
+
+
+
+
+ clover
+
+
+ generate-sources
+
+
+
+ true
+
+
+ clover:compiler
+
+
+
+
+
+
+