Java tutorial
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.commons.lang.StringUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; import org.apache.maven.shared.artifact.filter.PatternExcludesArtifactFilter; import org.apache.maven.shared.artifact.filter.PatternIncludesArtifactFilter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; /** * Base class for a mojo that updates dependency versions. * * @author Paul Gier * @author Stephen Connolly * @since 1.0-alpha-3 */ public abstract class AbstractVersionsDependencyUpdaterMojo extends AbstractVersionsUpdaterMojo { private static final String END_RANGE_CHARS = "])"; private static final String START_RANGE_CHARS = "[("; /** * A comma separated list of artifact patterns to include. Follows the pattern * "groupId:artifactId:type:classifier:version". Designed to allow specifing the set of includes from the command * line. When specifying includes from the pom, use the {@link #includes} configuration instead. If this property is * specified then the {@link # include} configuration is ignored. * * @parameter property="includes" * @since 1.0-beta-1 */ private String includesList = null; /** * A comma separated list of artifact patterns to exclude. Follows the pattern * "groupId:artifactId:type:classifier:version". Designed to allow specifing the set of excludes from the command * line. When specifying excludes from the pom, use the {@link #excludes} configuration instead. If this property is * specified then the {@link # exclude} configuration is ignored. * * @parameter property="excludes" * @since 1.0-beta-1 */ private String excludesList = null; /** * A list of artifact patterns to include. Follows the pattern * "groupId:artifactId:type:classifier:version". This configuration setting is ignored if {@link #includesList} is * defined. * * @parameter * @since 1.0-beta-1 */ private String[] includes = null; /** * A list of artifact patterns to exclude. Follows the pattern * "groupId:artifactId:type:classifier:version". This configuration setting is ignored if {@link #excludesList} is * defined. * * @parameter * @since 1.0-beta-1 */ private String[] excludes = null; /** * Whether to process the dependencies section of the project. If not * set will default to true. * * @parameter property="processDependencies" defaultValue="true" * @since 1.0-alpha-3 */ private Boolean processDependencies; /** * Whether to process the dependencyManagement section of the project. If not * set will default to true. * * @parameter property="processDependencyManagement" defaultValue="true" * @since 1.0-alpha-3 */ private Boolean processDependencyManagement; /** * Artifact filter to determine if artifact should be included * * @since 1.0-alpha-3 */ private PatternIncludesArtifactFilter includesFilter; /** * Artifact filter to determine if artifact should be excluded * * @since 1.0-alpha-3 */ private PatternExcludesArtifactFilter excludesFilter; /** * Whether to skip processing dependencies that are produced as part of the current reactor. * * @parameter property="excludeReactor" defaultValue="true" * @since 1.0-alpha-3 */ private Boolean excludeReactor; /** * Should the project/dependencies section of the pom be processed. * * @return returns <code>true if the project/dependencies section of the pom should be processed. * @since 1.0-alpha-3 */ public boolean isProcessingDependencies() { // true if true or null return !Boolean.FALSE.equals(processDependencies); } /** * Should the project/dependencyManagement section of the pom be processed. * * @return returns <code>true if the project/dependencyManagement section of the pom should be processed. * @since 1.0-alpha-3 */ public boolean isProcessingDependencyManagement() { // true if true or null return !Boolean.FALSE.equals(processDependencyManagement); } /** * Should the artifacts produced in the current reactor be excluded from processing. * * @return returns <code>true if the artifacts produced in the current reactor should be excluded from processing. * @since 1.0-alpha-3 */ public boolean isExcludeReactor() { // true if true or null return !Boolean.FALSE.equals(excludeReactor); } /** * Try to find the dependency artifact that matches the given dependency. * * @param dependency * @return * @since 1.0-alpha-3 */ protected Artifact findArtifact(Dependency dependency) { if (getProject().getDependencyArtifacts() == null) { return null; } Iterator iter = getProject().getDependencyArtifacts().iterator(); while (iter.hasNext()) { Artifact artifact = (Artifact) iter.next(); if (compare(artifact, dependency)) { return artifact; } } return null; } /** * Try to find the dependency artifact that matches the given dependency. * * @param dependency * @return * @since 1.0-alpha-3 */ protected Artifact toArtifact(Dependency dependency) throws MojoExecutionException { Artifact artifact = findArtifact(dependency); if (artifact == null) { try { return getHelper().createDependencyArtifact(dependency); } catch (InvalidVersionSpecificationException e) { throw new MojoExecutionException(e.getMessage(), e); } } return artifact; } protected String toString(Dependency d) { StringBuilder buf = new StringBuilder(); buf.append(d.getGroupId()); buf.append(':'); buf.append(d.getArtifactId()); if (d.getType() != null && d.getType().length() > 0) { buf.append(':'); buf.append(d.getType()); } else { buf.append(":jar"); } if (d.getClassifier() != null && d.getClassifier().length() > 0) { buf.append(':'); buf.append(d.getClassifier()); } if (d.getVersion() != null && d.getVersion().length() > 0) { buf.append(":"); buf.append(d.getVersion()); } return buf.toString(); } /** * Returns <code>true</code> if the dependency is produced by the current reactor. * * @param dependency the dependency to heck. * @return <code>true</code> if the dependency is produced by the current reactor. * @since 1.0-alpha-3 */ protected boolean isProducedByReactor(Dependency dependency) { Iterator iter = reactorProjects.iterator(); while (iter.hasNext()) { MavenProject project = (MavenProject) iter.next(); if (compare(project, dependency)) { return true; } } return false; } /** * Compare a project to a dependency. Returns true only if the groupId and artifactId are all * equal. * * @param project the project * @param dep the dependency * @return true if project and dep refer to the same artifact */ private boolean compare(MavenProject project, Dependency dep) { if (!StringUtils.equals(project.getGroupId(), dep.getGroupId())) { return false; } if (!StringUtils.equals(project.getArtifactId(), dep.getArtifactId())) { return false; } return true; } /** * Compare and artifact to a dependency. Returns true only if the groupId, artifactId, type, and classifier are all * equal. * * @param artifact * @param dep * @return true if artifact and dep refer to the same artifact */ private boolean compare(Artifact artifact, Dependency dep) { if (!StringUtils.equals(artifact.getGroupId(), dep.getGroupId())) { return false; } if (!StringUtils.equals(artifact.getArtifactId(), dep.getArtifactId())) { return false; } if (!StringUtils.equals(artifact.getType(), dep.getType())) { return false; } if (!StringUtils.equals(artifact.getClassifier(), dep.getClassifier())) { return false; } return true; } /** * Determine if the artifact is included in the list of artifacts to be processed. * * @param artifact The artifact we want to check. * @return true if the artifact should be processed, false otherwise. */ protected boolean isIncluded(Artifact artifact) { boolean result = true; ArtifactFilter includesFilter = this.getIncludesArtifactFilter(); if (includesFilter != null) { result = includesFilter.include(artifact); } ArtifactFilter excludesFilter = this.getExcludesArtifactFilter(); if (excludesFilter != null) { result = result && excludesFilter.include(artifact); } return result; } private ArtifactFilter getIncludesArtifactFilter() { if (includesFilter == null && (includes != null || includesList != null)) { List patterns = new ArrayList(); if (this.includesList != null) { patterns.addAll(separatePatterns(includesList)); } else if (includes != null) { patterns.addAll(Arrays.asList(includes)); } includesFilter = new PatternIncludesArtifactFilter(patterns); } return includesFilter; } private ArtifactFilter getExcludesArtifactFilter() { if (excludesFilter == null && (excludes != null || excludesList != null)) { List patterns = new ArrayList(); if (excludesList != null) { patterns.addAll(separatePatterns(excludesList)); } else if (excludes != null) { patterns.addAll(Arrays.asList(excludes)); } excludesFilter = new PatternExcludesArtifactFilter(patterns); } return excludesFilter; } /** * To handle multiple includes with version range like "group:artifact:jar:[1.0.0,2.2)", * we have to use a parsing a little bit more complex than split(). * * @param includeString the string to parse * @return list of patterns */ protected List separatePatterns(String includeString) { if (includeString == null) { return Collections.EMPTY_LIST; } List patterns = new ArrayList(); int indexOf = nextCommaIndex(includeString); while (indexOf >= 0) { patterns.add(includeString.substring(0, indexOf)); includeString = includeString.substring(indexOf + 1); indexOf = nextCommaIndex(includeString); } patterns.add(includeString); return patterns; } private int nextCommaIndex(final String includeString) { int indexOfComma = includeString.indexOf(','); int nextRangeStartDelimiterIndex = findFirstChar(includeString, START_RANGE_CHARS); if (nextRangeStartDelimiterIndex >= 0) { if (!(indexOfComma >= 0 && indexOfComma < nextRangeStartDelimiterIndex)) { int nextStopDelimiterIndex = findFirstChar(includeString, END_RANGE_CHARS); // recursive call int tmp = nextCommaIndex(includeString.substring(nextStopDelimiterIndex + 1)); indexOfComma = (tmp >= 0) ? nextStopDelimiterIndex + 1 + tmp : -1; } } return indexOfComma; } private int findFirstChar(final String includeString, final String chars) { int nextRangeStartDelimiterIndex = -1; char[] delimiters = chars.toCharArray(); for (int i = 0; i < delimiters.length; i++) { int index = includeString.indexOf(delimiters[i]); if (index >= 0 && nextRangeStartDelimiterIndex >= 0) { nextRangeStartDelimiterIndex = Math.min(index, nextRangeStartDelimiterIndex); } else { if (index >= 0) { nextRangeStartDelimiterIndex = index; } } } return nextRangeStartDelimiterIndex; } }