/*
* 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.
*/
package org.codehaus.mojo.pom;
import java.util.List;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.w3c.dom.Element;
/**
*
* @author Joerg Hohwiller (hohwille at users.sourceforge.net)
* @goal refactor
* @aggregator
* @requiresProject true
* @requiresDirectInvocation false
* @executionStrategy once-per-session
* @since 1.0.0
*/
public class PomRefactorMojo extends AbstractPomModifyMojo {
/**
* The new groupId to apply.
*
* @parameter expression="${newGroupId}"
* @since 1.0.0
*/
private String newGroupId;
/**
* The new artifactId to apply.
*
* @parameter expression="${newArtifactId}"
* @since 1.0.0
*/
private String newArtifactId;
/**
* The new version to apply.
*
* @parameter expression="${newVersion}"
* @since 1.0.0
*/
private String newVersion;
/**
* The new type to apply.
*
* @parameter expression="${newType}"
* @since 1.0.0
*/
private String newType;
/**
* The new scope to apply.
*
* @parameter expression="${newScope}"
* @since 1.0.0
*/
private String newScope;
/**
* The new classifier to apply.
*
* @parameter expression="${newClassifier}"
* @since 1.0.0
*/
private String newClassifier;
/**
* The flag to indicate if properties should be resolved for matching. If a
* <code>pom.xml</code> contains
* <code><version>${foo.version}</version></code> and
* <code>resolveVariables</code> is <code>true</code>, then the property
* <code>foo.version</code> is resolved and in case of a replacement, the
* property-value is replaced where declared while the reference remains
* untouched. Otherwise, the property is treated literally in order to be able
* to replace the property reference (<code>${foo.version}</code>) with a new
* value.
*
* @parameter expression="${resolveVariables}" default-value="true"
* @required
* @since 1.0.0
*/
private boolean resolveVariables;
// ----------------------------------------------------------------------
// Mojo fields
// ----------------------------------------------------------------------
/** The new classifier to apply. */
private DependencyInfo newAttributes;
protected DependencyInfo getNewAttributes() {
if (this.newAttributes == null) {
this.newAttributes = new DependencyInfo(this.newGroupId, this.newArtifactId, this.newVersion,
this.newType, this.newScope, this.newClassifier);
}
return this.newAttributes;
}
protected void updateDependencies(List<Dependency> dependencyList,
ProjectContainer projectContainer, String tagname) throws MojoExecutionException,
MojoFailureException {
for (Dependency dependency : dependencyList) {
if (getMatcher().isMatching(dependency)) {
DependencyInfo delta = getNewAttributes().getDiff(dependency);
if (!delta.isEmpty()) {
getLog().info(
"Chaning dependency " + new DependencyInfo(dependency) + " to "
+ delta.toDiffString());
// try to find dependency in XML
List<Element> dependencyElementList;
if (ProjectContainer.XML_TAG_DEPENDENCIES.equals(tagname)) {
dependencyElementList = projectContainer.getPomDependenciesList();
} else if (ProjectContainer.XML_TAG_DEPENDENCY_MANAGEMENT.equals(tagname)) {
dependencyElementList = projectContainer.getPomDependencyManagementList();
} else {
throw new MojoExecutionException("Internal Error: Unknown dependency tagname '"
+ tagname + "'!");
}
boolean notFound = true;
for (Element elementDependency : dependencyElementList) {
DependencyInfo dependencyInfo = projectContainer.createDependencyInfo(
elementDependency, this.resolveVariables);
getLog().debug("Checking dependency '" + dependencyInfo + "' ...");
if (dependencyInfo.isMatching(dependency)) {
getLog().debug("Found dependency in pom.xml: " + dependencyInfo);
notFound = false;
if (delta.getGroupId() != null) {
updateValue(elementDependency, ProjectContainer.XML_TAG_GROUPID, projectContainer,
delta.getGroupId());
}
if (delta.getArtifactId() != null) {
updateValue(elementDependency, ProjectContainer.XML_TAG_ARTIFACTID,
projectContainer, delta.getArtifactId());
}
if (delta.getVersion() != null) {
updateValue(elementDependency, ProjectContainer.XML_TAG_VERSION, projectContainer,
delta.getVersion());
}
if (delta.getType() != null) {
updateValue(elementDependency, ProjectContainer.XML_TAG_TYPE, projectContainer,
delta.getType());
}
if (delta.getScope() != null) {
updateValue(elementDependency, ProjectContainer.XML_TAG_SCOPE, projectContainer,
delta.getScope());
}
if (delta.getClassifier() != null) {
updateValue(elementDependency, ProjectContainer.XML_TAG_CLASSIFIER,
projectContainer, delta.getClassifier());
}
}
}
if (notFound) {
getLog().warn("Dependency NOT found in pom.xml");
}
}
}
}
}
protected void updateValue(Element containerElement, String valueTagname,
ProjectContainer projectContainer, String newValue) throws MojoExecutionException,
MojoFailureException {
Element elementValue = DomUtilities.getChildElement(containerElement, valueTagname);
if (elementValue != null) {
String currentValue = elementValue.getTextContent();
if (currentValue.startsWith(ProjectContainer.PROPERTY_PREFIX)) {
String propertyName = currentValue.substring(ProjectContainer.PROPERTY_PREFIX.length(),
currentValue.length() - ProjectContainer.PROPERTY_SUFFIX.length());
if (propertyName.startsWith(ProjectContainer.PROPERTY_PREFIX_POM)
|| propertyName.startsWith(ProjectContainer.PROPERTY_PREFIX_PROJECT)) {
getLog().debug("Keeping internal property '" + propertyName + "' ...");
} else {
projectContainer.updatePropertyValue(propertyName, newValue);
}
} else {
String oldValue = elementValue.getTextContent();
elementValue.setTextContent(newValue);
getLog().debug(
"Updating '" + valueTagname + "' of '" + projectContainer.getId() + "' from '"
+ oldValue + "' to '" + newValue + "'.");
projectContainer.setModified();
}
}
}
protected void updateProject(ProjectContainer projectContainer, MavenProject project,
boolean parent) throws MojoExecutionException, MojoFailureException {
if (getMatcher().isMatching(project)) {
DependencyInfo delta = getNewAttributes().getDiff(project);
if (!delta.isEmpty()) {
String source;
if (parent) {
source = "parent";
} else {
source = "project";
}
getLog().info("Changing " + source + " " + project.getId() + " to " + delta.toDiffString());
Element elementProject = projectContainer.getPomDocument().getDocumentElement();
if (parent) {
elementProject = DomUtilities.getChildElement(elementProject,
ProjectContainer.XML_TAG_PARENT);
}
if (delta.getGroupId() != null) {
updateValue(elementProject, ProjectContainer.XML_TAG_GROUPID, projectContainer, delta
.getGroupId());
}
if (delta.getArtifactId() != null) {
updateValue(elementProject, ProjectContainer.XML_TAG_ARTIFACTID, projectContainer, delta
.getArtifactId());
}
if (delta.getVersion() != null) {
updateValue(elementProject, ProjectContainer.XML_TAG_VERSION, projectContainer, delta
.getVersion());
}
}
}
}
/**
* {@inheritDoc}
*/
@Override
@SuppressWarnings("unchecked")
public void execute(ProjectContainer projectContainer) throws MojoExecutionException,
MojoFailureException {
if (getNewAttributes().isEmpty()) {
throw new MojoExecutionException(
"At least one of the new*-parameters (newVersion, newArtifactId, newGroupId, newScope or newClassifier) have to be configured!");
}
super.execute(projectContainer);
MavenProject project = projectContainer.getProject();
updateProject(projectContainer, project, false);
MavenProject parent = project.getParent();
if (parent != null) {
updateProject(projectContainer, parent, true);
}
updateDependencies(project.getDependencies(), projectContainer,
ProjectContainer.XML_TAG_DEPENDENCIES);
DependencyManagement dependencyManagement = project.getDependencyManagement();
if (dependencyManagement != null) {
updateDependencies(dependencyManagement.getDependencies(), projectContainer,
ProjectContainer.XML_TAG_DEPENDENCY_MANAGEMENT);
}
}
}