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.artifact.ArtifactUtils; import org.apache.maven.model.Model; import org.apache.maven.model.Parent; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.codehaus.mojo.versions.api.PomHelper; import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; import javax.xml.stream.XMLStreamException; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Map; /** * Scans the current projects child modules, updating the versions of any which use the current project to * the version of the current project. * * @author Stephen Connolly * @goal update-child-modules * @aggregator * @requiresProject true * @requiresDirectInvocation true * @since 1.0-alpha-2 */ public class UpdateChildModulesMojo extends AbstractVersionsUpdaterMojo { /** * The groupId that we are updating. Guarded by this. */ private transient String sourceGroupId = null; /** * The artifactId that we are updating. Guarded by this. */ private transient String sourceArtifactId = null; /** * The version that we are updating to. Guarded by this. */ private transient String sourceVersion = null; /** * Called when this mojo is executed. * * @throws MojoExecutionException when things go wrong. * @throws MojoFailureException when things go wrong. */ public void execute() throws MojoExecutionException, MojoFailureException { boolean didSomething = false; try { final Map reactor = PomHelper.getReactorModels( getProject(), getLog() ); List order = new ArrayList( reactor.keySet() ); Collections.sort( order, new Comparator() { public int compare( Object o1, Object o2 ) { Model m1 = (Model) reactor.get( o1 ); Model m2 = (Model) reactor.get( o2 ); int d1 = PomHelper.getReactorParentCount( reactor, m1 ); int d2 = PomHelper.getReactorParentCount( reactor, m2 ); if ( d1 < d2 ) { return -1; } else if ( d1 > d2 ) { return 1; } return 0; } } ); Iterator i = order.iterator(); while ( i.hasNext() ) { String sourcePath = (String) i.next(); Model sourceModel = (Model) reactor.get( sourcePath ); getLog().debug( sourcePath.length() == 0 ? "Processing root module as parent" : "Processing " + sourcePath + " as a parent." ); synchronized ( this ) { sourceGroupId = PomHelper.getGroupId( sourceModel ); if ( sourceGroupId == null ) { getLog().warn( "Module " + sourcePath + " is missing a groupId." ); continue; } sourceArtifactId = PomHelper.getArtifactId( sourceModel ); if ( sourceArtifactId == null ) { getLog().warn( "Module " + sourcePath + " is missing an artifactId." ); continue; } sourceVersion = PomHelper.getVersion( sourceModel ); if ( sourceVersion == null ) { getLog().warn( "Module " + sourcePath + " is missing a version." ); continue; } getLog().debug( "Looking for modules which use " + ArtifactUtils.versionlessKey( sourceGroupId, sourceArtifactId ) + " as their parent" ); Iterator j = PomHelper.getChildModels( reactor, sourceGroupId, sourceArtifactId ).entrySet().iterator(); while ( j.hasNext() ) { Map.Entry target = (Map.Entry) j.next(); String targetPath = (String) target.getKey(); File moduleDir = new File( getProject().getBasedir(), targetPath ); File moduleProjectFile; if ( moduleDir.isDirectory() ) { moduleProjectFile = new File( moduleDir, "pom.xml" ); } else { // i don't think this should ever happen... but just in case // the module references the file-name moduleProjectFile = moduleDir; } Model targetModel = (Model) target.getValue(); final Parent parent = targetModel.getParent(); if ( sourceVersion.equals( parent.getVersion() ) ) { getLog().debug( "Module: " + targetPath + " parent is " + ArtifactUtils.versionlessKey( sourceGroupId, sourceArtifactId ) + ":" + sourceVersion ); } else { getLog().info( "Module: " + targetPath ); getLog().info( " parent was " + ArtifactUtils.versionlessKey( sourceGroupId, sourceArtifactId ) + ":" + parent.getVersion() ); getLog().info( " updated to " + ArtifactUtils.versionlessKey( sourceGroupId, sourceArtifactId ) + ":" + sourceVersion ); process( moduleProjectFile ); // don't forget to update the cached model targetModel.setVersion( sourceVersion ); didSomething = true; } } } } } catch ( IOException e ) { throw new MojoExecutionException( e.getMessage(), e ); } if ( !didSomething ) { getLog().info( "All child modules are up to date." ); } } /** * Updates the pom file. * * @param pom The pom file to update. * @throws MojoExecutionException when things go wrong. * @throws MojoFailureException when things go wrong. * @throws XMLStreamException when things go wrong. */ protected synchronized void update( ModifiedPomXMLEventReader pom ) throws MojoExecutionException, MojoFailureException, XMLStreamException { getLog().debug( "Updating parent to " + sourceVersion ); if ( PomHelper.setProjectParentVersion( pom, sourceVersion ) ) { getLog().debug( "Made an update to " + sourceVersion ); } } }