All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.mojo.versions.SwitchMojo Maven / Gradle / Ivy

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.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.stream.XMLStreamException;

import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.model.Dependency;
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.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.codehaus.mojo.versions.api.PomHelper;
import org.codehaus.mojo.versions.change.VersionChange;
import org.codehaus.mojo.versions.change.VersionChanger;
import org.codehaus.mojo.versions.change.VersionChangerFactory;
import org.codehaus.mojo.versions.ordering.ReactorDepthComparator;
import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader;
import org.codehaus.mojo.versions.utils.ContextualLog;
import org.codehaus.mojo.versions.utils.DelegatingContextualLog;
import org.codehaus.plexus.util.StringUtils;

/**
 * Sets the current projects version, updating the details of any child modules as necessary.
 * 
 * @author axet based on Stephen Connolly
 */
public class SwitchMojo extends AbstractVersionsUpdaterMojo {

    /**
     * The new version number to set.
     * 
     * @parameter expression="${newVersion}"
     * @since 1.0-beta-1
     */
    @Parameter( property = "newVersion" )
    private String newVersion;

    /**
     * The changes to module coordinates. Guarded by this.
     */
    final transient List sourceChanges = new ArrayList();

    synchronized void addChange(String groupId, String artifactId, String oldVersion, String newVersion) {
        if (!newVersion.equals(oldVersion)) {
            VersionChange vv = new VersionChange(groupId, artifactId, oldVersion, newVersion);

            for (Object v : sourceChanges) {
                VersionChange q = (VersionChange) v;
                if (q.getGroupId().equals(groupId) && q.getArtifactId().equals(artifactId)
                        && q.getOldVersion().equals(oldVersion))
                    return;
            }

            sourceChanges.add(vv);
        }
    }

    static String incrementVersion(String version) {
        String[] vv = version.split("\\.");
        Integer v = Integer.parseInt(vv[vv.length - 1]);
        v++;

        String newVersion = "";
        for (int i = 0; i < vv.length - 1; i++) {
            newVersion += vv[i] + ".";
        }
        newVersion += v;

        return newVersion;
    }

    synchronized String updateSuffix(String groupId, String artifactId, String version) {
        return version;
    }

    synchronized String incrementModuleVersion(String groupId, String artifactId, String version) {
        return version;
    }

    /**
     * Called when this mojo is executed.
     * 
     * @throws org.apache.maven.plugin.MojoExecutionException
     *             when things go wrong.
     * @throws org.apache.maven.plugin.MojoFailureException
     *             when things go wrong.
     */
    public void execute() throws MojoExecutionException, MojoFailureException {
        if (!StringUtils.isEmpty(getNewVersion())) {
            addChange(getProject().getGroupId(), getProject().getArtifactId(), getProject().getVersion(),
                    getNewVersion());

            processAllDeps(getProject().getGroupId(), getProject().getArtifactId(), getProject().getVersion());

            updateModuleVersion(getProject().getGroupId(), getProject().getArtifactId(), getProject().getVersion(),
                    getNewVersion());
        }

        processAllModules();
        processAll();
    }

    public void processAllDeps(String groupId, String artifactId, String version) throws MojoExecutionException, MojoFailureException {
        try {
            final MavenProject project = PomHelper.getLocalRoot(projectBuilder, getProject(), localRepository, null,
                    getLog());

            getLog().info("Process All Modules Local aggregation root: " + project.getBasedir());
            final Map reactor = PomHelper.getReactorModels(project, getLog());

            final List order = new ArrayList(reactor.keySet());
            Collections.sort(order, new ReactorDepthComparator(reactor));

            final Iterator i = order.iterator();
            while (i.hasNext()) {
                final String sourcePath = (String) i.next();
                final Model sourceModel = (Model) reactor.get(sourcePath);

                getLog().debug(
                        sourcePath.length() == 0 ? "Process All Modules Processing root module as parent"
                                : "Processing " + sourcePath + " as a parent.");

                final String sourceGroupId = PomHelper.getGroupId(sourceModel);
                if (sourceGroupId == null) {
                    getLog().warn("Module " + sourcePath + " is missing a groupId.");
                    continue;
                }
                final String sourceArtifactId = PomHelper.getArtifactId(sourceModel);
                if (sourceArtifactId == null) {
                    getLog().warn("Module " + sourcePath + " is missing an artifactId.");
                    continue;
                }
                final String sourceVersion = PomHelper.getVersion(sourceModel);
                if (sourceVersion == null) {
                    getLog().warn("Module " + sourcePath + " is missing a version.");
                    continue;
                }

                if (PomHelper.isExplicitVersion(sourceModel)) {
                    List dd = sourceModel.getDependencies();
                    for (Dependency d : dd) {
                        if (d.getArtifactId().equals(artifactId) && d.getGroupId().equals(groupId)
                                && d.getVersion().equals(version)) {
                            String newVersion2 = incrementModuleVersion(PomHelper.getGroupId(sourceModel),
                                    PomHelper.getArtifactId(sourceModel), PomHelper.getVersion(sourceModel));
                            if (!newVersion2.equals(sourceModel.getVersion())) {
                                updateModuleVersion(PomHelper.getGroupId(sourceModel),
                                        PomHelper.getArtifactId(sourceModel), PomHelper.getVersion(sourceModel),
                                        newVersion2);
                            }
                        }
                    }
                }
            }
        } catch (IOException e) {
            throw new MojoExecutionException(e.getMessage(), e);
        }
    }

    public void processAllModules() throws MojoExecutionException, MojoFailureException {
        try {
            final MavenProject project = PomHelper.getLocalRoot(projectBuilder, getProject(), localRepository, null,
                    getLog());

            getLog().info("Process All Modules Local aggregation root: " + project.getBasedir());
            final Map reactor = PomHelper.getReactorModels(project, getLog());

            final List order = new ArrayList(reactor.keySet());
            Collections.sort(order, new ReactorDepthComparator(reactor));

            final Iterator i = order.iterator();
            while (i.hasNext()) {
                final String sourcePath = (String) i.next();
                final Model sourceModel = (Model) reactor.get(sourcePath);

                getLog().debug(
                        sourcePath.length() == 0 ? "Process All Modules Processing root module as parent"
                                : "Processing " + sourcePath + " as a parent.");

                final String sourceGroupId = PomHelper.getGroupId(sourceModel);
                if (sourceGroupId == null) {
                    getLog().warn("Module " + sourcePath + " is missing a groupId.");
                    continue;
                }
                final String sourceArtifactId = PomHelper.getArtifactId(sourceModel);
                if (sourceArtifactId == null) {
                    getLog().warn("Module " + sourcePath + " is missing an artifactId.");
                    continue;
                }
                final String sourceVersion = PomHelper.getVersion(sourceModel);
                if (sourceVersion == null) {
                    getLog().warn("Module " + sourcePath + " is missing a version.");
                    continue;
                }

                String newVersion = updateSuffix(PomHelper.getGroupId(sourceModel),
                        PomHelper.getArtifactId(sourceModel), PomHelper.getVersion(sourceModel));

                updateModuleVersion(PomHelper.getGroupId(sourceModel), PomHelper.getArtifactId(sourceModel),
                        PomHelper.getVersion(sourceModel), newVersion);
            }
        } catch (IOException e) {
            throw new MojoExecutionException(e.getMessage(), e);
        }
    }

    final Set files = new LinkedHashSet();

    public void updateModuleVersion(String groupId, String artifactId, String version, String newVersion)
            throws MojoExecutionException, MojoFailureException {
        // this is the triggering change
        addChange(groupId, artifactId, version, newVersion);

        try {
            final MavenProject project = PomHelper.getLocalRoot(projectBuilder, getProject(), localRepository, null,
                    getLog());

            getLog().info("Local aggregation root: " + project.getBasedir());
            final Map reactor = PomHelper.getReactorModels(project, getLog());

            // now fake out the triggering change
            final Model current = PomHelper.getModel(reactor, getProject().getGroupId(), getProject().getArtifactId());
            current.setVersion(newVersion);

            files.add(getProject().getFile());

            final List order = new ArrayList(reactor.keySet());
            Collections.sort(order, new ReactorDepthComparator(reactor));

            final Iterator i = order.iterator();
            while (i.hasNext()) {
                final String sourcePath = (String) i.next();
                final Model sourceModel = (Model) reactor.get(sourcePath);

                getLog().debug(
                        sourcePath.length() == 0 ? "Processing root module as parent" : "Processing " + sourcePath
                                + " as a parent.");

                final String sourceGroupId = PomHelper.getGroupId(sourceModel);
                if (sourceGroupId == null) {
                    getLog().warn("Module " + sourcePath + " is missing a groupId.");
                    continue;
                }
                final String sourceArtifactId = PomHelper.getArtifactId(sourceModel);
                if (sourceArtifactId == null) {
                    getLog().warn("Module " + sourcePath + " is missing an artifactId.");
                    continue;
                }
                final String sourceVersion = PomHelper.getVersion(sourceModel);
                if (sourceVersion == null) {
                    getLog().warn("Module " + sourcePath + " is missing a version.");
                    continue;
                }

                final File moduleDir = new File(project.getBasedir(), sourcePath);

                final 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;
                }

                files.add(moduleProjectFile);

                getLog().debug(
                        "Looking for modules which use "
                                + ArtifactUtils.versionlessKey(sourceGroupId, sourceArtifactId) + " as their parent");

                final Iterator j = PomHelper.getChildModels(reactor, sourceGroupId, sourceArtifactId).entrySet()
                        .iterator();

                while (j.hasNext()) {
                    final Map.Entry target = (Map.Entry) j.next();
                    final String targetPath = (String) target.getKey();
                    final Model targetModel = (Model) target.getValue();
                    final Parent parent = targetModel.getParent();
                    getLog().debug("Module: " + targetPath);
                    if (sourceVersion.equals(parent.getVersion())) {
                        getLog().debug(
                                "    parent already is "
                                        + ArtifactUtils.versionlessKey(sourceGroupId, sourceArtifactId) + ":"
                                        + sourceVersion);
                    } else {
                        getLog().debug(
                                "    parent is " + ArtifactUtils.versionlessKey(sourceGroupId, sourceArtifactId) + ":"
                                        + parent.getVersion());
                        getLog().debug(
                                "    will become " + ArtifactUtils.versionlessKey(sourceGroupId, sourceArtifactId)
                                        + ":" + sourceVersion);
                    }
                    final boolean targetExplicit = PomHelper.isExplicitVersion(targetModel);
                    Boolean updateMatchingVersions = true;
                    if ((updateMatchingVersions.booleanValue() || !targetExplicit)
                            && StringUtils.equals(parent.getVersion(), PomHelper.getVersion(targetModel))) {
                        getLog().debug(
                                "    module is "
                                        + ArtifactUtils.versionlessKey(PomHelper.getGroupId(targetModel),
                                                PomHelper.getArtifactId(targetModel)) + ":"
                                        + PomHelper.getVersion(targetModel));
                        getLog().debug(
                                "    will become "
                                        + ArtifactUtils.versionlessKey(PomHelper.getGroupId(targetModel),
                                                PomHelper.getArtifactId(targetModel)) + ":" + sourceVersion);
                        addChange(PomHelper.getGroupId(targetModel), PomHelper.getArtifactId(targetModel),
                                PomHelper.getVersion(targetModel), sourceVersion);
                        targetModel.setVersion(sourceVersion);
                    } else {
                        getLog().debug(
                                "    module is "
                                        + ArtifactUtils.versionlessKey(PomHelper.getGroupId(targetModel),
                                                PomHelper.getArtifactId(targetModel)) + ":"
                                        + PomHelper.getVersion(targetModel));
                    }
                }
            }
        } catch (IOException e) {
            throw new MojoExecutionException(e.getMessage(), e);
        }
    }

    void processAll() throws MojoExecutionException, MojoFailureException {
        // now process all the updates
        final Iterator k = files.iterator();
        while (k.hasNext()) {
            process((File) k.next());
        }
    }

    /**
     * Updates the pom file.
     * 
     * @param pom
     *            The pom file to update.
     * @throws org.apache.maven.plugin.MojoExecutionException
     *             when things go wrong.
     * @throws org.apache.maven.plugin.MojoFailureException
     *             when things go wrong.
     * @throws javax.xml.stream.XMLStreamException
     *             when things go wrong.
     */
    protected synchronized void update(ModifiedPomXMLEventReader pom) throws MojoExecutionException,
            MojoFailureException, XMLStreamException {
        ContextualLog log = new DelegatingContextualLog(getLog());
        try {
            Model model = PomHelper.getRawModel(pom);
            log.setContext("Processing " + PomHelper.getGroupId(model) + ":" + PomHelper.getArtifactId(model));

            VersionChangerFactory versionChangerFactory = new VersionChangerFactory();
            versionChangerFactory.setPom(pom);
            versionChangerFactory.setLog(log);
            versionChangerFactory.setModel(model);

            boolean processParent = true;
            boolean processProject = true;
            boolean processDependencies = true;
            boolean processPlugins = true;

            VersionChanger changer = versionChangerFactory.newVersionChanger(processParent, processProject,
                    processDependencies, processPlugins);

            Iterator i = sourceChanges.iterator();
            while (i.hasNext()) {
                VersionChange versionChange = (VersionChange) i.next();
                changer.apply(versionChange);
            }
        } catch (IOException e) {
            throw new MojoExecutionException(e.getMessage(), e);
        }
        log.clearContext();
    }

    public String getNewVersion() {
        return newVersion;
    }

    public void setNewVersion(String newVersion) {
        this.newVersion = newVersion;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy