
org.kuali.maven.plugins.fusion.MojoHelper Maven / Gradle / Ivy
/**
* Copyright 2011-2014 The Kuali Foundation
*
* Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
*
* 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.kuali.maven.plugins.fusion;
import static org.apache.commons.io.filefilter.FileFilterUtils.and;
import static org.apache.commons.io.filefilter.FileFilterUtils.directoryFileFilter;
import static org.apache.commons.io.filefilter.FileFilterUtils.nameFileFilter;
import static org.apache.commons.io.filefilter.FileFilterUtils.notFileFilter;
import java.io.File;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.swing.tree.DefaultMutableTreeNode;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.FileFilterUtils;
import org.apache.commons.io.filefilter.IOFileFilter;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugin.Mojo;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.kuali.common.util.KeyValue;
import org.kuali.common.util.Version;
import org.kuali.common.util.VersionUtils;
import org.kuali.maven.plugins.fusion.data.IUpdateTagMojoData;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
public class MojoHelper {
private static final String TAG_NAME_DELIMETER = "_";
private static final String QUALIFIER_DELIMETER = "-";
private static final String MAVEN_SNAPSHOT_TOKEN = "SNAPSHOT";
private static final char[] DIGITS = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
private static final String majorQualifierFoundersReleasePrefix = "FR";
private static final String minorQualiferMilestonePrefix = "M";
private static final String minorQualiferReleaseCandidatePrefix = "RC";
SVNUtils svnUtils = SVNUtils.getInstance();
POMUtils pomUtils = new POMUtils();
NumberFormat nf = NumberFormat.getInstance();
private final Log logger;
protected static MojoHelper instance;
protected MojoHelper(Mojo mojo) {
super();
nf.setMaximumFractionDigits(3);
nf.setMinimumFractionDigits(3);
nf.setGroupingUsed(false);
logger = mojo.getLog();
}
public synchronized static MojoHelper getInstance(Mojo mojo) {
if (instance == null) {
instance = new MojoHelper(mojo);
}
return instance;
}
public void incrementVersions(IUpdateTagMojoData mojo) throws MojoFailureException {
List mappings = mojo.getMappings();
// Make sure the modules listed in the pom match the svn:externals definitions and the mappings provided in the plugin config
validate(mojo.getProject(), mojo.getMappings(), mojo.ignoreNoMappingsPresent());
if (mojo.getMappings() == null && mojo.ignoreNoMappingsPresent())
mappings = new ArrayList();
List files = getPoms(mojo.getProject().getBasedir(), mojo.getPom(), mojo.getIgnoreDirectories());
List nodes = getNodes(files);
DefaultMutableTreeNode node = getTree(mojo.getProject().getBasedir(), nodes, mojo.getPom());
incrementVersions(node);
updateGavs(node);
updateProperties(node, mojo.getProject().getProperties(), mappings);
updateXml(node);
writePoms(node, mojo.getProject().getBasedir());
logger.info("Committing pom changes");
}
public void updateProjectProperties (MavenProject project, ListpropertyUpdates) {
List files = getPoms(project.getBasedir(), FusionMavenPluginConstants.FUSION_POM_DEFAULT, FusionMavenPluginConstants.FUSION_IGNORE_DIRS_DEFAULT);
List nodes = getNodes(files);
DefaultMutableTreeNode node = getTree(project.getBasedir(), nodes, FusionMavenPluginConstants.FUSION_POM_DEFAULT);
Properties properties = new Properties();
// update the property value.
for (KeyValue kv : propertyUpdates) {
properties.put(kv.getKey(), kv.getValue());
}
updateProperties(node, properties);
updateXml(node);
writePoms(node, project.getBasedir());
}
public void updateProjectLinkedProperties (MavenProject mavenProject, DefaultMutableTreeNode rootNode, ListlinkedPropertyNames, TagStyle tagStyle, String buildText, int buildNumber) throws MojoFailureException {
if (tagStyle.equals(TagStyle.INCREMENT))
return;
ListpropertyUpdates = new ArrayList();
Project project = (Project) rootNode.getUserObject();
for (String propertyName : linkedPropertyNames) {
String version = mavenProject.getProperties().getProperty(propertyName);
if (version == null)
throw new MojoFailureException("No property found for : " + propertyName);
String updatedVersion = null;
if (tagStyle.equals(TagStyle.BUILD_NUMBER))
updatedVersion = getBuildVersion(version, buildText, buildNumber);
else if (tagStyle.equals(TagStyle.RELEASE))
updatedVersion = version.replaceFirst("-SNAPSHOT", "");
propertyUpdates.add(new KeyValue(propertyName, updatedVersion));
}
updateProjectProperties(mavenProject, propertyUpdates);
}
private String getBuildVersion(String version, String buildText, int buildNumber) {
Version v = parseVersion(version);
StringBuilder sb = new StringBuilder();
sb.append(v.getMajor());
sb.append(".");
sb.append(v.getMinor());
sb.append(".");
sb.append(v.getIncremental());
String qualifier = v.getQualifier();
if (qualifier != null && !qualifier.isEmpty()) {
sb.append("-");
sb.append(qualifier);
}
sb.append("-");
sb.append(buildText);
sb.append("-");
sb.append(buildNumber);
return sb.toString();
}
protected List getChildren(DefaultMutableTreeNode node) {
Enumeration> e = node.children();
List children = new ArrayList();
while (e.hasMoreElements()) {
DefaultMutableTreeNode child = (DefaultMutableTreeNode) e.nextElement();
children.add(child);
}
return children;
}
public void incrementVersions(DefaultMutableTreeNode node) {
Project project = (Project) node.getUserObject();
GAV gav = project.getGav();
String oldVersion = gav.getVersion();
if (!StringUtils.isBlank(oldVersion)) {
String newVersion = getNextVersion(oldVersion);
GAV newGav = new GAV();
newGav.setGroupId(gav.getGroupId());
newGav.setArtifactId(gav.getArtifactId());
newGav.setVersion(newVersion);
project.setNewGav(newGav);
logger.info(StringUtils.repeat(" ", node.getLevel()) + gav.getArtifactId() + ":" + gav.getArtifactId() + ":" + oldVersion + "->" + newVersion);
}
List children = getChildren(node);
for (DefaultMutableTreeNode child : children) {
incrementVersions(child);
}
}
public String createAndUpdateTags(IUpdateTagMojoData mojo) throws MojoFailureException {
String buildText = mojo.getBuildText();
// Extract the Jenkins build number. Defaults to zero if no BUILD_NUMBER is set
int buildNumber = getBuildNumber(mojo.getProject(), mojo.getBuildNumberProperty());
// Create a GAV object from the Maven project
GAV gav = getGav(mojo.getProject());
// Scan the file system for pom.xml files
List files = getPoms(mojo.getProject().getBasedir(), mojo.getPom(), mojo.getIgnoreDirectories());
// Convert the list of files into a list of node objects
List nodes = getNodes(files);
// Build a tree from the list
DefaultMutableTreeNode node = getTree(mojo.getProject().getBasedir(), nodes, mojo.getPom());
List mappings = mojo.getMappings();
// Make sure the modules listed in the pom match the svn:externals definitions and the mappings provided in the plugin config
validate(mojo.getProject(), mojo.getMappings(), mojo.ignoreNoMappingsPresent());
if (mojo.getMappings() == null && mojo.ignoreNoMappingsPresent())
mappings = new ArrayList();
// Calculate the build tag for the root
BuildTag rootTag = getBuildTag(mojo.getProject().getBasedir(), gav, mojo.getTagStyle(), buildText, buildNumber);
// Update build info for the root node
updateBuildInfo(node, rootTag, mojo.getTagStyle(), buildText, buildNumber);
// Calculate build tags for each module
List moduleTags = getBuildTags(mojo.getProject().getProperties(), mappings, mojo.getTagStyle(), buildText, buildNumber);
// Update build information for nodes that represent an svn:external
updateBuildInfo(nodes, moduleTags, mappings, mojo.getTagStyle(), buildText, buildNumber);
// Recursively update the mojo.getProject() gav's and parent gav's
updateGavs(node);
// Recursively update the corresponding Maven pom's
updateXml(node);
// Update the properties in the root pom that hold version info for the modules
updateProperties(node, mojo.getProject().getProperties(), mappings);
writePoms(node, mojo.getProject().getBasedir());
// Update linkedProperties (run at end so we can rewrite the poms)
updateProjectLinkedProperties(mojo.getProject(), node, mojo.getLinkedVersionPropertyNames(), mojo.getTagStyle(), buildText, buildNumber);
return rootTag.getName();
}
public GAV getGav(MavenProject project) {
GAV gav = new GAV();
gav.setGroupId(project.getGroupId());
gav.setArtifactId(project.getArtifactId());
gav.setVersion(project.getVersion());
return gav;
}
public String toString(GAV gav) {
StringBuilder sb = new StringBuilder();
sb.append(gav.getGroupId());
sb.append(":");
sb.append(gav.getArtifactId());
sb.append(":");
sb.append(gav.getVersion());
return sb.toString();
}
public String getGroupId(DefaultMutableTreeNode node) {
List projects = getProjectPath(node);
for (Project project : projects) {
GAV gav = project.getGav();
if (!StringUtils.isBlank(gav.getGroupId())) {
return gav.getGroupId();
}
}
throw new IllegalStateException("Unable to determine a version");
}
public String getVersion(DefaultMutableTreeNode node) {
List projects = getProjectPath(node);
for (Project project : projects) {
GAV gav = project.getGav();
if (!StringUtils.isBlank(gav.getVersion())) {
return gav.getVersion();
}
}
throw new IllegalStateException("Unable to determine a version");
}
protected List getProjectPath(DefaultMutableTreeNode node) {
Object[] projectObjects = node.getUserObjectPath();
List projects = new ArrayList();
for (Object projectObject : projectObjects) {
projects.add((Project) projectObject);
}
Collections.reverse(projects);
return projects;
}
public String getDisplayString(DefaultMutableTreeNode node) {
Project project = (Project) node.getUserObject();
GAV gav = project.getGav();
GAV parent = project.getParent();
int level = node.getLevel();
StringBuilder sb = new StringBuilder();
sb.append(StringUtils.repeat(" ", level));
sb.append(toString(parent));
sb.append(" -> ");
sb.append(toString(gav));
sb.append("\n");
Enumeration> children = node.children();
while (children.hasMoreElements()) {
DefaultMutableTreeNode child = (DefaultMutableTreeNode) children.nextElement();
sb.append(getDisplayString(child));
}
return sb.toString();
}
public String getDisplayString(DefaultMutableTreeNode node, File basedir, String pomFile) {
Project project = (Project) node.getUserObject();
File pom = project.getPom();
String pomPath = pom.getAbsolutePath();
String displayPath = pomPath.replace(basedir.getAbsolutePath(), "");
displayPath = displayPath.replace(pomFile, "");
if (!node.isRoot()) {
displayPath = displayPath.substring(0, displayPath.length() - 1);
int pos = displayPath.lastIndexOf(File.separator);
displayPath = displayPath.substring(pos);
displayPath = displayPath.replace(TAG_NAME_DELIMETER, "");
}
int level = node.getLevel();
StringBuilder sb = new StringBuilder();
sb.append(StringUtils.repeat(" ", level));
sb.append(displayPath);
sb.append("\n");
Enumeration> children = node.children();
while (children.hasMoreElements()) {
DefaultMutableTreeNode child = (DefaultMutableTreeNode) children.nextElement();
sb.append(getDisplayString(child, basedir, pomFile));
}
return sb.toString();
}
/**
* Convert each pom.xml into a Project
object and then store each Project
as the user object in a
* DefaultMutableTreeNode
*/
protected List getNodes(List files) {
List nodes = new ArrayList();
for (File file : files) {
String pomContents = read(file);
GAV parent = pomUtils.getParentGAV(pomContents);
GAV gav = pomUtils.getGAV(pomContents);
Project project = new Project();
project.setPom(file);
project.setPomContents(pomContents);
project.setGav(gav);
project.setParent(parent);
DefaultMutableTreeNode node = new DefaultMutableTreeNode(project);
nodes.add(node);
}
return nodes;
}
public Map getMap(List nodes) {
Map map = new HashMap();
for (DefaultMutableTreeNode node : nodes) {
Project project = (Project) node.getUserObject();
File file = project.getPom();
map.put(file.getAbsolutePath(), node);
}
return map;
}
/**
* Assemble the list of nodes into a tree, based on the directory structure.
*/
public DefaultMutableTreeNode getTree(File basedir, List nodes, String pomFile) {
Map map = getMap(nodes);
for (DefaultMutableTreeNode child : nodes) {
Project project = (Project) child.getUserObject();
File pom = project.getPom();
File pomDir = pom.getParentFile();
File parentPom = new File(pomDir.getParentFile(), pomFile);
String parentPomPath = parentPom.getAbsolutePath();
DefaultMutableTreeNode parent = map.get(parentPomPath);
if (parent != null) {
parent.add(child);
}
}
String rootPom = basedir + File.separator + pomFile;
DefaultMutableTreeNode root = map.get(rootPom);
return root;
}
protected IOFileFilter getIgnoreDirectoryFilter(String dir) {
return notFileFilter(and(directoryFileFilter(), nameFileFilter(dir)));
}
protected IOFileFilter getIgnoreDirectoriesFilter(String csv) {
return getIgnoreDirectoriesFilter(csv.split(","));
}
protected IOFileFilter getIgnoreDirectoriesFilter(String... directories) {
IOFileFilter[] filters = new IOFileFilter[directories.length];
for (int i = 0; i < filters.length; i++) {
String dir = directories[i].trim();
filters[i] = getIgnoreDirectoryFilter(dir);
}
return FileFilterUtils.and(filters);
}
public List getPoms(File basedir, String pomFile, String ignoreDirectoriesCSV) {
IOFileFilter fileFilter = nameFileFilter(pomFile);
IOFileFilter dirFilter = getIgnoreDirectoriesFilter(ignoreDirectoriesCSV);
List files = new ArrayList(FileUtils.listFiles(basedir, fileFilter, dirFilter));
Collections.sort(files);
return files;
}
public List getExternals(List moduleTags, List mappings) {
List externals = new ArrayList();
for (int i = 0; i < mappings.size(); i++) {
Mapping mapping = mappings.get(i);
SVNExternal external = new SVNExternal();
external.setPath(mapping.getModule());
externals.add(external);
}
return externals;
}
public boolean exists(String url) {
ResourceLoader loader = new DefaultResourceLoader();
Resource resource = loader.getResource(url);
return resource.exists();
}
// public void createTag(BuildTag buildTag, String message) {
// createTags(Collections.singletonList(buildTag), message);
// }
// public void createTags(List buildTags, String message) {
// for (BuildTag buildTag : buildTags) {
// boolean exists = exists(dst);
// if (exists) {
// logger.info("Skip existing tag [" + dst + "]");
// buildTag.setSkipped(true);
// } else {
//// SVNCommitInfo info = svnUtils.copy(src, revision, dst, message);
// logger.info("Created [" + dst + "]");
//// logger.debug("Comitted revision " + info.getNewRevision());
// }
// }
// }
public void updateExternalsFile(List externals, File externalsFile) {
StringBuilder sb = new StringBuilder();
for (SVNExternal external : externals) {
sb.append(external.getPath());
sb.append(" ");
sb.append(external.getUrl());
sb.append("\n");
}
write(externalsFile, sb.toString());
logger.info("Updated svn:externals control file - " + externalsFile.getAbsolutePath());
}
public void commitChanges(File dir, List externals, String msg) {
List workingCopyPaths = new ArrayList();
workingCopyPaths.add(dir);
for (SVNExternal external : externals) {
String path = dir.getAbsolutePath() + File.separator + external.getPath();
workingCopyPaths.add(new File(path));
}
File[] commitDirs = workingCopyPaths.toArray(new File[workingCopyPaths.size()]);
// SVNCommitInfo info = svnUtils.commit(commitDirs, msg, null, null);
// logger.info("Committed revision " + info.getNewRevision() + ".");
}
public void logTime(String msg, long elapsed) {
double millis = elapsed * 1.0D;
double millisPerSecond = 1000;
double millisPerMinute = 60 * millisPerSecond;
double millisPerHour = 60 * millisPerMinute;
if (millis > millisPerHour) {
logger.info(msg + nf.format(millis / millisPerHour) + "h");
} else if (millis > millisPerMinute) {
logger.info(msg + nf.format(millis / millisPerMinute) + "m");
} else {
logger.info(msg + nf.format(millis / millisPerSecond) + "s");
}
}
public void writePoms(DefaultMutableTreeNode node, File baseDir) {
int count = 0;
Enumeration> e = node.depthFirstEnumeration();
while (e.hasMoreElements()) {
DefaultMutableTreeNode element = (DefaultMutableTreeNode) e.nextElement();
Project project = (Project) element.getUserObject();
File pom = project.getPom();
String oldContents = read(pom);
String newContents = project.getPomContents();
if (!oldContents.equals(newContents)) {
logger.debug("Updating " + pom.getAbsolutePath());
write(pom, newContents);
count++;
}
}
logger.info("Updated " + count + " Maven pom's");
}
protected String getRelativePath(File dir, File file) {
String dirPath = dir.getAbsolutePath();
String filePath = file.getAbsolutePath();
return filePath.replace(dirPath, "");
}
public void updateScm(DefaultMutableTreeNode root, String scmUrlPrefix) {
// for now we don't need to do anything.
// once on github we could change the url to point at the tag
// https://github.com/kuali
// Project project = (Project) root.getUserObject();
// BuildTag buildTag = project.getBuildTag();
// String oldXml = project.getPomContents();
// String newXml = pomUtils.updateScm(oldXml, scmUrlPrefix, url);
// project.setPomContents(newXml);
}
protected String getGroupId(Project project) {
GAV gav = project.getGav();
GAV parent = project.getParent();
String groupId = gav.getGroupId();
String parentGroupId = parent.getGroupId();
if (!StringUtils.isBlank(groupId)) {
return groupId;
} else {
return parentGroupId;
}
}
protected String getVersion(Project project) {
GAV gav = project.getGav();
GAV parent = project.getParent();
String version = gav.getVersion();
String parentVersion = parent.getVersion();
if (!StringUtils.isBlank(version)) {
return version;
} else {
return parentVersion;
}
}
public void updateGavs(DefaultMutableTreeNode node) {
Project project = (Project) node.getUserObject();
if (project.getNewGav() != null) {
project.setGav(project.getNewGav());
}
Enumeration> children = node.children();
while (children.hasMoreElements()) {
DefaultMutableTreeNode child = (DefaultMutableTreeNode) children.nextElement();
Project childProject = (Project) child.getUserObject();
String oldParentVersion = childProject.getParent().getVersion();
String newParentVersion = getVersion(node);
if (!oldParentVersion.equals(newParentVersion)) {
childProject.getParent().setVersion(newParentVersion);
}
updateGavs(child);
}
}
public void updateProperties(DefaultMutableTreeNode node, Properties properties, List mappings) {
Project project = (Project) node.getUserObject();
Properties versionProperties = getVersionProperties(properties, mappings, node);
String oldXml = project.getPomContents();
String newXml = pomUtils.updateProperties(oldXml, versionProperties);
project.setPomContents(newXml);
}
public void updateProperties(DefaultMutableTreeNode node, Properties properties) {
Project project = (Project) node.getUserObject();
String oldXml = project.getPomContents();
String newXml = pomUtils.updateProperties(oldXml, properties);
project.setPomContents(newXml);
}
public Properties getVersionProperties(Properties properties, List mappings, DefaultMutableTreeNode node) {
Properties newProperties = new Properties();
for (Mapping mapping : mappings) {
String artifactId = mapping.getModule();
String key = mapping.getVersionProperty();
String oldValue = properties.getProperty(key);
if (StringUtils.isBlank(oldValue)) {
throw new IllegalStateException("No existing value for '" + key + "'");
}
DefaultMutableTreeNode moduleNode = findNode(node, artifactId);
String newValue = getVersion(moduleNode);
newProperties.setProperty(key, newValue);
}
return newProperties;
}
protected DefaultMutableTreeNode findNode(DefaultMutableTreeNode node, String artifactId) {
Enumeration> e = node.breadthFirstEnumeration();
while (e.hasMoreElements()) {
DefaultMutableTreeNode element = (DefaultMutableTreeNode) e.nextElement();
Project project = (Project) element.getUserObject();
GAV gav = project.getGav();
if (gav.getArtifactId().equals(artifactId)) {
return element;
}
}
throw new IllegalStateException("Unable to locate " + artifactId);
}
public void updateXml(DefaultMutableTreeNode node) {
Project project = (Project) node.getUserObject();
String version = project.getGav().getVersion();
if (!StringUtils.isBlank(version)) {
String oldXml = project.getPomContents();
String newXml = pomUtils.updateVersion(oldXml, version);
project.setPomContents(newXml);
}
String parentVersion = project.getParent().getVersion();
String oldXml = project.getPomContents();
String newXml = pomUtils.updateParentVersion(oldXml, parentVersion);
project.setPomContents(newXml);
Enumeration> children = node.children();
while (children.hasMoreElements()) {
DefaultMutableTreeNode child = (DefaultMutableTreeNode) children.nextElement();
updateXml(child);
}
}
protected void log(DefaultMutableTreeNode node) {
StringBuilder sb = new StringBuilder();
logger.info(sb.toString());
}
public Map getGavMap(DefaultMutableTreeNode node) {
Enumeration> e = node.breadthFirstEnumeration();
Map map = new HashMap();
while (e.hasMoreElements()) {
DefaultMutableTreeNode element = (DefaultMutableTreeNode) e.nextElement();
Project project = (Project) element.getUserObject();
GAV gav = project.getGav();
String gavId = toString(gav);
map.put(gavId, element);
}
return map;
}
public void validateMappings(Properties properties, List mappings, DefaultMutableTreeNode node) {
for (Mapping mapping : mappings) {
boolean valid = isValid(properties, mapping, node);
if (!valid) {
throw new IllegalStateException("Version mismatch on " + mapping.getModule());
}
}
}
public boolean isValid(Properties properties, Mapping mapping, DefaultMutableTreeNode node) {
DefaultMutableTreeNode match = findNode(node, mapping.getModule());
Project project = (Project) match.getUserObject();
GAV gav = project.getGav();
String propertyVersion = properties.getProperty(mapping.getVersionProperty());
String gavVersion = gav.getVersion();
if (propertyVersion.equals(gavVersion)) {
return true;
}
else {
logger.error(String.format("(artifactId, propertyVersion, gavVersion) = (%s, %s, %s)", project.getGav().getArtifactId(), propertyVersion, gavVersion));
return false;
}
}
public void validateParents(DefaultMutableTreeNode node, Map map) {
Enumeration> e = node.breadthFirstEnumeration();
while (e.hasMoreElements()) {
DefaultMutableTreeNode element = (DefaultMutableTreeNode) e.nextElement();
if (element.isRoot()) {
continue;
}
Project project = (Project) element.getUserObject();
GAV parentGav = project.getParent();
String parentGavId = toString(parentGav);
DefaultMutableTreeNode parent = map.get(parentGavId);
if (parent == null) {
throw new IllegalStateException(parentGavId + " could not be located");
}
}
}
public void fillInGavs(DefaultMutableTreeNode node) {
Project project = (Project) node.getUserObject();
GAV gav = project.getGav();
String groupId = getGroupId(node);
String version = getVersion(node);
if (gav.getGroupId() == null) {
gav.setGroupId(groupId);
logger.debug("Update " + gav.getArtifactId() + "->" + groupId);
}
if (gav.getVersion() == null) {
gav.setVersion(version);
logger.debug("Update " + gav.getArtifactId() + "->" + version);
}
Enumeration> e = node.children();
while (e.hasMoreElements()) {
DefaultMutableTreeNode child = (DefaultMutableTreeNode) e.nextElement();
fillInGavs(child);
}
}
public void updateBuildInfo(DefaultMutableTreeNode node, BuildTag buildTag, TagStyle tagStyle, String buildText, int buildNumber) {
Project project = (Project) node.getUserObject();
project.setBuildTag(buildTag);
GAV oldGav = project.getGav();
String newVersion = null;
if (oldGav.getVersion() != null)
newVersion = getNewVersion(oldGav.getVersion(), buildText, buildNumber, tagStyle);
GAV newGav = new GAV();
newGav.setGroupId(oldGav.getGroupId());
newGav.setArtifactId(oldGav.getArtifactId());
newGav.setVersion(newVersion);
project.setNewGav(newGav);
logger.info("GAV Update - [" + toString(oldGav) + "->" + newVersion + "]");
}
public void updateBuildInfo(List nodes, List moduleTags, List mappings, TagStyle tagStyle, String buildText, int buildNumber) {
for (int i = 0; i < mappings.size(); i++) {
Mapping mapping = mappings.get(i);
BuildTag moduleTag = moduleTags.get(i);
DefaultMutableTreeNode node = findNode(nodes, mapping.getModule());
updateBuildInfo(node, moduleTag, tagStyle, buildText, buildNumber);
}
}
protected DefaultMutableTreeNode findNode(List nodes, String artifactId) {
for (DefaultMutableTreeNode node : nodes) {
Project project = (Project) node.getUserObject();
if (project.getGav().getArtifactId().equals(artifactId)) {
return node;
}
}
throw new IllegalStateException("Unable to locate " + artifactId);
}
public List getBuildTags(Properties properties, List mappings, TagStyle tagStyle, String buildText, int buildNumber) {
List buildTags = new ArrayList();
Collections.sort(mappings);
for (int i = 0; i < mappings.size(); i++) {
Mapping mapping = mappings.get(i);
BuildTag buildTag = getBuildTag(properties, mapping, tagStyle, buildText, buildNumber);
buildTags.add(buildTag);
}
return buildTags;
}
public BuildTag getBuildTag(File workingCopy, GAV gav, TagStyle tagStyle, String buildText, int buildNumber) {
String version = gav.getVersion();
//
String tag = getTag(version, gav.getArtifactId(), buildText, buildNumber, tagStyle);
//
BuildTag buildTag = new BuildTag(tag);
buildTag.setName(tag);
return buildTag;
}
public BuildTag getBuildTag(Properties properties, Mapping mapping, TagStyle tagStyle, String buildText, int buildNumber) {
String version = properties.getProperty(mapping.getVersionProperty());
String tag = getTag(version, mapping.getModule(), buildText, buildNumber, tagStyle);
BuildTag buildTag = new BuildTag(tag);
return buildTag;
}
/**
* Assuming version is in the form 1.0.0-beta-SNAPSHOT
, this method returns 1.0.0-beta-r3201
when
* TagStyle=REVISION
, 1.0.0-beta-build-187
when TagStyle=BUILDNUMBER
, and 1.0.0-beta
* when TagStyle=RELEASE
*/
public String getNewVersion(String version, String buildText, int buildNumber, TagStyle tagStyle) {
String trimmed = trimSnapshot(version);
switch (tagStyle) {
case BUILD_NUMBER:
return trimmed + "-"+buildText+"-" + buildNumber;
case RELEASE:
return trimmed;
default:
throw new IllegalArgumentException(tagStyle + " is unknown");
}
}
/**
* Assuming version is in the form 1.0.0-beta-SNAPSHOT
, this method will increment the 3rd digit by 1, and return
* 1.0.1-beta-SNAPSHOT
*/
public String getNextVersion(String version) {
if (!version.contains(MAVEN_SNAPSHOT_TOKEN)) {
throw new IllegalArgumentException(version + " is not a " + MAVEN_SNAPSHOT_TOKEN);
}
Version v = VersionUtils.getVersion(version);
String qualifier = v.getQualifier();
if (qualifier != null && !qualifier.isEmpty()) {
String qualifierParts[] = qualifier.split(QUALIFIER_DELIMETER);
if (qualifierParts.length > 0) {
StringBuilder nextQualifer = new StringBuilder();
if (qualifierContainsVersionedPrefix(
majorQualifierFoundersReleasePrefix, qualifierParts[0])) {
// founders release qualifier is present.
if (qualifierParts.length == 2) {
// founders release - milestone or release candidate
nextQualifer.append(qualifierParts[0]);
nextQualifer.append(QUALIFIER_DELIMETER);
if (qualifierContainsVersionedPrefix(
minorQualiferMilestonePrefix, qualifierParts[1])) {
// milestone
String nextMilestone = incrementQualifier(
minorQualiferMilestonePrefix,
qualifierParts[1]);
nextQualifer.append(nextMilestone);
} else if (qualifierContainsVersionedPrefix(
minorQualiferReleaseCandidatePrefix,
qualifierParts[1])) {
// release candidate
String nextReleaseCandidate = incrementQualifier(
minorQualiferReleaseCandidatePrefix,
qualifierParts[1]);
nextQualifer.append(nextReleaseCandidate);
} else {
// invalid minor qualifier
throw new IllegalArgumentException(
"invalid minor qualifier: "
+ qualifierParts[1]);
}
v.setQualifier(nextQualifer.toString());
} else {
// only contains the main qualifier
String nextMajorQualifer = incrementQualifier(
majorQualifierFoundersReleasePrefix,
qualifierParts[0]);
v.setQualifier(nextMajorQualifer);
}
} else {
// invalid major qualifier
throw new IllegalArgumentException(
"invalid major qualifier: " + qualifierParts[0]);
}
}
}
else {
Integer oldIncremental = new Integer(v.getIncremental());
Integer newIncremental = oldIncremental + 1;
v.setIncremental(newIncremental.toString());
}
StringBuilder sb = new StringBuilder();
sb.append(v.getMajor());
sb.append(".");
sb.append(v.getMinor());
sb.append(".");
sb.append(v.getIncremental());
sb.append(QUALIFIER_DELIMETER);
if (!StringUtils.isBlank(v.getQualifier())) {
sb.append(v.getQualifier());
sb.append(QUALIFIER_DELIMETER);
}
sb.append(MAVEN_SNAPSHOT_TOKEN);
return sb.toString();
}
private String incrementQualifier(String targetPrefix, String qualifier) {
// increment this part
if (qualifier.toLowerCase().startsWith(targetPrefix.toLowerCase())) {
String baseQualifier = qualifier.substring(0, targetPrefix.length());
String token = "";
try {
token = qualifier.substring(targetPrefix.length());
Integer oldVersion = new Integer(token);
Integer newVersion = oldVersion + 1;
return baseQualifier + newVersion;
} catch (NumberFormatException e) {
throw new RuntimeException("failed to convert " + token + " suffix of " + qualifier + "into an Integer", e);
}
} else {
throw new IllegalArgumentException("'" + qualifier
+ "' does not contain a part starting with '"
+ targetPrefix);
}
}
/**
* A main qualifier is a Founders Release FR[0-9]+
*/
protected boolean isKnownMainQualifier (String qualifier) {
return qualifierContainsVersionedPrefix(majorQualifierFoundersReleasePrefix, qualifier);
}
/**
* A sub qualifier is a milestone M[0-9]+ or release candidate RC[0-9]+
*/
protected boolean isKnownSubQualifier(String qualifier) {
if (qualifierContainsVersionedPrefix(minorQualiferMilestonePrefix, qualifier) ||
qualifierContainsVersionedPrefix(minorQualiferReleaseCandidatePrefix, qualifier))
return true;
else
return false;
}
private boolean qualifierContainsVersionedPrefix(String targetPrefix, String qualifier) {
if (StringUtils.isBlank(qualifier)) {
return false;
}
else if (qualifier.length() < targetPrefix.length()) {
return false;
}
else {
if (qualifier.toLowerCase().startsWith(targetPrefix.toLowerCase())) {
try {
String suffix = StringUtils.substring(qualifier,
targetPrefix.length());
Integer.parseInt(suffix);
} catch (NumberFormatException e) {
return false;
}
}
else {
return false;
}
}
return true;
}
protected boolean isDigit(char c) {
for (char digit : DIGITS) {
if (c == digit) {
return true;
}
}
return false;
}
public String getTag(String version, String artifactId, String buildText, int buildNumber, TagStyle tagStyle) {
switch (tagStyle) {
case BUILD_NUMBER:
return getBuildNumberTag(version, artifactId, buildText, buildNumber);
case RELEASE:
return getReleaseTag(version, artifactId);
default:
throw new IllegalArgumentException(tagStyle + " is unknown");
}
}
public int getBuildNumber(MavenProject project, String buildNumberProperty) {
if (buildNumberProperty == null)
return 0;
String buildNumber = System.getenv(buildNumberProperty);
if (StringUtils.isBlank(buildNumber)) {
logger.warn(buildNumberProperty + " is blank");
return 0;
} else {
return new Integer(buildNumber);
}
}
public String getReleaseTag(String version, String artifactId) {
String trimmed = trimSnapshot(version);
StringBuilder sb = new StringBuilder();
sb.append(artifactId);
sb.append(QUALIFIER_DELIMETER);
sb.append(trimmed);
return sb.toString();
}
public String getBuildNumberTag(String version, String artifactId, String buildText, int buildNumber) {
StringBuilder sb = new StringBuilder();
sb.append(getBaseTag(version, artifactId));
sb.append(TAG_NAME_DELIMETER);
sb.append(buildText + "-" + buildNumber);
return sb.toString();
}
public String getRevisionTag(String version, String artifactId, String revisionTagSuffix) {
StringBuilder sb = new StringBuilder();
sb.append(getBaseTag(version, artifactId));
sb.append(TAG_NAME_DELIMETER);
sb.append(revisionTagSuffix);
return sb.toString();
}
protected String getBaseTag(String version, String artifactId) {
Version v = parseVersion(version);
String trimmed = trimSnapshot(version);
StringBuilder sb = new StringBuilder();
sb.append(artifactId);
sb.append(QUALIFIER_DELIMETER);
sb.append(v.getMajor());
sb.append(".");
sb.append(v.getMinor());
sb.append(TAG_NAME_DELIMETER);
sb.append(trimmed);
return sb.toString();
}
public String getTagName(GAV gav) {
Version v = parseVersion(gav.getVersion());
StringBuilder sb = new StringBuilder();
sb.append(gav.getArtifactId());
sb.append(QUALIFIER_DELIMETER);
sb.append(v.getMajor());
sb.append(".");
sb.append(v.getMinor());
sb.append(TAG_NAME_DELIMETER);
sb.append(gav.getVersion());
return sb.toString();
}
public void validate(MavenProject project, List mappings, boolean ignoreMissingMappings) throws MojoFailureException {
validate(project.getProperties(), mappings);
if (mappings == null) {
String errorMessage = "No Module Mappings were found. Is there a configuration section for the fusion-maven-plugin in the project's pom.xml file?";
// indicates a missing configuration in the project pom file
if (ignoreMissingMappings) {
logger.warn(errorMessage);
}
else
throw new MojoFailureException(errorMessage);
}
else {
validateModules(project.getModules(), mappings);
}
}
public void validateModules(List modules, List mappings) {
Collections.sort(mappings);
Collections.sort(modules);
if (isEmpty(modules) && isEmpty(mappings)) {
return;
} else if (isEmpty(modules) && !isEmpty(mappings)) {
throw new IllegalArgumentException("No modules detected but " + mappings.size() + " mappings were supplied");
} else if (!isEmpty(modules) && isEmpty(mappings)) {
throw new IllegalArgumentException(modules.size() + " modules were detected but no mappings were supplied");
} else if (modules.size() != mappings.size()) {
throw new IllegalArgumentException("Mismatch. " + modules.size() + " modules were detected. " + mappings.size() + " mappings were supplied");
}
for (int i = 0; i < modules.size(); i++) {
String module1 = modules.get(i);
String module2 = mappings.get(i).getModule();
if (!module1.equals(module2)) {
throw new IllegalArgumentException("Mismatch. " + module1 + " <> " + module2);
}
}
}
public void validate(Properties properties, List mappings) {
if (isEmpty(mappings)) {
return;
}
StringBuilder sb = new StringBuilder();
int missingCount = 0;
for (Mapping mapping : mappings) {
String key = mapping.getVersionProperty();
String value = properties.getProperty(key);
if (StringUtils.isBlank(value)) {
if (missingCount++ != 0) {
sb.append(", ");
}
sb.append(key);
}
}
if (missingCount != 0) {
throw new IllegalArgumentException("Missing values for [" + sb.toString() + "]");
}
}
public String trimSnapshot(String version) {
if (version.toUpperCase().endsWith(QUALIFIER_DELIMETER + MAVEN_SNAPSHOT_TOKEN)) {
int length = MAVEN_SNAPSHOT_TOKEN.length() + 1;
return StringUtils.left(version, version.length() - length);
} else {
return version;
}
}
public boolean isEmpty(Collection> c) {
return c == null || c.isEmpty();
}
protected Version parseVersion(String s) {
boolean snapshot = s.toUpperCase().endsWith(QUALIFIER_DELIMETER + MAVEN_SNAPSHOT_TOKEN);
Version version = new Version();
version.setSnapshot(snapshot);
String[] tokens = StringUtils.split(s, ".-");
if (tokens.length > 0) {
version.setMajor(tokens[0]);
}
if (tokens.length > 1) {
version.setMinor(tokens[1]);
}
if (tokens.length > 2) {
version.setIncremental(tokens[2]);
}
String qualifier = getQualifier(tokens);
version.setQualifier(qualifier);
return version;
}
protected String getQualifier(String[] tokens) {
if (tokens.length <= 3) {
return null;
}
StringBuilder sb = new StringBuilder();
for (int i = 3; i < tokens.length; i++) {
if (tokens[i].toUpperCase().equals(MAVEN_SNAPSHOT_TOKEN)) {
break;
}
if (i != 3) {
sb.append(QUALIFIER_DELIMETER);
}
sb.append(tokens[i]);
}
return sb.toString();
}
public void write(File file, String data) {
try {
FileUtils.write(file, data);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
public void deleteDirectory(File dir) {
try {
FileUtils.deleteDirectory(dir);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
public String read(File file) {
try {
return FileUtils.readFileToString(file);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy