org.kie.integration.eap.maven.util.EAPArtifactUtils Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2014 Red Hat, Inc. and/or its affiliates.
*
* Licensed 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.kie.integration.eap.maven.util;
import org.apache.maven.artifact.versioning.ComparableVersion;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.kie.integration.eap.maven.exception.EAPModuleDefinitionException;
import org.kie.integration.eap.maven.model.dependency.EAPStaticModuleDependency;
import org.kie.integration.eap.maven.model.graph.EAPModuleGraphNode;
import org.kie.integration.eap.maven.model.graph.EAPModuleGraphNodeResource;
import org.kie.integration.eap.maven.model.graph.EAPModulesGraph;
import org.kie.integration.eap.maven.model.module.EAPModule;
import org.kie.integration.eap.maven.model.resource.EAPModuleResource;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.collection.CollectRequest;
import org.eclipse.aether.collection.CollectResult;
import org.eclipse.aether.collection.DependencyCollectionException;
import org.eclipse.aether.collection.DependencySelector;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.graph.DependencyFilter;
import org.eclipse.aether.graph.DependencyNode;
import org.eclipse.aether.graph.Exclusion;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.DependencyResolutionException;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.util.graph.selector.AndDependencySelector;
import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector;
import org.eclipse.aether.util.graph.selector.OptionalDependencySelector;
import org.eclipse.aether.util.graph.selector.ScopeDependencySelector;
import org.eclipse.aether.util.graph.transformer.NoopDependencyGraphTransformer;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* This class contains some artifact utils.
*/
public class EAPArtifactUtils {
/** The pattern for maven propoerties. **/
protected static final Pattern PROPERTY_PATTERN = Pattern.compile("\\$\\{([^}]*)\\}");
protected static final Pattern JAR_NAME_PARSER_PATTERN = Pattern.compile("(.*)-(\\d+[\\.-].*).jar");
/**
* Creates an artifact instance.
*
* @param groupId The artifact's groupId.
* @param artifactId The artifact's artifactId.
* @param version The artifact's version.
* @param packaging The artifact's packaging.
* @return The artifact instance.
*/
public static Artifact createArtifact(String groupId, String artifactId, String version, String packaging) {
return new DefaultArtifact(groupId, artifactId, packaging, version);
}
/**
* Creates an artifact instance.
*
* @param artifactCoordinates The artifact's coordinates..
* @return The artifact instance.
*/
public static Artifact createArtifact(String artifactCoordinates) {
String[] coords = extractArtifactCorrdinates(artifactCoordinates);
String groupId = coords[0];
String artifactId = coords[1];
String type = coords.length > 2 ? coords[2] : "";
String version = coords.length > 3 ? coords[3] : "";
return new DefaultArtifact(groupId, artifactId, type, version);
}
/**
* Creates an artifact instance.
*
* @param groupId The artifact's groupId.
* @param artifactId The artifact's artifactId.
* @param version The artifact's version.
* @param packaging The artifact's packaging.
* @param classifier The artifact's classifier.
* @return The artifact instance.
*/
public static Artifact createArtifact(String groupId, String artifactId, String version, String packaging, String classifier) {
return new DefaultArtifact(groupId, artifactId, classifier, packaging, version);
}
/**
* Resolves an artifact in remote repositories.
*
* @param groupId The artifact's groupId.
* @param artifactId The artifact's artifactId.
* @param version The artifact's version.
* @param packaging The artifact's packaging.
* @param classifier The artifact's classifier..
* @return The artifact resolved.
*
* @throws org.eclipse.aether.resolution.ArtifactResolutionException
*/
public static Artifact resolveArtifact(String groupId, String artifactId, String version, String packaging, String classifier, RepositorySystem repoSystem, RepositorySystemSession repoSession, List remoteRepos) throws ArtifactResolutionException {
Artifact art = createArtifact(groupId, artifactId, version, packaging, classifier);
return resolveArtifact(art, repoSystem, repoSession, remoteRepos);
}
/**
* Resolves an artifact in remote repositories.
*
* @param groupId The artifact's groupId.
* @param artifactId The artifact's artifactId.
* @param version The artifact's version.
* @param packaging The artifact's packaging..
* @return The artifact resolved.
*
* @throws org.eclipse.aether.resolution.ArtifactResolutionException
*/
public static Artifact resolveArtifact(String groupId, String artifactId, String version, String packaging, RepositorySystem repoSystem, RepositorySystemSession repoSession, List remoteRepos) throws ArtifactResolutionException {
Artifact art = createArtifact(groupId, artifactId, version, packaging);
return resolveArtifact(art, repoSystem, repoSession, remoteRepos);
}
/**
* Resolves an artifact in remote repositories.
*
* @param art The artifact to resolve.
* @return The artifact resolved.
*
* @throws ArtifactResolutionException
*/
public static Artifact resolveArtifact(Artifact art, RepositorySystem repoSystem, RepositorySystemSession repoSession, List remoteRepos) throws ArtifactResolutionException {
ArtifactRequest request = new ArtifactRequest(art, remoteRepos, "");
return repoSystem.resolveArtifact(repoSession, request).getArtifact();
}
/**
* Check if two artifacts are equals.
* The equality is done by comparing artifact coordinates.
*
* @param a1 The artifact.
* @param a2 The other artifact.
* @return Are artifact coordinates equals.
*/
public static boolean equals(Artifact a1, Artifact a2) {
String a1Coords = getArtifactCoordinates(a1);
String a2Coords = getArtifactCoordinates(a2);
return a1Coords.equalsIgnoreCase(a2Coords);
}
/**
* Check if two artifacts are equals except for the version coordinate.
* The equality is done by comparing artifact coordinates.
*
* @param a1 The artifact.
* @param a2 The other artifact.
* @return Are artifact coordinates equals (except for version coordinate).
*/
public static boolean equalsNoVersion(Artifact a1, Artifact a2) {
Artifact a1Copy = new DefaultArtifact(a1.getGroupId(), a1.getArtifactId(), a1.getExtension(), null);
Artifact a2Copy = new DefaultArtifact(a2.getGroupId(), a2.getArtifactId(), a2.getExtension(), null);
String a1Coords = getArtifactCoordinates(a1Copy);
String a2Coords = getArtifactCoordinates(a2Copy);
return a1Coords.equalsIgnoreCase(a2Coords);
}
/**
* Clones an artifact instance.
* Only clones the coordinates:
* - groupId
* - artifactId
* - version
* - type
* @param a The artifact to clone.
* @return The cloned artifact.
*/
public static Artifact cloneArtifact(Artifact a) {
String groupId = a.getGroupId();
String artifactId = a.getArtifactId();
String type = a.getExtension();
String version = a.getVersion();
return new DefaultArtifact(groupId, artifactId, type, version);
}
/**
* Extract the artifact properties for a given artifact string.
* TODO: Use maven API?
*
* @param artifactCoordinates The artifact string.
* @return The artifact properties.
*/
public static String[] extractArtifactCorrdinates(String artifactCoordinates) {
if (artifactCoordinates == null || artifactCoordinates.trim().length() == 0) throw new IllegalArgumentException("Artifact string cannot be null or empty.");
return artifactCoordinates.split(EAPConstants.ARTIFACT_SEPARATOR);
}
/**
* Returns the artifact with all coordinates - groupId:artifactId:type[:classifier]:version
* TODO: Use maven API?
*
* @param artifact The artifact.
* @return The artifact coordinates.
*/
public static String getArtifactCoordinates(org.apache.maven.artifact.Artifact artifact) {
if (artifact == null) return null;
StringBuilder result = new StringBuilder();
if (artifact.getGroupId() != null && artifact.getGroupId().trim().length() > 0) {
result.append(artifact.getGroupId());
}
if (artifact.getArtifactId() != null && artifact.getArtifactId().trim().length() > 0) {
if (result.length() > 0) result.append(EAPConstants.ARTIFACT_SEPARATOR);
result.append(artifact.getArtifactId());
}
if (artifact.getType() != null && artifact.getType().trim().length() > 0) {
if (result.length() > 0) result.append(EAPConstants.ARTIFACT_SEPARATOR);
result.append(artifact.getType());
}
if (artifact.getClassifier() != null && artifact.getClassifier().trim().length() > 0) {
if (result.length() > 0) result.append(EAPConstants.ARTIFACT_SEPARATOR);
result.append(artifact.getClassifier());
}
String version = toSnaphostVersion(artifact);
if (version != null) {
if (result.length() > 0) result.append(EAPConstants.ARTIFACT_SEPARATOR);
result.append(version);
}
return result.toString();
}
/**
* Returns the artifact with all coordinates - groupId:artifactId:type[:classifier]:version
* TODO: Use maven API?
*
* @param artifact The artifact.
* @return The artifact coordinates.
*/
public static String getArtifactCoordinates(Artifact artifact) {
if (artifact == null) return null;
StringBuilder result = new StringBuilder();
if (artifact.getGroupId() != null && artifact.getGroupId().trim().length() > 0) {
result.append(artifact.getGroupId());
}
if (artifact.getArtifactId() != null && artifact.getArtifactId().trim().length() > 0) {
if (result.length() > 0) result.append(EAPConstants.ARTIFACT_SEPARATOR);
result.append(artifact.getArtifactId());
}
if (artifact.getExtension() != null && artifact.getExtension().trim().length() > 0) {
if (result.length() > 0) result.append(EAPConstants.ARTIFACT_SEPARATOR);
result.append(artifact.getExtension());
}
if (artifact.getClassifier() != null && artifact.getClassifier().trim().length() > 0) {
if (result.length() > 0) result.append(EAPConstants.ARTIFACT_SEPARATOR);
result.append(artifact.getClassifier());
}
String version = toSnaphostVersion(artifact);
if (version != null) {
if (result.length() > 0) result.append(EAPConstants.ARTIFACT_SEPARATOR);
result.append(version);
}
return result.toString();
}
/**
* Returns the artifact with all coordinates exception the version one - groupId:artifactId:type[:classifier]
*
* @param artifact The artifact.
* @return The artifact coordinates without the version one.
*/
public static String getArtifactCoordinatesWithoutVersion(Artifact artifact) {
if (artifact == null) return null;
StringBuilder result = new StringBuilder();
if (artifact.getGroupId() != null && artifact.getGroupId().trim().length() > 0) {
result.append(artifact.getGroupId());
}
if (artifact.getArtifactId() != null && artifact.getArtifactId().trim().length() > 0) {
if (result.length() > 0) result.append(EAPConstants.ARTIFACT_SEPARATOR);
result.append(artifact.getArtifactId());
}
if (artifact.getExtension() != null && artifact.getExtension().trim().length() > 0) {
if (result.length() > 0) result.append(EAPConstants.ARTIFACT_SEPARATOR);
result.append(artifact.getExtension());
}
if (artifact.getClassifier() != null && artifact.getClassifier().trim().length() > 0) {
if (result.length() > 0) result.append(EAPConstants.ARTIFACT_SEPARATOR);
result.append(artifact.getClassifier());
}
return result.toString();
}
public static String toSnaphostVersion(Artifact artifact) {
if (artifact == null) return null;
if (artifact.getBaseVersion() != null && artifact.getBaseVersion().trim().length() > 0) {
// Avoid snapshot timestamped versions.
return artifact.getBaseVersion();
} else if (artifact.getVersion() != null && artifact.getVersion().trim().length() > 0) {
return artifact.getVersion();
}
return null;
}
public static String toSnaphostVersion(org.apache.maven.artifact.Artifact artifact) {
if (artifact == null) return null;
// TODO: Use ArtifactUtils.toSnapshotVersion()?
if (artifact.getBaseVersion() != null && artifact.getBaseVersion().trim().length() > 0) {
// Avoid snapshot timestamped versions.
return artifact.getBaseVersion();
} else if (artifact.getVersion() != null && artifact.getVersion().trim().length() > 0) {
return artifact.getVersion();
}
return null;
}
/**
* Returns the artifact with gropupId and artifactId coordinates - groupId:artifactId
* TODO: Use maven API?
*
* @param artifactCoords The artifact coordinates..
* @return The artifact short coordinates.
*/
public static String getArtifactShortCoordinates(String artifactCoords) {
if (artifactCoords == null) return null;
String[] coords = extractArtifactCorrdinates(artifactCoords);
return new StringBuilder().append(coords[0]).append(EAPConstants.ARTIFACT_SEPARATOR).append(coords[1]).toString();
}
/**
* Generates a model for a given artifact.
* @param artifact The artifact.
* @return The model for this artifact's pom file.
*
* @throws java.io.IOException Pom file cannot be readed.
* @throws org.codehaus.plexus.util.xml.pull.XmlPullParserException Pom file cannot be parsed.
*/
public static Model generateModel(Artifact artifact) throws IOException, XmlPullParserException {
File pomFile = artifact.getFile();
Reader reader = new FileReader(pomFile);
try {
MavenXpp3Reader xpp3Reader = new MavenXpp3Reader();
Model model = xpp3Reader.read(reader);
return model;
} finally {
reader.close();
}
}
/**
* Obtain the property value when using a property as a value.
* TODO: Use Maven API?
*
* @param model
* @param propertyValue
* @return
*/
public static String getPropertyValue(Model model, String propertyValue) {
if (model == null && propertyValue != null) return propertyValue;
if (model == null || propertyValue == null) return null;
StringBuffer sb = new StringBuffer(propertyValue.length());
// Check if the property value is a variable.
Matcher m = PROPERTY_PATTERN.matcher(propertyValue);
while (m.find()) {
String pName = m.group(1);
String pValue = null;
if (EAPConstants.PROPERTY_PROJECT_VERSION.equalsIgnoreCase(pName)) pValue = model.getParent().getVersion();
else pValue = (String) model.getProperties().get(pName);
if (pValue == null) throw new IllegalArgumentException("Cannot resolve the property " + pName + " in project properties.");
// Custom pom properties.
if (PROPERTY_PATTERN.matcher(pValue).matches()) pValue = getPropertyValue(model, pValue);
m.appendReplacement(sb, Matcher.quoteReplacement(pValue));
}
m.appendTail(sb);
return sb.toString();
}
public static void toArtifacts( EAPArtifactsHolder holder,
Collection extends DependencyNode> nodes,
DependencyFilter filter )
{
// Setting depth as 0 means that it will scan the whole tree.
toArtifacts(holder, nodes, filter, 0);
}
public static void toArtifacts( EAPArtifactsHolder holder,
Collection extends DependencyNode> nodes,
DependencyFilter filter, int depth )
{
if (nodes == null || nodes.isEmpty()) return;
int currentDepth = 0;
toArtifacts(holder, nodes, filter, depth, currentDepth);
}
public static void toArtifacts( EAPArtifactsHolder holder,
Collection extends DependencyNode> nodes,
DependencyFilter filter, int depth, int currentDepth )
{
if (depth > 0 && depth >= currentDepth) return;
if (nodes == null || nodes.isEmpty()) return;
for ( DependencyNode node : nodes )
{
// Artifact artifact = toArtifact( node.getDependency() );
Artifact artifact = node.getDependency().getArtifact();
if (holder.contains(artifact)) continue;
if ( filter == null || filter.accept( node, Collections. emptyList() ) )
{
// System.out.println("Adding artifact " + artifact.getGroupId() + ":" + artifact.getArtifactId());
holder.add( artifact );
}
currentDepth++;
toArtifacts( holder, node.getChildren(), filter, depth, currentDepth );
}
}
public static Artifact toArtifact( org.eclipse.aether.graph.Dependency dependency )
{
if ( dependency == null )
{
return null;
}
String artifactId = dependency.getArtifact().getArtifactId();
String groupId = dependency.getArtifact().getGroupId();
String version = dependency.getArtifact().getVersion();
String classifier = dependency.getArtifact().getClassifier();
String packaging = dependency.getArtifact().getExtension();
if (classifier != null && classifier.trim().length() > 0) return createArtifact(groupId, artifactId, version, packaging, classifier);
else return createArtifact(groupId, artifactId, version, packaging);
}
/**
* Generates the dependency graph for an artifact.
*
* @param rootArtifact The artifact to generate the dependency graph.
* @return The artifact dependency graph.
*
* @throws org.eclipse.aether.collection.DependencyCollectionException
*/
public static DependencyNode getDependencyGraph(Artifact rootArtifact, RepositorySystem repoSystem, RepositorySystemSession repoSession, List remoteRepos, boolean includeOptionalDependencies)
throws DependencyCollectionException, DependencyResolutionException {
Dependency rootDependency = new Dependency(rootArtifact, EAPConstants.SCOPE_COMPILE);
CollectRequest collectRequest = new CollectRequest(rootDependency, remoteRepos);
// Collect all the nodes using a NoopDependencyGraphTransformer transformer to have the whole unmanaged tree.
DefaultRepositorySystemSession newSession = new DefaultRepositorySystemSession(repoSession);
// Do not transform the tree. We don't any any dependency resolution applied.
newSession.setDependencyGraphTransformer(NoopDependencyGraphTransformer.INSTANCE);
// Exclude only test scope dependencies, include other ones (provided).
ScopeDependencySelector scopeDependencySelector = new ScopeDependencySelector(EAPConstants.SCOPE_TEST);
// Create the dependency selector.
DependencySelector selector = null;
if (includeOptionalDependencies) selector = new AndDependencySelector(scopeDependencySelector, new ExclusionDependencySelector());
else selector = new AndDependencySelector(scopeDependencySelector, new ExclusionDependencySelector(), new OptionalDependencySelector());
newSession.setDependencySelector(selector);
// DependencyRequest depRequest = new DependencyRequest(collectRequest, null);
CollectResult result = repoSystem.collectDependencies(newSession, collectRequest);
return result.getRoot();
}
public static Artifact createProjectArtifact(MavenProject project) {
return EAPArtifactUtils.createArtifact(project.getGroupId(),
project.getArtifactId(), project.getVersion(),
project.getPackaging());
}
public static String getUID(String name, String slot) {
if (name == null) return null;
StringBuilder result = new StringBuilder(name);
if (slot != null && slot.trim().length() > 0) {
result.append(EAPConstants.ARTIFACT_SEPARATOR).append(slot);
}
return result.toString();
}
public static EAPModuleGraphNode getNodeWithResource(Artifact artifact, EAPModulesGraph graph) {
if (artifact != null && graph != null) {
String artifactCoordinates = EAPArtifactUtils.getArtifactCoordinates(artifact);
Collection nodes = graph.getNodes();
if (nodes != null && !nodes.isEmpty()) {
for (EAPModuleGraphNode node : nodes) {
Collection resources = node.getResources();
if (resources != null && !resources.isEmpty()) {
for (EAPModuleGraphNodeResource resource : resources) {
String resourceCoordinates = EAPArtifactUtils.getArtifactCoordinates((Artifact) resource.getResource());
if (artifactCoordinates.equalsIgnoreCase(resourceCoordinates)) return node;
}
}
}
}
}
return null;
}
/**
* Parses a jar resource name.
* Extract artifactId and version coordinates.
*
* @param fileName the jar file name.
* @return
*/
public static String[] parseFileName(String fileName) {
String[] result = new String[2];
Matcher m1 = JAR_NAME_PARSER_PATTERN.matcher(fileName);
boolean matches = m1.matches();
if (!matches) {
result[0] = fileName.substring(0,fileName.length() - 4);
result[1] = "";
} else {
result[0] = m1.group(1);
result[1] = m1.group(2);
}
return result;
}
public static boolean isArtifactExcludedInModule(EAPModule module, Artifact artifact) {
if (module == null || artifact == null) return false;
Collection resources = module.getResources();
if (resources != null && !resources.isEmpty()) {
for (EAPModuleResource resource : resources) {
Collection exclusions = resource.getExclusions();
if (exclusions != null && !exclusions.isEmpty()) {
for (Exclusion exclusion : exclusions) {
// TODO: Check classfifer and type too for exclusion artifacts?.
if (exclusion.getGroupId().equalsIgnoreCase(artifact.getGroupId()) && exclusion.getArtifactId().equalsIgnoreCase(artifact.getArtifactId())) return true;
}
}
}
}
return false;
}
public static Collection getStaticDependencies(Artifact moduleArtifact, Model moduleModel ,String moduleDependenciesRaw) throws EAPModuleDefinitionException {
Collection result = null;
if (moduleDependenciesRaw != null && moduleDependenciesRaw.trim().length() > 0) {
String moduleArtifactCoordinates = getArtifactCoordinates(moduleArtifact);
result = new LinkedList();
// If module pom descriptor file contains dependencies, add these ones.
String[] _moduleDependenciesRaw = moduleDependenciesRaw.split(",");
for (String moduleDep : _moduleDependenciesRaw) {
String[] _moduleDep = moduleDep.split(":");
if (_moduleDep == null || _moduleDep.length < 2)
throw new EAPModuleDefinitionException(moduleArtifactCoordinates, "The static dependency '" + _moduleDep + "' syntax is not correct.");
String moduleName = EAPArtifactUtils.getPropertyValue(moduleModel, _moduleDep[0]);
String moduleSlot = EAPArtifactUtils.getPropertyValue(moduleModel, _moduleDep[1]);
boolean export = false;
if (_moduleDep.length == 3) export = Boolean.valueOf(_moduleDep[2]);
EAPStaticModuleDependency dep = new EAPStaticModuleDependency(moduleName);
dep.setSlot(moduleSlot);
dep.setOptional(false);
dep.setExport(export);
result.add(dep);
}
}
return result;
}
public static boolean isVersionEqualsThan(ComparableVersion version1, ComparableVersion version2) {
return version1.compareTo(version2) == 0;
}
public static boolean isVersionGreaterThan(ComparableVersion version1, ComparableVersion version2) {
return version1.compareTo(version2) == 1;
}
public static boolean isVersionLowerThan(ComparableVersion version1, ComparableVersion version2) {
return version1.compareTo(version2) == -1;
}
}