![JAR search and dependency download from the Maven repository](/logo.png)
org.codehaus.mojo.versions.DisplayPluginUpdatesMojo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of versions-maven-plugin Show documentation
Show all versions of versions-maven-plugin Show documentation
Versions Plugin for Maven 2. The Versions Plugin updates the versions of components in the POM.
The newest version!
package org.codehaus.mojo.versions;
/*
* 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.BuildFailureException;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.RuntimeInformation;
import org.apache.maven.lifecycle.Lifecycle;
import org.apache.maven.lifecycle.LifecycleExecutionException;
import org.apache.maven.lifecycle.LifecycleExecutor;
import org.apache.maven.lifecycle.mapping.LifecycleMapping;
import org.apache.maven.model.*;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.apache.maven.plugin.*;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.version.PluginVersionNotFoundException;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.project.DefaultProjectBuilderConfiguration;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.interpolation.ModelInterpolationException;
import org.apache.maven.project.interpolation.ModelInterpolator;
import org.apache.maven.settings.Settings;
import org.codehaus.mojo.versions.api.ArtifactVersions;
import org.codehaus.mojo.versions.api.PomHelper;
import org.codehaus.mojo.versions.ordering.MavenVersionComparator;
import org.codehaus.mojo.versions.report.ArtifactUpdate;
import org.codehaus.mojo.versions.report.DisplayPluginUpdatesReport;
import org.codehaus.mojo.versions.report.IncompatibleParentAndProjectMavenVersion;
import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader;
import org.codehaus.mojo.versions.utils.ObjectToXmlWriter;
import org.codehaus.mojo.versions.utils.PluginComparator;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.*;
import java.util.regex.Pattern;
/**
* Displays all plugins that have newer versions available.
*
* @author Stephen Connolly
* @goal display-plugin-updates
* @requiresProject true
* @requiresDirectInvocation false
* @since 1.0-alpha-1
*/
public class DisplayPluginUpdatesMojo
extends AbstractVersionsUpdaterMojo
{
// ------------------------------ FIELDS ------------------------------
/**
* The width to pad warn messages.
*
* @since 1.0-alpha-1
*/
private static final int WARN_PAD_SIZE = 65;
/**
* The width to pad info messages.
*
* @since 1.0-alpha-1
*/
private static final int INFO_PAD_SIZE = 68;
/**
* String to flag a plugin version being forced by the super-pom.
*
* @since 1.0-alpha-1
*/
private static final String FROM_SUPER_POM = "(from super-pom) ";
/**
* @component
* @since 1.0-alpha-1
*/
private LifecycleExecutor lifecycleExecutor;
/**
* @component
* @since 1.0-alpha-3
*/
private ModelInterpolator modelInterpolator;
/**
* The plugin manager.
*
* @component
* @since 1.0-alpha-1
*/
private PluginManager pluginManager;
/**
* @component
* @since 1.3
*/
private RuntimeInformation runtimeInformation;
private DisplayPluginUpdatesReport report =new DisplayPluginUpdatesReport();
/**
* file to write xml report to
*
* @parameter expression="${xmlReport}" defaultValue="null"
*/
private File xmlReport;
// --------------------- GETTER / SETTER METHODS ---------------------
public void setXmlReport(File xmlReport) {
this.xmlReport = xmlReport;
}
/**
* Returns the pluginManagement section of the super-pom.
*
* @return Returns the pluginManagement section of the super-pom.
* @throws MojoExecutionException when things go wrong.
*/
private Map getSuperPomPluginManagement()
throws MojoExecutionException
{
if ( new DefaultArtifactVersion( "3.0" ).compareTo( runtimeInformation.getApplicationVersion() ) <= 0 )
{
getLog().debug( "Using Maven 3.x strategy to determine superpom defined plugins" );
try
{
Method getPluginsBoundByDefaultToAllLifecycles =
LifecycleExecutor.class.getMethod( "getPluginsBoundByDefaultToAllLifecycles",
new Class[]{ String.class } );
Set plugins = (Set) getPluginsBoundByDefaultToAllLifecycles.invoke( lifecycleExecutor,
new Object[]{
getProject().getPackaging() } );
// we need to provide a copy with the version blanked out so that inferring from super-pom
// works as for 2.x as 3.x fills in the version on us!
Map result = new LinkedHashMap( plugins.size() );
for ( Plugin plugin : plugins )
{
result.put( getPluginCoords( plugin ), getPluginVersion( plugin ) );
}
URL superPom = getClass().getClassLoader().getResource( "org/apache/maven/model/pom-4.0.0.xml" );
if ( superPom != null )
{
try
{
Reader reader = ReaderFactory.newXmlReader( superPom );
try
{
StringBuilder buf = new StringBuilder( IOUtil.toString( reader ) );
ModifiedPomXMLEventReader pom = newModifiedPomXER( buf );
Pattern pathRegex = Pattern.compile(
"/project(/profiles/profile)?" + "((/build(/pluginManagement)?)|(/reporting))"
+ "/plugins/plugin" );
Stack pathStack = new Stack();
StackState curState = null;
while ( pom.hasNext() )
{
XMLEvent event = pom.nextEvent();
if ( event.isStartDocument() )
{
curState = new StackState( "" );
pathStack.clear();
}
else if ( event.isStartElement() )
{
String elementName = event.asStartElement().getName().getLocalPart();
if ( curState != null && pathRegex.matcher( curState.path ).matches() )
{
if ( "groupId".equals( elementName ) )
{
curState.groupId = pom.getElementText().trim();
continue;
}
else if ( "artifactId".equals( elementName ) )
{
curState.artifactId = pom.getElementText().trim();
continue;
}
else if ( "version".equals( elementName ) )
{
curState.version = pom.getElementText().trim();
continue;
}
}
pathStack.push( curState );
curState = new StackState( curState.path + "/" + elementName );
}
else if ( event.isEndElement() )
{
if ( curState != null && pathRegex.matcher( curState.path ).matches() )
{
if ( curState.artifactId != null )
{
Plugin plugin = new Plugin();
plugin.setArtifactId( curState.artifactId );
plugin.setGroupId( curState.groupId == null
? PomHelper.APACHE_MAVEN_PLUGINS_GROUPID
: curState.groupId );
plugin.setVersion( curState.version );
if ( !result.containsKey( getPluginCoords( plugin ) ) )
{
result.put( getPluginCoords( plugin ), getPluginVersion( plugin ) );
}
}
}
curState = pathStack.pop();
}
}
}
finally
{
IOUtil.close( reader );
}
}
catch ( IOException e )
{
// ignore
}
catch ( XMLStreamException e )
{
// ignore
}
}
return result;
}
catch ( NoSuchMethodException e1 )
{
// no much we can do here
}
catch ( InvocationTargetException e1 )
{
// no much we can do here
}
catch ( IllegalAccessException e1 )
{
// no much we can do here
}
}
getLog().debug( "Using Maven 2.x strategy to determine superpom defined plugins" );
Map superPomPluginManagement = new HashMap();
try
{
MavenProject superProject =
projectBuilder.buildStandaloneSuperProject( new DefaultProjectBuilderConfiguration() );
superPomPluginManagement.putAll( getPluginManagement( superProject.getOriginalModel() ) );
}
catch ( ProjectBuildingException e )
{
throw new MojoExecutionException( "Could not determine the super pom.xml", e );
}
return superPomPluginManagement;
}
/**
* Gets the plugin management plugins of a specific project.
*
* @param model the model to get the plugin management plugins from.
* @return The map of effective plugin versions keyed by coordinates.
* @since 1.0-alpha-1
*/
private Map getPluginManagement( Model model )
{
// we want only those parts of pluginManagement that are defined in this project
Map pluginManagement = new HashMap();
try
{
for ( Plugin plugin : model.getBuild().getPluginManagement().getPlugins() )
{
String coord = getPluginCoords( plugin );
String version = getPluginVersion( plugin );
if ( version != null )
{
pluginManagement.put( coord, version );
}
}
}
catch ( NullPointerException e )
{
// guess there are no plugins here
}
try
{
for ( Profile profile : model.getProfiles() )
{
try
{
for ( Plugin plugin : profile.getBuild().getPluginManagement().getPlugins() )
{
String coord = getPluginCoords( plugin );
String version = getPluginVersion( plugin );
if ( version != null )
{
pluginManagement.put( coord, version );
}
}
}
catch ( NullPointerException e )
{
// guess there are no plugins here
}
}
}
catch ( NullPointerException e )
{
// guess there are no profiles here
}
return pluginManagement;
}
// ------------------------ INTERFACE METHODS ------------------------
// --------------------- Interface Mojo ---------------------
/**
* @throws MojoExecutionException when things go wrong
* @throws MojoFailureException when things go wrong in a very bad way
* @see AbstractVersionsUpdaterMojo#execute()
* @since 1.0-alpha-1
*/
public void execute()
throws MojoExecutionException, MojoFailureException
{
Set pluginsWithVersionsSpecified;
try
{
pluginsWithVersionsSpecified = findPluginsWithVersionsSpecified( getProject() );
}
catch ( XMLStreamException e )
{
throw new MojoExecutionException( e.getMessage(), e );
}
catch ( IOException e )
{
throw new MojoExecutionException( e.getMessage(), e );
}
Map superPomPluginManagement = getSuperPomPluginManagement();
getLog().debug( "superPom plugins = " + superPomPluginManagement );
Map parentPluginManagement = new HashMap();
Map parentBuildPlugins = new HashMap();
Map parentReportPlugins = new HashMap();
List parents = getParentProjects( getProject() );
for ( MavenProject parentProject : parents )
{
getLog().debug(
"Processing parent: " + parentProject.getGroupId() + ":" + parentProject.getArtifactId() + ":"
+ parentProject.getVersion() + " -> " + parentProject.getFile() );
StringWriter writer = new StringWriter();
boolean havePom = false;
Model interpolatedModel;
try
{
Model originalModel = parentProject.getOriginalModel();
if ( originalModel == null )
{
getLog().warn( "project.getOriginalModel()==null for " + parentProject.getGroupId() + ":"
+ parentProject.getArtifactId() + ":" + parentProject.getVersion()
+ " is null, substituting project.getModel()" );
originalModel = parentProject.getModel();
}
try
{
new MavenXpp3Writer().write( writer, originalModel );
writer.close();
havePom = true;
}
catch ( IOException e )
{
// ignore
}
interpolatedModel = modelInterpolator.interpolate( originalModel, null,
new DefaultProjectBuilderConfiguration().setExecutionProperties(
getProject().getProperties() ), false );
}
catch ( ModelInterpolationException e )
{
throw new MojoExecutionException( e.getMessage(), e );
}
if ( havePom )
{
try
{
Set withVersionSpecified =
findPluginsWithVersionsSpecified( new StringBuilder( writer.toString() ) );
Map map = getPluginManagement( interpolatedModel );
map.keySet().retainAll( withVersionSpecified );
parentPluginManagement.putAll( map );
map = getBuildPlugins( interpolatedModel, true );
map.keySet().retainAll( withVersionSpecified );
parentPluginManagement.putAll( map );
map = getReportPlugins( interpolatedModel, true );
map.keySet().retainAll( withVersionSpecified );
parentPluginManagement.putAll( map );
}
catch ( IOException e )
{
throw new MojoExecutionException( e.getMessage(), e );
}
catch ( XMLStreamException e )
{
throw new MojoExecutionException( e.getMessage(), e );
}
}
else
{
parentPluginManagement.putAll( getPluginManagement( interpolatedModel ) );
parentPluginManagement.putAll( getBuildPlugins( interpolatedModel, true ) );
parentPluginManagement.putAll( getReportPlugins( interpolatedModel, true ) );
}
}
Set plugins = getProjectPlugins( superPomPluginManagement, parentPluginManagement, parentBuildPlugins,
parentReportPlugins, pluginsWithVersionsSpecified );
List updates = new ArrayList();
List lockdowns = new ArrayList();
Map> upgrades =
new TreeMap>( new MavenVersionComparator() );
ArtifactVersion curMavenVersion = runtimeInformation.getApplicationVersion();
ArtifactVersion specMavenVersion = new DefaultArtifactVersion( getRequiredMavenVersion( getProject(), "2.0" ) );
ArtifactVersion minMavenVersion = null;
boolean superPomDrivingMinVersion = false;
Iterator i = plugins.iterator();
while ( i.hasNext() )
{
Object plugin = i.next();
String groupId = getPluginGroupId( plugin );
String artifactId = getPluginArtifactId( plugin );
String version = getPluginVersion( plugin );
String coords = ArtifactUtils.versionlessKey( groupId, artifactId );
if ( version == null )
{
version = parentPluginManagement.get( coords );
}
getLog().debug(
new StringBuilder().append( "Checking " ).append( coords ).append( " for updates newer than " ).append(
version ).toString() );
String effectiveVersion = version;
VersionRange versionRange;
boolean unspecified = version == null;
try
{
versionRange = unspecified
? VersionRange.createFromVersionSpec( "[0,)" )
: VersionRange.createFromVersionSpec( version );
}
catch ( InvalidVersionSpecificationException e )
{
throw new MojoExecutionException( "Invalid version range specification: " + version, e );
}
Artifact artifact = artifactFactory.createPluginArtifact( groupId, artifactId, versionRange );
ArtifactVersion artifactVersion = null;
try
{
// now we want to find the newest version that is compatible with the invoking version of Maven
ArtifactVersions artifactVersions = getHelper().lookupArtifactVersions( artifact, true );
ArtifactVersion[] newerVersions =
artifactVersions.getVersions( Boolean.TRUE.equals( this.allowSnapshots ) );
ArtifactVersion minRequires = null;
for ( int j = newerVersions.length - 1; j >= 0; j-- )
{
Artifact probe = artifactFactory.createDependencyArtifact( groupId, artifactId,
VersionRange.createFromVersion(
newerVersions[j].toString() ), "pom",
null, "runtime" );
try
{
getHelper().resolveArtifact( probe, true );
MavenProject mavenProject =
projectBuilder.buildFromRepository( probe, remotePluginRepositories, localRepository );
ArtifactVersion requires =
new DefaultArtifactVersion( getRequiredMavenVersion( mavenProject, "2.0" ) );
if ( specMavenVersion.compareTo( requires ) >= 0 && artifactVersion == null )
{
artifactVersion = newerVersions[j];
}
if ( effectiveVersion == null && curMavenVersion.compareTo( requires ) >= 0 )
{
// version was unspecified, current version of maven thinks it should use this
effectiveVersion = newerVersions[j].toString();
}
if ( artifactVersion != null && effectiveVersion != null )
{
// no need to look at any older versions.
break;
}
if ( minRequires == null || minRequires.compareTo( requires ) > 0 )
{
Map upgradePlugins = upgrades.get( requires );
if ( upgradePlugins == null )
{
upgrades.put( requires, upgradePlugins = new LinkedHashMap() );
}
String upgradePluginKey = compactKey( groupId, artifactId );
if ( !upgradePlugins.containsKey( upgradePluginKey ) )
{
upgradePlugins.put( upgradePluginKey, newerVersions[j].toString() );
}
minRequires = requires;
}
}
catch ( ArtifactResolutionException e )
{
// ignore bad version
}
catch ( ArtifactNotFoundException e )
{
// ignore bad version
}
catch ( ProjectBuildingException e )
{
// ignore bad version
}
}
if ( effectiveVersion != null )
{
VersionRange currentVersionRange = VersionRange.createFromVersion( effectiveVersion );
Artifact probe =
artifactFactory.createDependencyArtifact( groupId, artifactId, currentVersionRange, "pom", null,
"runtime" );
try
{
getHelper().resolveArtifact( probe, true );
MavenProject mavenProject =
projectBuilder.buildFromRepository( probe, remotePluginRepositories, localRepository );
ArtifactVersion requires =
new DefaultArtifactVersion( getRequiredMavenVersion( mavenProject, "2.0" ) );
if ( minMavenVersion == null || minMavenVersion.compareTo( requires ) < 0 )
{
minMavenVersion = requires;
}
}
catch ( ArtifactResolutionException e )
{
// ignore bad version
}
catch ( ArtifactNotFoundException e )
{
// ignore bad version
}
catch ( ProjectBuildingException e )
{
// ignore bad version
}
}
}
catch ( ArtifactMetadataRetrievalException e )
{
throw new MojoExecutionException( e.getMessage(), e );
}
String newVersion;
if ( version == null && pluginsWithVersionsSpecified.contains( coords ) )
{
// Hack ALERT!
//
// All this should be re-written in a less "pom is xml" way... but it'll
// work for now :-(
//
// we have removed the version information, as it was the same as from
// the super-pom... but it actually was specified.
version = artifactVersion != null ? artifactVersion.toString() : null;
}
getLog().debug( "[" + coords + "].version=" + version );
getLog().debug( "[" + coords + "].artifactVersion=" + artifactVersion );
getLog().debug( "[" + coords + "].effectiveVersion=" + effectiveVersion );
getLog().debug( "[" + coords + "].specified=" + pluginsWithVersionsSpecified.contains( coords ) );
if ( version == null || !pluginsWithVersionsSpecified.contains( coords ) )
{
version = (String) superPomPluginManagement.get( ArtifactUtils.versionlessKey( artifact ) );
getLog().debug( "[" + coords + "].superPom.version=" + version );
newVersion = artifactVersion != null
? artifactVersion.toString()
: ( version != null ? version : ( effectiveVersion != null ? effectiveVersion : "(unknown)" ) );
StringBuilder buf = new StringBuilder( compactKey( groupId, artifactId ) );
buf.append( ' ' );
int padding =
WARN_PAD_SIZE - effectiveVersion.length() - ( version != null ? FROM_SUPER_POM.length() : 0 );
while ( buf.length() < padding )
{
buf.append( '.' );
}
buf.append( ' ' );
if ( version != null )
{
buf.append( FROM_SUPER_POM );
superPomDrivingMinVersion = true;
}
buf.append( effectiveVersion );
lockdowns.add( buf.toString() );
addMissingVersionPlugin(groupId, artifactId, version);
}
else if ( artifactVersion != null )
{
newVersion = artifactVersion.toString();
}
else
{
newVersion = null;
}
if ( version != null && artifactVersion != null && newVersion != null &&
new DefaultArtifactVersion( effectiveVersion ).compareTo( new DefaultArtifactVersion( newVersion ) )
< 0 )
{
StringBuilder buf = new StringBuilder( compactKey( groupId, artifactId ) );
buf.append( ' ' );
int padding = INFO_PAD_SIZE - version.length() - newVersion.length() - 4;
while ( buf.length() < padding )
{
buf.append( '.' );
}
buf.append( ' ' );
buf.append( effectiveVersion );
buf.append( " -> " );
buf.append( newVersion );
updates.add( buf.toString() );
addUpdate(groupId,artifactId,version,artifactVersion);
}
}
getLog().info( "" );
if ( updates.isEmpty() )
{
getLog().info( "All plugins with a version specified are using the latest versions." );
}
else
{
getLog().info( "The following plugin updates are available:" );
for ( String update : updates )
{
getLog().info( " " + update );
}
}
getLog().info( "" );
if ( lockdowns.isEmpty() )
{
getLog().info( "All plugins have a version specified." );
}
else
{
getLog().warn( "The following plugins do not have their version specified:" );
for ( String lockdown : lockdowns )
{
getLog().warn( " " + lockdown );
}
}
getLog().info( "" );
boolean noMavenMinVersion = getRequiredMavenVersion( getProject(), null ) == null;
boolean noExplicitMavenMinVersion =
getProject().getPrerequisites() == null || getProject().getPrerequisites().getMaven() == null;
if ( noMavenMinVersion )
{
getLog().warn( "Project does not define minimum Maven version, default is: 2.0" );
report.warnNoMinimumVersion();
}
else if ( noExplicitMavenMinVersion )
{
getLog().info( "Project inherits minimum Maven version as: " + specMavenVersion );
}
else
{
ArtifactVersion explicitMavenVersion =
new DefaultArtifactVersion( getProject().getPrerequisites().getMaven() );
if ( explicitMavenVersion.compareTo( specMavenVersion ) < 0 )
{
getLog().error( "Project's effective minimum Maven (from parent) is: " + specMavenVersion );
getLog().error( "Project defines minimum Maven version as: " + explicitMavenVersion );
IncompatibleParentAndProjectMavenVersion incompatibleParentAndProjectMavenVersion = new IncompatibleParentAndProjectMavenVersion();
incompatibleParentAndProjectMavenVersion.setParentVersion(specMavenVersion.toString());
incompatibleParentAndProjectMavenVersion.setProjectVersion(explicitMavenVersion.toString());
report.warn(incompatibleParentAndProjectMavenVersion);
}
else
{
getLog().info( "Project defines minimum Maven version as: " + specMavenVersion );
}
}
getLog().info( "Plugins require minimum Maven version of: " + minMavenVersion );
if ( superPomDrivingMinVersion )
{
getLog().info( "Note: the super-pom from Maven " + curMavenVersion + " defines some of the plugin" );
getLog().info( " versions and may be influencing the plugins required minimum Maven" );
getLog().info( " version." );
}
getLog().info( "" );
if ( "maven-plugin".equals( getProject().getPackaging() ) )
{
if ( noMavenMinVersion )
{
getLog().warn( "Project (which is a Maven Plugin) does not define required minimum version of Maven." );
getLog().warn( "Update the pom.xml to contain" );
getLog().warn( " " );
getLog().warn( " " );
getLog().warn( " " );
getLog().warn( "To build this plugin you need at least Maven " + minMavenVersion );
getLog().warn( "A Maven Enforcer rule can be used to enforce this if you have not already set one up" );
}
else if ( minMavenVersion != null && specMavenVersion.compareTo( minMavenVersion ) < 0 )
{
getLog().warn( "Project (which is a Maven Plugin) targets Maven " + specMavenVersion + " or newer" );
getLog().warn( "but requires Maven " + minMavenVersion + " or newer to build." );
getLog().warn( "This may or may not be a problem. A Maven Enforcer rule can help " );
getLog().warn( "enforce that the correct version of Maven is used to build this plugin." );
}
else
{
getLog().info( "No plugins require a newer version of Maven than specified by the pom." );
}
}
else
{
if ( noMavenMinVersion )
{
getLog().error( "Project does not define required minimum version of Maven." );
getLog().error( "Update the pom.xml to contain" );
getLog().error( " " );
getLog().error( " " + minMavenVersion + " " );
getLog().error( " " );
}
else if ( minMavenVersion != null && specMavenVersion.compareTo( minMavenVersion ) < 0 )
{
getLog().error( "Project requires an incorrect minimum version of Maven." );
getLog().error( "Either change plugin versions to those compatible with " + specMavenVersion );
getLog().error( "or update the pom.xml to contain" );
getLog().error( " " );
getLog().error( " " + minMavenVersion + " " );
getLog().error( " " );
IncompatibleParentAndProjectMavenVersion incompatibleParentAndProjectMavenVersion = new IncompatibleParentAndProjectMavenVersion();
incompatibleParentAndProjectMavenVersion.setParentVersion(specMavenVersion.toString());
incompatibleParentAndProjectMavenVersion.setProjectVersion(minMavenVersion.toString());
report.warn(incompatibleParentAndProjectMavenVersion);
}
else
{
getLog().info( "No plugins require a newer version of Maven than specified by the pom." );
}
}
for ( Map.Entry> mavenUpgrade : upgrades.entrySet() )
{
ArtifactVersion mavenUpgradeVersion = (ArtifactVersion) mavenUpgrade.getKey();
Map upgradePlugins = mavenUpgrade.getValue();
if ( upgradePlugins.isEmpty() || specMavenVersion.compareTo( mavenUpgradeVersion ) >= 0 )
{
continue;
}
getLog().info( "" );
getLog().info( "Require Maven " + mavenUpgradeVersion + " to use the following plugin updates:" );
for ( Map.Entry entry : upgradePlugins.entrySet() )
{
StringBuilder buf = new StringBuilder( " " );
buf.append( entry.getKey() );
buf.append( ' ' );
String s = entry.getValue();
int padding = INFO_PAD_SIZE - s.length() + 2;
while ( buf.length() < padding )
{
buf.append( '.' );
}
buf.append( ' ' );
buf.append( s );
getLog().info( buf.toString() );
}
}
getLog().info( "" );
ObjectToXmlWriter.writeXmlReport(xmlReport, report);
}
private void addUpdate(final String groupId, final String artifactId, final String version,
final ArtifactVersion artifactVersion) {
ArtifactUpdate update = new ArtifactUpdate();
org.codehaus.mojo.versions.report.Dependency dependency = new org.codehaus.mojo.versions.report.Dependency();
dependency.setGroupId(groupId);
dependency.setArtifactId(artifactId);
dependency.setVersion(version);
update.setDependency(dependency);
update.setVersionUpdate(artifactVersion.toString());
report.addPluginUpdate(update);
}
private void addMissingVersionPlugin(final String groupId, final String artifactId, final String version) {
org.codehaus.mojo.versions.report.Dependency dependency = new org.codehaus.mojo.versions.report.Dependency();
dependency.setGroupId(groupId);
dependency.setArtifactId(artifactId);
dependency.setVersion(version);
report.addMissingVersionPlugin(dependency);
}
private String compactKey( String groupId, String artifactId )
{
if ( PomHelper.APACHE_MAVEN_PLUGINS_GROUPID.equals( groupId ) )
{
// a core plugin... group id is not needed
return artifactId;
}
return groupId + ":" + artifactId;
}
private String getRequiredMavenVersion( MavenProject mavenProject, String defaultValue )
{
ArtifactVersion requiredMavenVersion = null;
while ( mavenProject != null )
{
final Prerequisites prerequisites = mavenProject.getPrerequisites();
final String mavenVersion = prerequisites == null ? null : prerequisites.getMaven();
if ( mavenVersion != null )
{
final ArtifactVersion v = new DefaultArtifactVersion( mavenVersion );
if ( requiredMavenVersion == null || requiredMavenVersion.compareTo( v ) < 0 )
{
requiredMavenVersion = v;
}
}
mavenProject = mavenProject.getParent();
}
return requiredMavenVersion == null ? defaultValue : requiredMavenVersion.toString();
}
private static final class StackState
{
private final String path;
private String groupId;
private String artifactId;
private String version;
public StackState( String path )
{
this.path = path;
}
public String toString()
{
return path + "[groupId=" + groupId + ", artifactId=" + artifactId + ", version=" + version + "]";
}
}
/**
* Returns a set of Strings which correspond to the plugin coordinates where there is a version
* specified.
*
* @param project The project to get the plugins with versions specified.
* @return a set of Strings which correspond to the plugin coordinates where there is a version
* specified.
*/
private Set findPluginsWithVersionsSpecified( MavenProject project )
throws IOException, XMLStreamException
{
return findPluginsWithVersionsSpecified( PomHelper.readXmlFile( project.getFile() ) );
}
/**
* Returns a set of Strings which correspond to the plugin coordinates where there is a version
* specified.
*
* @param pomContents The project to get the plugins with versions specified.
* @return a set of Strings which correspond to the plugin coordinates where there is a version
* specified.
*/
private Set findPluginsWithVersionsSpecified( StringBuilder pomContents )
throws IOException, XMLStreamException
{
Set result = new HashSet();
ModifiedPomXMLEventReader pom = newModifiedPomXER( pomContents );
Pattern pathRegex = Pattern.compile(
"/project(/profiles/profile)?" + "((/build(/pluginManagement)?)|(/reporting))" + "/plugins/plugin" );
Stack pathStack = new Stack();
StackState curState = null;
while ( pom.hasNext() )
{
XMLEvent event = pom.nextEvent();
if ( event.isStartDocument() )
{
curState = new StackState( "" );
pathStack.clear();
}
else if ( event.isStartElement() )
{
String elementName = event.asStartElement().getName().getLocalPart();
if ( curState != null && pathRegex.matcher( curState.path ).matches() )
{
if ( "groupId".equals( elementName ) )
{
curState.groupId = pom.getElementText().trim();
continue;
}
else if ( "artifactId".equals( elementName ) )
{
curState.artifactId = pom.getElementText().trim();
continue;
}
else if ( "version".equals( elementName ) )
{
curState.version = pom.getElementText().trim();
continue;
}
}
pathStack.push( curState );
curState = new StackState( curState.path + "/" + elementName );
}
else if ( event.isEndElement() )
{
if ( curState != null && pathRegex.matcher( curState.path ).matches() )
{
if ( curState.artifactId != null && curState.version != null )
{
if ( curState.groupId == null )
{
curState.groupId = PomHelper.APACHE_MAVEN_PLUGINS_GROUPID;
}
result.add( curState.groupId + ":" + curState.artifactId );
}
}
curState = pathStack.pop();
}
}
return result;
}
// -------------------------- OTHER METHODS --------------------------
/**
* Gets the build plugins of a specific project.
*
* @param model the model to get the build plugins from.
* @param onlyIncludeInherited true
to only return the plugins definitions that will be
* inherited by child projects.
* @return The map of effective plugin versions keyed by coordinates.
* @since 1.0-alpha-1
*/
private Map getBuildPlugins( Model model, boolean onlyIncludeInherited )
{
Map buildPlugins = new HashMap();
try
{
for ( Plugin plugin : model.getBuild().getPlugins() )
{
String coord = getPluginCoords( plugin );
String version = getPluginVersion( plugin );
if ( version != null && ( !onlyIncludeInherited || getPluginInherited( plugin ) ) )
{
buildPlugins.put( coord, version );
}
}
}
catch ( NullPointerException e )
{
// guess there are no plugins here
}
try
{
for ( Profile profile : model.getProfiles() )
{
try
{
for ( Plugin plugin : profile.getBuild().getPlugins() )
{
String coord = getPluginCoords( plugin );
String version = getPluginVersion( plugin );
if ( version != null && ( !onlyIncludeInherited || getPluginInherited( plugin ) ) )
{
buildPlugins.put( coord, version );
}
}
}
catch ( NullPointerException e )
{
// guess there are no plugins here
}
}
}
catch ( NullPointerException e )
{
// guess there are no profiles here
}
return buildPlugins;
}
/**
* Returns the Inherited of a {@link Plugin} or {@link ReportPlugin}
*
* @param plugin the {@link Plugin} or {@link ReportPlugin}
* @return the Inherited of the {@link Plugin} or {@link ReportPlugin}
* @since 1.0-alpha-1
*/
private static boolean getPluginInherited( Object plugin )
{
return "true".equalsIgnoreCase( plugin instanceof ReportPlugin
? ( (ReportPlugin) plugin ).getInherited()
: ( (Plugin) plugin ).getInherited() );
}
/**
* Returns the lifecycle plugins of a specific project.
*
* @param project the project to get the lifecycle plugins from.
* @return The map of effective plugin versions keyed by coordinates.
* @throws org.apache.maven.plugin.MojoExecutionException
* if things go wrong.
* @since 1.0-alpha-1
*/
private Map getLifecyclePlugins( MavenProject project )
throws MojoExecutionException
{
Map lifecyclePlugins = new HashMap();
try
{
Set plugins = getBoundPlugins( project, "clean,deploy,site" );
for ( Plugin plugin : plugins )
{
lifecyclePlugins.put( getPluginCoords( plugin ), plugin );
}
}
catch ( PluginNotFoundException e )
{
throw new MojoExecutionException( "Could not find plugin", e );
}
catch ( LifecycleExecutionException e )
{
throw new MojoExecutionException( "Could not determine lifecycle", e );
}
catch ( IllegalAccessException e )
{
throw new MojoExecutionException( "Could not determine lifecycles", e );
}
catch ( NullPointerException e )
{
// Maven 3.x
}
return lifecyclePlugins;
}
/**
* Gets the plugins that are bound to the defined phases. This does not find plugins bound in the pom to a phase
* later than the plugin is executing.
*
* @param project the project
* @param thePhases the the phases
* @return the bound plugins
* @throws org.apache.maven.plugin.PluginNotFoundException
* the plugin not found exception
* @throws LifecycleExecutionException the lifecycle execution exception
* @throws IllegalAccessException the illegal access exception
*/
// pilfered this from enforcer-rules
// TODO coordinate with Brian Fox to remove the duplicate code
private Set getBoundPlugins( MavenProject project, String thePhases )
throws PluginNotFoundException, LifecycleExecutionException, IllegalAccessException
{
if ( new DefaultArtifactVersion( "3.0" ).compareTo( runtimeInformation.getApplicationVersion() ) <= 0 )
{
getLog().debug( "Using Maven 3.0+ strategy to determine lifecycle defined plugins" );
try
{
Method getPluginsBoundByDefaultToAllLifecycles =
LifecycleExecutor.class.getMethod( "getPluginsBoundByDefaultToAllLifecycles",
new Class[]{ String.class } );
Set plugins = (Set) getPluginsBoundByDefaultToAllLifecycles.invoke( lifecycleExecutor,
new Object[]{
project.getPackaging()
== null
? "jar"
: project.getPackaging() } );
// we need to provide a copy with the version blanked out so that inferring from super-pom
// works as for 2.x as 3.x fills in the version on us!
Set result = new LinkedHashSet( plugins.size() );
for ( Plugin plugin : plugins )
{
Plugin dup = new Plugin();
dup.setGroupId( plugin.getGroupId() );
dup.setArtifactId( plugin.getArtifactId() );
result.add( dup );
}
return result;
}
catch ( NoSuchMethodException e1 )
{
// no much we can do here
}
catch ( InvocationTargetException e1 )
{
// no much we can do here
}
catch ( IllegalAccessException e1 )
{
// no much we can do here
}
}
List lifecycles = null;
getLog().debug( "Using Maven 2.0.10+ strategy to determine lifecycle defined plugins" );
try
{
Method getLifecycles = LifecycleExecutor.class.getMethod( "getLifecycles", new Class[0] );
lifecycles = (List) getLifecycles.invoke( lifecycleExecutor, new Object[0] );
}
catch ( NoSuchMethodException e1 )
{
// no much we can do here
}
catch ( InvocationTargetException e1 )
{
// no much we can do here
}
catch ( IllegalAccessException e1 )
{
// no much we can do here
}
Set allPlugins = new HashSet();
// lookup the bindings for all the passed in phases
for ( String lifecyclePhase : thePhases.split( "," ) )
{
if ( StringUtils.isNotEmpty( lifecyclePhase ) )
{
try
{
Lifecycle lifecycle = getLifecycleForPhase( lifecycles, lifecyclePhase );
allPlugins.addAll( getAllPlugins( project, lifecycle ) );
}
catch ( BuildFailureException e )
{
// i'm going to swallow this because the
// user may have declared a phase that
// doesn't exist for every module.
}
}
}
return allPlugins;
}
/**
* Gets the lifecycle for phase.
*
* @param lifecycles The list of lifecycles.
* @param phase the phase
* @return the lifecycle for phase
* @throws BuildFailureException the build failure exception
* @throws LifecycleExecutionException the lifecycle execution exception
*/
private Lifecycle getLifecycleForPhase( List lifecycles, String phase )
throws BuildFailureException, LifecycleExecutionException
{
Lifecycle lifecycle = (Lifecycle) getPhaseToLifecycleMap( lifecycles ).get( phase );
if ( lifecycle == null )
{
throw new BuildFailureException( "Unable to find lifecycle for phase '" + phase + "'" );
}
return lifecycle;
}
/*
* Uses borrowed lifecycle code to get a list of all plugins bound to the lifecycle.
*/
/**
* Gets the all plugins.
*
* @param project the project
* @param lifecycle the lifecycle
* @return the all plugins
* @throws PluginNotFoundException the plugin not found exception
* @throws LifecycleExecutionException the lifecycle execution exception
*/
private Set getAllPlugins( MavenProject project, Lifecycle lifecycle )
throws PluginNotFoundException, LifecycleExecutionException
{
Set plugins = new HashSet();
// first, bind those associated with the packaging
Map mappings = findMappingsForLifecycle( project, lifecycle );
Iterator iter = mappings.entrySet().iterator();
while ( iter.hasNext() )
{
Map.Entry entry = (Map.Entry) iter.next();
String value = (String) entry.getValue();
String[] tokens = value.split( ":" );
Plugin plugin = new Plugin();
plugin.setGroupId( tokens[0] );
plugin.setArtifactId( tokens[1] );
plugins.add( plugin );
}
for ( String value : findOptionalMojosForLifecycle( project, lifecycle ) )
{
String[] tokens = value.split( ":" );
Plugin plugin = new Plugin();
plugin.setGroupId( tokens[0] );
plugin.setArtifactId( tokens[1] );
plugins.add( plugin );
}
plugins.addAll( (List) project.getBuildPlugins() );
return plugins;
}
/**
* Find mappings for lifecycle.
*
* @param project the project
* @param lifecycle the lifecycle
* @return the map
* @throws LifecycleExecutionException the lifecycle execution exception
* @throws PluginNotFoundException the plugin not found exception
*/
private Map findMappingsForLifecycle( MavenProject project, Lifecycle lifecycle )
throws LifecycleExecutionException, PluginNotFoundException
{
String packaging = project.getPackaging();
Map mappings = null;
LifecycleMapping m =
(LifecycleMapping) findExtension( project, LifecycleMapping.ROLE, packaging, session.getSettings(),
session.getLocalRepository() );
if ( m != null )
{
mappings = m.getPhases( lifecycle.getId() );
}
Map defaultMappings = lifecycle.getDefaultPhases();
if ( mappings == null )
{
try
{
m = (LifecycleMapping) session.lookup( LifecycleMapping.ROLE, packaging );
mappings = m.getPhases( lifecycle.getId() );
}
catch ( ComponentLookupException e )
{
if ( defaultMappings == null )
{
throw new LifecycleExecutionException(
"Cannot find lifecycle mapping for packaging: \'" + packaging + "\'.", e );
}
}
}
if ( mappings == null )
{
if ( defaultMappings == null )
{
throw new LifecycleExecutionException(
"Cannot find lifecycle mapping for packaging: \'" + packaging + "\', and there is no default" );
}
else
{
mappings = defaultMappings;
}
}
return mappings;
}
/**
* Find optional mojos for lifecycle.
*
* @param project the project
* @param lifecycle the lifecycle
* @return the list
* @throws LifecycleExecutionException the lifecycle execution exception
* @throws PluginNotFoundException the plugin not found exception
*/
private List findOptionalMojosForLifecycle( MavenProject project, Lifecycle lifecycle )
throws LifecycleExecutionException, PluginNotFoundException
{
String packaging = project.getPackaging();
List optionalMojos = null;
LifecycleMapping m =
(LifecycleMapping) findExtension( project, LifecycleMapping.ROLE, packaging, session.getSettings(),
session.getLocalRepository() );
if ( m != null )
{
optionalMojos = m.getOptionalMojos( lifecycle.getId() );
}
if ( optionalMojos == null )
{
try
{
m = (LifecycleMapping) session.lookup( LifecycleMapping.ROLE, packaging );
optionalMojos = m.getOptionalMojos( lifecycle.getId() );
}
catch ( ComponentLookupException e )
{
getLog().debug( "Error looking up lifecycle mapping to retrieve optional mojos. Lifecycle ID: " +
lifecycle.getId() + ". Error: " + e.getMessage(), e );
}
}
if ( optionalMojos == null )
{
optionalMojos = Collections.emptyList();
}
return optionalMojos;
}
/**
* Find extension.
*
* @param project the project
* @param role the role
* @param roleHint the role hint
* @param settings the settings
* @param localRepository the local repository
* @return the object
* @throws LifecycleExecutionException the lifecycle execution exception
* @throws PluginNotFoundException the plugin not found exception
*/
private Object findExtension( MavenProject project, String role, String roleHint, Settings settings,
ArtifactRepository localRepository )
throws LifecycleExecutionException, PluginNotFoundException
{
Object pluginComponent = null;
for ( Iterator i = project.getBuildPlugins().iterator(); i.hasNext() && pluginComponent == null; )
{
Plugin plugin = (Plugin) i.next();
if ( plugin.isExtensions() )
{
loadPluginDescriptor( plugin, project, session );
// TODO: if moved to the plugin manager we
// already have the descriptor from above
// and so do can lookup the container
// directly
try
{
pluginComponent = pluginManager.getPluginComponent( plugin, role, roleHint );
}
catch ( ComponentLookupException e )
{
getLog().debug( "Unable to find the lifecycle component in the extension", e );
}
catch ( PluginManagerException e )
{
throw new LifecycleExecutionException(
"Error getting extensions from the plugin '" + plugin.getKey() + "': " + e.getMessage(), e );
}
}
}
return pluginComponent;
}
/**
* Verify plugin.
*
* @param plugin the plugin
* @param project the project
* @param session the session
* @return the plugin descriptor
* @throws LifecycleExecutionException the lifecycle execution exception
* @throws PluginNotFoundException the plugin not found exception
*/
private PluginDescriptor loadPluginDescriptor( Plugin plugin, MavenProject project, MavenSession session )
throws LifecycleExecutionException, PluginNotFoundException
{
PluginDescriptor pluginDescriptor;
try
{
pluginDescriptor = pluginManager.loadPluginDescriptor( plugin, project, session );
}
catch ( PluginManagerException e )
{
throw new LifecycleExecutionException(
"Internal error in the plugin manager getting plugin '" + plugin.getKey() + "': " + e.getMessage(), e );
}
catch ( PluginVersionResolutionException e )
{
throw new LifecycleExecutionException( e.getMessage(), e );
}
catch ( InvalidVersionSpecificationException e )
{
throw new LifecycleExecutionException( e.getMessage(), e );
}
catch ( InvalidPluginException e )
{
throw new LifecycleExecutionException( e.getMessage(), e );
}
catch ( ArtifactNotFoundException e )
{
throw new LifecycleExecutionException( e.getMessage(), e );
}
catch ( ArtifactResolutionException e )
{
throw new LifecycleExecutionException( e.getMessage(), e );
}
catch ( PluginVersionNotFoundException e )
{
throw new LifecycleExecutionException( e.getMessage(), e );
}
return pluginDescriptor;
}
/**
* Returns all the parent projects of the specified project, with the root project first.
*
* @param project The maven project to get the parents of
* @return the parent projects of the specified project, with the root project first.
* @throws org.apache.maven.plugin.MojoExecutionException
* if the super-pom could not be created.
* @since 1.0-alpha-1
*/
private List getParentProjects( MavenProject project )
throws MojoExecutionException
{
List parents = new ArrayList();
while ( project.getParent() != null )
{
project = project.getParent();
parents.add( 0, project );
}
return parents;
}
/*
* NOTE: All the code following this point was scooped from the DefaultLifecycleExecutor. There must be a better way
* but for now it should work.
*/
/**
* Gets the phase to lifecycle map.
*
* @param lifecycles The list of lifecycles.
* @return the phase to lifecycle map.
* @throws LifecycleExecutionException the lifecycle execution exception.
*/
public Map getPhaseToLifecycleMap( List lifecycles )
throws LifecycleExecutionException
{
Map phaseToLifecycleMap = new HashMap();
for ( Iterator i = lifecycles.iterator(); i.hasNext(); )
{
Lifecycle lifecycle = (Lifecycle) i.next();
for ( Iterator p = lifecycle.getPhases().iterator(); p.hasNext(); )
{
String phase = (String) p.next();
if ( phaseToLifecycleMap.containsKey( phase ) )
{
Lifecycle prevLifecycle = (Lifecycle) phaseToLifecycleMap.get( phase );
throw new LifecycleExecutionException(
"Phase '" + phase + "' is defined in more than one lifecycle: '" + lifecycle.getId() +
"' and '" + prevLifecycle.getId() + "'" );
}
else
{
phaseToLifecycleMap.put( phase, lifecycle );
}
}
}
return phaseToLifecycleMap;
}
/**
* Returns the set of all plugins used by the project.
*
* @param superPomPluginManagement the super pom's pluginManagement plugins.
* @param parentPluginManagement the parent pom's pluginManagement plugins.
* @param parentBuildPlugins the parent pom's build plugins.
* @param parentReportPlugins the parent pom's report plugins.
* @param pluginsWithVersionsSpecified the plugin coords that have a version defined in the project.
* @return the set of plugins used by the project.
* @throws org.apache.maven.plugin.MojoExecutionException
* if things go wrong.
*/
private Set getProjectPlugins( Map superPomPluginManagement,
Map parentPluginManagement,
Map parentBuildPlugins,
Map parentReportPlugins,
Set pluginsWithVersionsSpecified )
throws MojoExecutionException
{
Map plugins = new HashMap();
getLog().debug( "Building list of project plugins..." );
if ( getLog().isDebugEnabled() )
{
StringWriter origModel = new StringWriter();
try
{
origModel.write( "Original model:\n" );
getProject().writeOriginalModel( origModel );
getLog().debug( origModel.toString() );
}
catch ( IOException e )
{
// ignore
}
}
debugVersionMap( "super-pom version map", superPomPluginManagement );
debugVersionMap( "parent version map", parentPluginManagement );
Map excludePluginManagement = new HashMap( superPomPluginManagement );
excludePluginManagement.putAll( parentPluginManagement );
debugVersionMap( "aggregate version map", excludePluginManagement );
excludePluginManagement.keySet().removeAll( pluginsWithVersionsSpecified );
debugVersionMap( "final aggregate version map", excludePluginManagement );
Model originalModel;
try
{
originalModel = modelInterpolator.interpolate( getProject().getOriginalModel(), getProject().getBasedir(),
new DefaultProjectBuilderConfiguration().setExecutionProperties(
getProject().getProperties() ), true );
}
catch ( ModelInterpolationException e )
{
throw new MojoExecutionException( e.getMessage(), e );
}
try
{
addProjectPlugins( plugins, originalModel.getBuild().getPluginManagement().getPlugins(),
excludePluginManagement );
}
catch ( NullPointerException e )
{
// guess there are no plugins here
}
debugPluginMap( "after adding local pluginManagement", plugins );
try
{
List lifecyclePlugins = new ArrayList( getLifecyclePlugins( getProject() ).values() );
for ( Iterator i = lifecyclePlugins.iterator(); i.hasNext(); )
{
Plugin lifecyclePlugin = i.next();
if ( getPluginVersion( lifecyclePlugin ) != null )
{
// version comes from lifecycle, therefore cannot modify
i.remove();
}
else
{
// lifecycle leaves version open
String parentVersion = parentPluginManagement.get( getPluginCoords( lifecyclePlugin ) );
if ( parentVersion != null )
{
// parent controls version
i.remove();
}
}
}
addProjectPlugins( plugins, lifecyclePlugins, parentPluginManagement );
debugPluginMap( "after adding lifecycle plugins", plugins );
}
catch ( NullPointerException e )
{
// using maven 3.x or newer
}
try
{
List buildPlugins = new ArrayList( originalModel.getBuild().getPlugins() );
for ( Iterator i = buildPlugins.iterator(); i.hasNext(); )
{
Plugin buildPlugin = i.next();
if ( getPluginVersion( buildPlugin ) == null )
{
String parentVersion = parentPluginManagement.get( getPluginCoords( buildPlugin ) );
if ( parentVersion != null )
{
// parent controls version
i.remove();
}
}
}
addProjectPlugins( plugins, buildPlugins, parentBuildPlugins );
}
catch ( NullPointerException e )
{
// guess there are no plugins here
}
debugPluginMap( "after adding build plugins", plugins );
try
{
List reportPlugins = new ArrayList( originalModel.getReporting().getPlugins() );
for ( Iterator i = reportPlugins.iterator(); i.hasNext(); )
{
ReportPlugin reportPlugin = i.next();
if ( getPluginVersion( reportPlugin ) == null )
{
String parentVersion = parentPluginManagement.get( getPluginCoords( reportPlugin ) );
if ( parentVersion != null )
{
// parent controls version
i.remove();
}
}
}
addProjectPlugins( plugins, toPlugins( reportPlugins ), parentReportPlugins );
}
catch ( NullPointerException e )
{
// guess there are no plugins here
}
debugPluginMap( "after adding reporting plugins", plugins );
for ( Profile profile : originalModel.getProfiles() )
{
try
{
addProjectPlugins( plugins, profile.getBuild().getPluginManagement().getPlugins(),
excludePluginManagement );
}
catch ( NullPointerException e )
{
// guess there are no plugins here
}
debugPluginMap( "after adding build pluginManagement for profile " + profile.getId(), plugins );
try
{
addProjectPlugins( plugins, profile.getBuild().getPlugins(), parentBuildPlugins );
}
catch ( NullPointerException e )
{
// guess there are no plugins here
}
debugPluginMap( "after adding build plugins for profile " + profile.getId(), plugins );
try
{
addProjectPlugins( plugins, toPlugins( profile.getReporting().getPlugins() ), parentReportPlugins );
}
catch ( NullPointerException e )
{
// guess there are no plugins here
}
debugPluginMap( "after adding reporting plugins for profile " + profile.getId(), plugins );
}
Set result = new TreeSet( new PluginComparator() );
result.addAll( plugins.values() );
return result;
}
/**
* Adds those project plugins which are not inherited from the parent definitions to the list of plugins.
*
* @param plugins The list of plugins.
* @param projectPlugins The project's plugins.
* @param parentDefinitions The parent plugin definitions.
* @since 1.0-alpha-1
*/
private void addProjectPlugins( Map plugins, Collection projectPlugins,
Map parentDefinitions )
{
for ( Plugin plugin : projectPlugins )
{
String coord = getPluginCoords( plugin );
String version = getPluginVersion( plugin );
String parentVersion = parentDefinitions.get( coord );
if ( version == null && ( !plugins.containsKey( coord )
|| getPluginVersion( plugins.get( coord ) ) == null ) && parentVersion != null )
{
Plugin parentPlugin = new Plugin();
parentPlugin.setGroupId( getPluginGroupId( plugin ) );
parentPlugin.setArtifactId( getPluginArtifactId( plugin ) );
parentPlugin.setVersion( parentVersion );
plugins.put( coord, parentPlugin );
}
else if ( parentVersion == null || !parentVersion.equals( version ) )
{
if ( !plugins.containsKey( coord ) || getPluginVersion( plugins.get( coord ) ) == null )
{
plugins.put( coord, plugin );
}
}
if ( !plugins.containsKey( coord ) )
{
plugins.put( coord, plugin );
}
}
}
/**
* Logs at debug level a map of plugins keyed by versionless key.
*
* @param description log description
* @param plugins a map with keys being the {@link String} corresponding to the versionless artifact key and
* values being {@link Plugin} or {@link ReportPlugin}.
*/
private void debugPluginMap( String description, Map plugins )
{
if ( getLog().isDebugEnabled() )
{
Set sorted = new TreeSet( new PluginComparator() );
sorted.addAll( plugins.values() );
StringBuilder buf = new StringBuilder( description );
Iterator i = sorted.iterator();
while ( i.hasNext() )
{
Object plugin = i.next();
buf.append( "\n " );
buf.append( getPluginCoords( plugin ) );
buf.append( ":" );
buf.append( getPluginVersion( plugin ) );
}
getLog().debug( buf.toString() );
}
}
/**
* Logs at debug level a map of plugin versions keyed by versionless key.
*
* @param description log description
* @param plugins a map with keys being the {@link String} corresponding to the versionless artifact key and
* values being {@link String} plugin version.
*/
private void debugVersionMap( String description, Map plugins )
{
if ( getLog().isDebugEnabled() )
{
StringBuilder buf = new StringBuilder( description );
Iterator i = plugins.entrySet().iterator();
while ( i.hasNext() )
{
Map.Entry plugin = (Map.Entry) i.next();
buf.append( "\n " );
buf.append( plugin.getKey() );
buf.append( ":" );
buf.append( plugin.getValue() );
}
getLog().debug( buf.toString() );
}
}
/**
* Returns the coordinates of a plugin.
*
* @param plugin The plugin
* @return The groupId and artifactId separated by a colon.
* @since 1.0-alpha-1
*/
private static String getPluginCoords( Object plugin )
{
return getPluginGroupId( plugin ) + ":" + getPluginArtifactId( plugin );
}
/**
* Returns the ArtifactId of a {@link Plugin} or {@link ReportPlugin}
*
* @param plugin the {@link Plugin} or {@link ReportPlugin}
* @return the ArtifactId of the {@link Plugin} or {@link ReportPlugin}
* @since 1.0-alpha-1
*/
private static String getPluginArtifactId( Object plugin )
{
return plugin instanceof ReportPlugin
? ( (ReportPlugin) plugin ).getArtifactId()
: ( (Plugin) plugin ).getArtifactId();
}
private static Plugin toPlugin( ReportPlugin reportPlugin )
{
Plugin plugin = new Plugin();
plugin.setGroupId( reportPlugin.getGroupId() );
plugin.setArtifactId( reportPlugin.getArtifactId() );
plugin.setVersion( reportPlugin.getVersion() );
return plugin;
}
private static ReportPlugin toReportPlugin( Plugin plugin )
{
ReportPlugin reportPlugin = new ReportPlugin();
reportPlugin.setGroupId( plugin.getGroupId() );
reportPlugin.setArtifactId( plugin.getArtifactId() );
reportPlugin.setVersion( plugin.getVersion() );
return reportPlugin;
}
private static Set toPlugins( Set reportPlugins )
{
Set result;
if ( reportPlugins instanceof LinkedHashSet )
{
result = new LinkedHashSet( reportPlugins.size() );
}
else if ( reportPlugins instanceof SortedSet )
{
final Comparator super ReportPlugin> comparator =
( (SortedSet) reportPlugins ).comparator();
result = new TreeSet( new Comparator()
{
public int compare( Plugin o1, Plugin o2 )
{
return comparator.compare( toReportPlugin( o1 ), toReportPlugin( o2 ) );
}
} );
}
else
{
result = new HashSet( reportPlugins.size() );
}
for ( ReportPlugin reportPlugin : reportPlugins )
{
result.add( toPlugin( reportPlugin ) );
}
return result;
}
private static List toPlugins( List reportPlugins )
{
List result = new ArrayList( reportPlugins.size() );
for ( ReportPlugin reportPlugin : reportPlugins )
{
result.add( toPlugin( reportPlugin ) );
}
return result;
}
private static Collection toPlugins( Collection reportPlugins )
{
if ( reportPlugins instanceof Set )
{
return toPlugins( (Set) reportPlugins );
}
if ( reportPlugins instanceof List )
{
return toPlugins( (List) reportPlugins );
}
return toPlugins( new ArrayList( reportPlugins ) );
}
/**
* Returns the GroupId of a {@link Plugin} or {@link ReportPlugin}
*
* @param plugin the {@link Plugin} or {@link ReportPlugin}
* @return the GroupId of the {@link Plugin} or {@link ReportPlugin}
* @since 1.0-alpha-1
*/
private static String getPluginGroupId( Object plugin )
{
return plugin instanceof ReportPlugin
? ( (ReportPlugin) plugin ).getGroupId()
: ( (Plugin) plugin ).getGroupId();
}
/**
* Returns the Version of a {@link Plugin} or {@link ReportPlugin}
*
* @param plugin the {@link Plugin} or {@link ReportPlugin}
* @return the Version of the {@link Plugin} or {@link ReportPlugin}
* @since 1.0-alpha-1
*/
private static String getPluginVersion( Object plugin )
{
return plugin instanceof ReportPlugin
? ( (ReportPlugin) plugin ).getVersion()
: ( (Plugin) plugin ).getVersion();
}
/**
* Gets the report plugins of a specific project.
*
* @param model the model to get the report plugins from.
* @param onlyIncludeInherited true
to only return the plugins definitions that will be
* inherited by child projects.
* @return The map of effective plugin versions keyed by coordinates.
* @since 1.0-alpha-1
*/
private Map getReportPlugins( Model model, boolean onlyIncludeInherited )
{
Map reportPlugins = new HashMap();
try
{
for ( ReportPlugin plugin : model.getReporting().getPlugins() )
{
String coord = getPluginCoords( plugin );
String version = getPluginVersion( plugin );
if ( version != null && ( !onlyIncludeInherited || getPluginInherited( plugin ) ) )
{
reportPlugins.put( coord, version );
}
}
}
catch ( NullPointerException e )
{
// guess there are no plugins here
}
try
{
for ( Profile profile : model.getProfiles() )
{
try
{
for ( ReportPlugin plugin : profile.getReporting().getPlugins() )
{
String coord = getPluginCoords( plugin );
String version = getPluginVersion( plugin );
if ( version != null && ( !onlyIncludeInherited || getPluginInherited( plugin ) ) )
{
reportPlugins.put( coord, version );
}
}
}
catch ( NullPointerException e )
{
// guess there are no plugins here
}
}
}
catch ( NullPointerException e )
{
// guess there are no profiles here
}
return reportPlugins;
}
/**
* @param pom the pom to update.
* @throws MojoExecutionException when things go wrong
* @throws MojoFailureException when things go wrong in a very bad way
* @throws XMLStreamException when things go wrong with XML streaming
* @see AbstractVersionsUpdaterMojo#update(ModifiedPomXMLEventReader)
* @since 1.0-alpha-1
*/
protected void update( ModifiedPomXMLEventReader pom )
throws MojoExecutionException, MojoFailureException, XMLStreamException
{
// do nothing
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy