Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
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 java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.stream.XMLStreamException;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.codehaus.mojo.versions.api.ArtifactAssociation;
import org.codehaus.mojo.versions.api.PomHelper;
import org.codehaus.mojo.versions.api.PropertyVersions;
import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader;
/**
* Compare dependency versions of the current project to dependencies or dependency management of a remote repository
* project. Can optionally update locally the project instead of reporting the comparison
*
* @author Paul Gier
* @since 1.3
*/
@Mojo( name = "compare-dependencies", requiresProject = true, requiresDirectInvocation = true )
public class CompareDependenciesMojo
extends AbstractVersionsDependencyUpdaterMojo
{
/**
* The width to pad info messages.
*
* @since 1.0-alpha-1
*/
private static final int INFO_PAD_SIZE = 68;
/**
* The groupId, artifactId, and version of the remote project (POM) to which we are comparing. This should be in the
* form "groupId:artifactId:version"
*/
@Parameter( property = "remotePom", required = true )
protected String remotePom;
/**
* Ignore the list of remote dependencies and only compare the remote dependencyManagement
*/
@Parameter( property = "ignoreRemoteDependencies", defaultValue = "false" )
protected boolean ignoreRemoteDependencies;
/**
* Ignore the remote dependency management and only check against the actual dependencies of the remote project
*/
@Parameter( property = "ignoreRemoteDependencyManagement", defaultValue = "false" )
protected boolean ignoreRemoteDependencyManagement;
/**
* Update dependency versions in the current POM.
*/
@Parameter( property = "updateDependencies", defaultValue = "false" )
protected boolean updateDependencies;
/**
* Update dependency versions stored in properties
*
* @parameter property="updatePropertyVersions" default-value="false"
*/
@Parameter( property = "updatePropertyVersions", defaultValue = "false" )
protected boolean updatePropertyVersions;
/**
* Display the dependency version differences on the command line, but do not update the versions in the current
* pom. If updateDependencies is set to "true" this will automatically be set to false.
*/
@Parameter( property = "reportMode", defaultValue = "true" )
protected boolean reportMode;
/**
* If the output file is set, the diff report will be written to this file.
*/
@Parameter( property = "reportOutputFile" )
protected File reportOutputFile;
/**
* The project builder used to initialize the remote project.
*/
@Component
protected MavenProjectBuilder mavenProjectBuilder;
// ------------------------------ METHODS --------------------------
/**
* @param pom the pom to update.
* @throws org.apache.maven.plugin.MojoExecutionException Something wrong with the plugin itself
* @throws org.apache.maven.plugin.MojoFailureException The plugin detected an error in the build
* @throws javax.xml.stream.XMLStreamException when things go wrong with XML streaming
* @see AbstractVersionsUpdaterMojo#update(org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader)
*/
protected void update( ModifiedPomXMLEventReader pom )
throws MojoExecutionException, MojoFailureException, XMLStreamException
{
if ( this.ignoreRemoteDependencies && this.ignoreRemoteDependencyManagement )
{
throw new MojoFailureException( " ignoreRemoteDependencies and ignoreRemoteDependencyManagement"
+ "are both set to true. At least one of these needs to be false " );
}
if ( updateDependencies )
{
reportMode = false;
}
String[] remotePomParts = this.remotePom.split( ":" );
if ( remotePomParts.length != 3 )
{
throw new MojoFailureException( " Invalid format for remotePom: " + remotePom );
}
String rGroupId = remotePomParts[0];
String rArtifactId = remotePomParts[1];
String rVersion = remotePomParts[2];
Dependency remoteDependency = new Dependency();
remoteDependency.setGroupId( rGroupId );
remoteDependency.setArtifactId( rArtifactId );
remoteDependency.setVersion( rVersion );
Artifact remoteArtifact = this.toArtifact( remoteDependency );
MavenProject remoteMavenProject = null;
try
{
remoteMavenProject =
mavenProjectBuilder.buildFromRepository( remoteArtifact, remoteArtifactRepositories, localRepository );
}
catch ( ProjectBuildingException e )
{
throw new MojoExecutionException( "Unable to build remote project " + remoteArtifact, e );
}
Map remoteDepsMap = new HashMap();
if ( !ignoreRemoteDependencyManagement )
{
List remoteProjectDepMgmtDeps = ( remoteMavenProject.getDependencyManagement() == null ) ? null
: remoteMavenProject.getDependencyManagement().getDependencies();
mapDependencies( remoteDepsMap, remoteProjectDepMgmtDeps );
}
if ( !ignoreRemoteDependencies )
{
List remoteProjectDeps = remoteMavenProject.getDependencies();
mapDependencies( remoteDepsMap, remoteProjectDeps );
}
List totalDiffs = new ArrayList();
List propertyDiffs = new ArrayList();
if ( getProject().getDependencyManagement() != null && isProcessingDependencyManagement() )
{
List depManDiffs =
compareVersions( pom, getProject().getDependencyManagement().getDependencies(), remoteDepsMap );
totalDiffs.addAll( depManDiffs );
}
if ( isProcessingDependencies() )
{
List depDiffs = compareVersions( pom, getProject().getDependencies(), remoteDepsMap );
totalDiffs.addAll( depDiffs );
}
if ( updatePropertyVersions )
{
Map versionProperties =
this.getHelper().getVersionPropertiesMap( getProject(), null, null, null, true );
List diff = updatePropertyVersions( pom, versionProperties, remoteDepsMap );
propertyDiffs.addAll( diff );
}
if ( reportMode )
{
getLog().info( "The following differences were found:" );
if ( totalDiffs.size() == 0 )
{
getLog().info( " none" );
}
else
{
for ( String totalDiff : totalDiffs )
{
getLog().info( " " + totalDiff );
}
}
getLog().info( "The following property differences were found:" );
if ( propertyDiffs.size() == 0 )
{
getLog().info( " none" );
}
else
{
for ( String propertyDiff : propertyDiffs )
{
getLog().info( " " + propertyDiff );
}
}
}
if ( reportOutputFile != null )
{
writeReportFile( totalDiffs, propertyDiffs );
}
}
/**
* Compare the dependency versions of the current project with the dependency versions of a remote project
*
* @throws XMLStreamException
*/
private List compareVersions( ModifiedPomXMLEventReader pom, List dependencies,
Map remoteDependencies )
throws MojoExecutionException, XMLStreamException
{
List updates = new ArrayList();
for ( Dependency dep : dependencies )
{
Artifact artifact = this.toArtifact( dep );
if ( !isIncluded( artifact ) )
{
continue;
}
Dependency remoteDep = remoteDependencies.get( dep.getManagementKey() );
if ( remoteDep != null )
{
String remoteVersion = remoteDep.getVersion();
if ( !dep.getVersion().equals( remoteVersion ) )
{
StringBuilder buf = writeDependencyDiffMessage( dep, remoteVersion );
updates.add( buf.toString() );
if ( !reportMode )
{
if ( PomHelper.setDependencyVersion( pom, dep.getGroupId(), dep.getArtifactId(),
dep.getVersion(), remoteVersion,
getProject().getModel() ) )
{
getLog().info( "Updated " + toString( dep ) + " to version " + remoteVersion );
}
}
}
}
}
return updates;
}
/**
* Updates the properties holding a version if necessary.
*/
private List updatePropertyVersions( ModifiedPomXMLEventReader pom,
Map versionProperties,
Map remoteDependencies )
throws XMLStreamException
{
List result = new ArrayList();
for ( Map.Entry entry : versionProperties.entrySet() )
{
Property property = entry.getKey();
PropertyVersions version = entry.getValue();
String candidateVersion = computeCandidateVersion( remoteDependencies, property, version );
if ( candidateVersion != null )
{
String originalVersion = version.getAssociations()[0].getArtifact().getVersion(); // Yekes
if ( !candidateVersion.equals( originalVersion ) ) // Update needed
{
result.add( writeDiffMessage( property.getName(), originalVersion, candidateVersion ).toString() );
if ( !reportMode
&& PomHelper.setPropertyVersion( pom, null, property.getName(), candidateVersion ) )
{
getLog().info( "Updated ${" + property.getName() + "} from " + originalVersion + " to "
+ candidateVersion );
}
}
}
}
return result;
}
/**
* Returns the candidate version to use for the specified property.
*
* The dependencies currently linked to the property must all be defined by the remote POM and they should refer to
* the same version. If that's the case, that same version is returned. Otherwise, null is returned
* indicating that there is no candidate.
*
* @param remoteDependencies the remote dependencies
* @param property the property to update
* @param propertyVersions the association
* @return the candidate version or null if there isn't any
*/
private String computeCandidateVersion( Map remoteDependencies, Property property,
PropertyVersions propertyVersions )
{
String candidateVersion = null;
for ( ArtifactAssociation artifactAssociation : propertyVersions.getAssociations() )
{
String id = generateId( artifactAssociation.getArtifact() );
Dependency dependency = remoteDependencies.get( id );
if ( dependency == null )
{
getLog().info( "Not updating ${" + property.getName() + "}: no info for " + id );
return null;
}
else
{
if ( candidateVersion == null )
{
candidateVersion = dependency.getVersion();
}
else if ( !candidateVersion.equals( dependency.getVersion() ) )
{
getLog().warn( "Could not update ${" + property.getName() + "}: version mismatch" );
return null;
}
}
}
return candidateVersion;
}
private void writeReportFile( List dependenciesUpdate, List propertiesUpdate )
throws MojoExecutionException
{
if ( !reportOutputFile.getParentFile().exists() )
{
reportOutputFile.getParentFile().mkdirs();
}
FileWriter fw = null;
PrintWriter pw = null;
try
{
fw = new FileWriter( reportOutputFile );
pw = new PrintWriter( fw );
pw.println( "The following differences were found:" );
pw.println();
if ( dependenciesUpdate.size() == 0 )
{
pw.println( " none" );
}
else
{
for ( String dependencyUpdate : dependenciesUpdate )
{
pw.println( " " + dependencyUpdate );
}
}
pw.println();
pw.println( "The following property differences were found:" );
pw.println();
if ( propertiesUpdate.size() == 0 )
{
pw.println( " none" );
}
else
{
for ( String propertyUpdate : propertiesUpdate )
{
pw.println( " " + propertyUpdate );
}
}
pw.close();
fw.close();
}
catch ( IOException e )
{
throw new MojoExecutionException( "Unable to write report file. ", e );
}
finally
{
if ( pw != null )
{
pw.close();
}
if ( fw != null )
{
try
{
fw.close();
}
catch ( IOException io )
{
// Ignore
}
}
}
}
/**
* Create a simple message describing the version diff
*
* @param dep
* @param remoteVersion
* @return The message
*/
private StringBuilder writeDependencyDiffMessage( Dependency dep, String remoteVersion )
{
String id = dep.getGroupId() + ":" + dep.getArtifactId();
return writeDiffMessage( id, dep.getVersion(), remoteVersion );
}
private StringBuilder writeDiffMessage( String id, String originalVersion, String targetVersion )
{
StringBuilder buf = new StringBuilder();
buf.append( id );
buf.append( ' ' );
int padding = INFO_PAD_SIZE - originalVersion.length() - targetVersion.length() - 4;
while ( buf.length() < padding )
{
buf.append( '.' );
}
buf.append( ' ' );
buf.append( originalVersion );
buf.append( " -> " );
buf.append( targetVersion );
return buf;
}
/**
* Add a list of dependencies to a Map for easy access
*
* @param map
* @param deps
*/
private void mapDependencies( Map map, List deps )
{
if ( deps != null )
{
for ( Dependency nextDep : deps )
{
map.put( nextDep.getManagementKey(), nextDep );
}
}
}
/**
* Creates a key that is similar to what {@link Dependency#getManagementKey()} generates for a dependency.
*/
private static String generateId( Artifact artifact )
{
StringBuilder sb = new StringBuilder();
sb.append( artifact.getGroupId() ).append( ":" ).append( artifact.getArtifactId() ).append( ":" ).append( artifact.getType() );
if ( artifact.getClassifier() != null )
{
sb.append( ":" ).append( artifact.getClassifier() );
}
return sb.toString();
}
}