com.cisco.device.packages.internal.sdu.SduCreator Maven / Gradle / Ivy
/******************************************************************************
* Copyright (c) 2011-2018 by Cisco Systems, Inc. and/or its affiliates.
* All rights reserved.
*
* This software is made available under the CISCO SAMPLE CODE LICENSE
* Version 1.1. See LICENSE.TXT at the root of this project for more information.
*
********************************************************************************/
package com.cisco.device.packages.internal.sdu;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.execution.BuildFailure;
import org.apache.maven.execution.BuildSuccess;
import org.apache.maven.execution.BuildSummary;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Exclusion;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
import org.apache.maven.model.io.DefaultModelReader;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.resolution.VersionRangeRequest;
import org.eclipse.aether.resolution.VersionRangeResolutionException;
import org.eclipse.aether.resolution.VersionRangeResult;
import org.eclipse.aether.version.Version;
import com.cisco.common.constructs.Node;
import com.cisco.device.packages.constants.PackagingConstants;
import com.cisco.device.packages.internal.plugin.DependencyTree;
/**
* Can be used to create an SDU from a collection of Maven projects during a
* Maven build. Expects at least the packaging phase to have been run prior to
* invocation.
*
* @author danijoh2
*/
public class SduCreator {
public static final String SDU_MANIFEST_ATTR_GROUP_ID = "xmp_groupId"; // $NON-NLS-1$
public static final String SDU_MANIFEST_ATTR_ARTIFACT_ID = "xmp_artifactId"; // $NON-NLS-1$
public static final String SDU_MANIFEST_ATTR_VERSION = "xmp_version"; // $NON-NLS-1$
public static final String SDU_MANIFEST_ATTR_TYPE = "xmp_type"; // $NON-NLS-1$
public static final String SDU_MANIFEST_ATTR_LOAD_ORDER = "devicePackage"; // $NON-NLS-1$
private MavenProject project;
private MavenSession mavenSession;
private List reactorProjects;
List extraExclusions;
private RepositorySystem repoSystem;
private RepositorySystemSession repoSession;
private List remoteRepos;
/**
* Can be used to specify a different name for the resulting SDU file.
*/
private String sduName;
private boolean includeAllReactorProjects = true;
private Log log;
private Map dependencyVersionMap = new HashMap();
public SduCreator(MavenProject project, MavenSession mavenSession, RepositorySystem repoSystem,
RepositorySystemSession repoSession, List remoteRepos) {
this.project = project;
this.mavenSession = mavenSession;
this.repoSystem = repoSystem;
this.repoSession = repoSession;
this.remoteRepos = remoteRepos;
}
public void setSduName(String name) {
this.sduName = name;
}
public void setLog(Log log) {
this.log = log;
}
public void setExtraExclusions(List exclusions) {
this.extraExclusions = exclusions;
}
public void setReactorProjects(List reactorProjects) {
this.reactorProjects = reactorProjects;
}
public void setIncludeAllReactorProjects(boolean includeAll) {
this.includeAllReactorProjects = includeAll;
}
public File create() throws MojoExecutionException, MojoFailureException {
Set projects = new HashSet();
projects.add(project);
if (PackagingConstants.POM_EXT.equals(project.getPackaging())) {
projects.addAll(getSubProjects(project, reactorProjects));
} else if (PackagingConstants.ALL_DP_PACKAGING.contains(project.getPackaging())) {
if (project.getArtifact() == null || project.getArtifact().getFile() == null
|| !project.getArtifact().getFile().exists()) {
throw new MojoExecutionException(
"SDU Creation requires at least goal 'package' of the current project to be executed.");
}
}
if (projects.isEmpty()) {
log.warn("No projects found to create SDU from, skipping SDU creation.");
return null;
}
Set artifacts = getArtifacts(projects);
if (artifacts.isEmpty()) {
if (extraExclusions != null) {
StringBuffer excludesBuffer = new StringBuffer();
Iterator iter = extraExclusions.iterator();
while (iter.hasNext()) {
Exclusion ex = iter.next();
excludesBuffer.append(ex.getGroupId()).append(":").append(ex.getArtifactId());
if (iter.hasNext()) {
excludesBuffer.append(", ");
}
}
throw new MojoFailureException(
"No artifacts found to include in the SDU. Check your project dependencies and use of exclusions. Received the following excludes: ["
+ excludesBuffer.toString() + "]");
} else {
throw new MojoFailureException(
"No artifacts found to include in the SDU. Check your project dependencies and use of dependency exclusions.");
}
}
Map files = createSDUFileMap(artifacts);
File baseDir = new File(project.getBuild().getDirectory());
if (!baseDir.exists()) {
// Create the "target" directory to place the .sdu into
baseDir.mkdir();
}
// Check if user supplied name for .sdu file
if (sduName == null) {
// They did not, default to -.sdu
sduName = project.getArtifactId() + PackagingConstants.DASH + project.getVersion();
if (!sduName.endsWith(PackagingConstants.DOT)) {
sduName += PackagingConstants.DOT;
}
sduName += PackagingConstants.SDU_EXT;
}
File sdu = null;
try {
sdu = createSDU(files, createManifest(artifacts), baseDir, sduName);
} catch (IOException e) {
throw new MojoFailureException(e.getMessage(), e);
}
return sdu;
}
protected Set getProjectRoots(Set projects) {
Set projectRoots = new HashSet();
for (MavenProject project : projects) {
boolean isDependOn = false;
for (MavenProject otherProject : projects) {
if (project == otherProject) {
continue;
}
isDependOn = hasDependency(otherProject, project);
if (isDependOn) {
break;
}
}
if (!isDependOn) {
projectRoots.add(project);
}
}
return projectRoots;
}
protected boolean hasDependency(MavenProject rootProject, MavenProject dependentProject) {
if (rootProject.getDependencies() != null) {
for (Dependency dep : rootProject.getDependencies()) {
if (dep.getGroupId().equals(dependentProject.getGroupId())
&& dep.getArtifactId().equals(dependentProject.getArtifactId())) {
return true;
}
}
}
return false;
}
protected Set getSubProjects(MavenProject project, List reactorProjects) {
Set subProjects = new HashSet();
if (reactorProjects != null) {
for (MavenProject subProject : reactorProjects) {
if (isModule(project, subProject)) {
if (PackagingConstants.DAR_EXT.equals(subProject.getPackaging()) || (includeAllReactorProjects
&& (PackagingConstants.FEATURE_EXT.equals(subProject.getPackaging())
|| PackagingConstants.XDE_EXT.equals(subProject.getPackaging())))) {
subProjects.add(subProject);
}
subProjects.addAll(getSubProjects(subProject, reactorProjects));
}
}
}
return subProjects;
}
protected boolean isModule(MavenProject project, MavenProject subProject) {
for (String module : project.getModules()) {
File moduleFile = new File(project.getBasedir(), module);
if (subProject.getBasedir().equals(moduleFile) || subProject.getFile().equals(moduleFile)) {
return true;
}
}
return false;
}
protected Set getArtifacts(Set projects)
throws MojoExecutionException, MojoFailureException {
Set artifacts = new HashSet();
for (MavenProject proj : projects) {
if (PackagingConstants.ALL_DP_PACKAGING.contains(proj.getPackaging())) {
Artifact artifact = proj.getArtifact();
while (artifact.getFile() == null || !artifact.getFile().exists()) {
if (mavenSession.getResult().hasExceptions()) {
throw new MojoExecutionException(
"Stopping build of " + project.getId() + " because of upstream build failures.");
}
BuildSummary projectSummary = mavenSession.getResult().getBuildSummary(proj);
if (projectSummary instanceof BuildFailure) {
throw new MojoExecutionException(
"Failed to package SDU because of a build failure in project " + proj.getId());
} else if (projectSummary instanceof BuildSuccess) {
break;
}
// Need to use the artifact in the reactor, wait until it is
// ready if we have to
info(project.getId() + " is waiting on project in reactor to finish: " + proj.getId());
try {
Thread.sleep(1000);
} catch (Exception e) {
}
}
artifacts.add(artifact);
}
addAllDependencyArtifacts(proj.getModel(), null, artifacts);
}
return artifacts;
}
private void addAllDependencyArtifacts(Model model, List exclusions, Set artifacts)
throws MojoExecutionException {
if (model.getDependencies() == null) {
return;
}
Properties properties = getAllProperties(model);
for (Dependency dep : model.getDependencies()) {
if (!PackagingConstants.ALL_DP_PACKAGING.contains(dep.getType())) {
continue;
}
// We can't process standard exclusions for the parent device
// profile, because in order to load a parent package in the runtime
// we will need its original feature dependencies present. We can
// process any extra exclusions passed explicitly though.
if (!PackagingConstants.DAR_EXT.equals(dep.getType()) || exclusions == null) {
exclusions = extraExclusions;
} else if (extraExclusions != null) {
exclusions.addAll(extraExclusions);
}
if (exclusions != null) {
boolean skip = false;
for (Exclusion exclusion : exclusions) {
if (matches(exclusion, dep)) {
log.debug("Ignoring dependency " + dep + " because of exclusion " + "{groupId="
+ exclusion.getGroupId() + ", artifactId=" + exclusion.getArtifactId()
+ "} from project {groupId=" + model.getGroupId() + ", artifactId="
+ model.getArtifactId() + "}");
skip = true;
break;
}
}
if (skip) {
continue;
}
}
String version = resolve(properties, dep.getVersion());
boolean found = false;
for (Artifact artifact : artifacts) {
if (artifact.getArtifactId().equals(dep.getArtifactId())
&& artifact.getGroupId().equals(dep.getGroupId()) && artifact.getVersion().equals(version)
&& artifact.getType().equals(dep.getType())) {
found = true;
break;
}
}
MavenProject reactorProject = null;
for (MavenProject buildProject : reactorProjects) {
if (buildProject.getGroupId().equals(dep.getGroupId())
&& buildProject.getArtifactId().equals(dep.getArtifactId())
&& buildProject.getVersion().equals(version)) {
reactorProject = buildProject;
break;
}
}
if (!found) {
if (reactorProject == null) {
// Not in the reactor, need to get it from repository
org.eclipse.aether.artifact.Artifact art = new org.eclipse.aether.artifact.DefaultArtifact(
dep.getGroupId(), dep.getArtifactId(), dep.getType(), version);
art = getArtifact(art);
// danijoh2 - We must specify a non-null classifier,
// otherwise the contructor tries to
// access the artifact handler (null) in the case the
// classifier is specified as null.
String classifier = dep.getClassifier() == null ? dep.getType() : dep.getClassifier();
Artifact artifact = new org.apache.maven.artifact.DefaultArtifact(art.getGroupId(),
art.getArtifactId(), art.getVersion(), dep.getScope(), dep.getType(), classifier, null);
artifact.setFile(art.getFile());
artifacts.add(artifact);
} else {
Artifact artifact = reactorProject.getArtifact();
while (artifact.getFile() == null || !artifact.getFile().exists()) {
if (mavenSession.getResult().hasExceptions()) {
throw new MojoExecutionException(
"Stopping build of " + project.getId() + " because of upstream build failures.");
}
BuildSummary projectSummary = mavenSession.getResult().getBuildSummary(reactorProject);
if (projectSummary instanceof BuildFailure) {
throw new MojoExecutionException(
"Failed to package SDU because of a build failure in project "
+ reactorProject.getId());
} else if (projectSummary instanceof BuildSuccess) {
break;
}
// Need to use the artifact in the reactor, wait until
// it is ready if we have to
info(project.getId() + " is waiting on project in reactor to finish: "
+ reactorProject.getId());
try {
Thread.sleep(1000);
} catch (Exception e) {
}
}
artifacts.add(artifact);
}
}
Model depModel = null;
if (reactorProject != null) {
depModel = reactorProject.getModel();
} else {
depModel = getModelForDependency(dep, properties);
}
addAllDependencyArtifacts(depModel, dep.getExclusions(), artifacts);
}
}
private boolean matches(Exclusion exclusion, Dependency dep) {
if (!StringUtils.isEmpty(exclusion.getGroupId())) {
if (exclusion.getGroupId().contains("*")) {
String pattern = exclusion.getGroupId().replaceAll("\\*", ".*");
if (!dep.getGroupId().matches(pattern)) {
return false;
}
} else {
if (!dep.getGroupId().equals(exclusion.getGroupId())) {
return false;
}
}
}
if (!StringUtils.isEmpty(exclusion.getArtifactId())) {
if (exclusion.getArtifactId().contains("*")) {
String pattern = exclusion.getArtifactId().replaceAll("\\*", ".*");
if (!dep.getArtifactId().matches(pattern)) {
return false;
}
} else {
if (!dep.getArtifactId().equals(exclusion.getArtifactId())) {
return false;
}
}
}
return true;
}
private Properties getAllProperties(Model depModel) throws MojoExecutionException {
Properties properties = depModel.getProperties();
if (properties == null) {
properties = new Properties();
}
Parent parent = depModel.getParent();
// Add project.version property
String version = depModel.getVersion();
if (version == null || version.isEmpty()) {
if (parent != null) {
version = parent.getVersion();
}
}
if (version != null && !version.isEmpty()) {
properties.put("project.version", version);
}
while (parent != null) {
Model parentModel = getParentModel(parent);
Properties props = parentModel.getProperties();
if (props != null) {
properties.putAll(props);
}
parent = parentModel.getParent();
}
return properties;
}
private String resolve(Properties properties, String value) {
while (value.contains("${")) {
int start = value.indexOf("${");
int end = value.indexOf("}");
if (start == -1 || end == -1 || end <= start) {
break;
}
String orig = value.substring(start, end + 1);
String key = orig.substring(start + 2, orig.length() - 1);
if (!properties.containsKey(key)) {
break;
}
String resolved = properties.getProperty(key);
value = value.replace(orig, resolved);
}
if (value.contains("${")) {
info("Failed to resolve a property in the given value: " + value);
}
return value;
}
protected Map createSDUFileMap(Set artifacts) {
Map files = new TreeMap();
for (Artifact art : artifacts) {
File file = art.getFile();
if (file == null || !file.exists()) {
info("No file found for " + art.getGroupId() + PackagingConstants.DOT + art.getArtifactId()
+ PackagingConstants.DASH + art.getVersion());
continue;
}
// Replace .jar extension with the correct one (.dar, .feature,
// etc.)
String fileName = file.getName();
if (fileName.endsWith(PackagingConstants.JAR_EXT)) {
String ext = repoSession.getArtifactTypeRegistry().get(art.getType()).getExtension();
if (ext.equals(PackagingConstants.JAR_EXT)) {
continue;
}
fileName = fileName.substring(0, fileName.length() - PackagingConstants.JAR_EXT.length()) + ext;
}
if (fileName.endsWith(PackagingConstants.DAR_EXT)) {
// Device Profile, place at root of the .sdu
files.put(file, fileName);
} else {
// Feature or XDE, get path ACPM expects
fileName = getACPMPath(art) + fileName;
files.put(file, fileName);
}
// Save the version for when we create the manifest entries
dependencyVersionMap.put(art.getGroupId() + PackagingConstants.DOT + art.getArtifactId(),
art.getBaseVersion());
}
for (String path : files.values()) {
info("Adding: " + path);
}
return files;
}
protected File createSDU(Map files, Manifest mf, File baseDir, String name)
throws IOException, MojoExecutionException {
File sduFile = new File(baseDir, name);
if (sduFile.exists()) {
// .sdu file already exists, delete it
info("Deleting " + sduFile.getCanonicalPath());
if (!sduFile.delete()) {
throw new IOException("Failed to delete the already existing file " + sduFile.getCanonicalPath());
}
}
// Create the .sdu with the manifest
try (FileOutputStream jarStream = new FileOutputStream(sduFile)) {
try (JarOutputStream sduJar = new JarOutputStream(jarStream, mf)) {
int read;
byte[] buffer = new byte[1024];
CRC32 crc = new CRC32();
// Create versions.txt in SDU
String versionText = project.getGroupId() + "." + project.getArtifactId() + "-" + project.getVersion();
byte[] bytes = versionText.getBytes(Charset.forName("UTF-8"));
crc.update(bytes);
ZipEntry versionsFile = new ZipEntry("version.txt");
versionsFile.setMethod(ZipEntry.STORED);
versionsFile.setSize(bytes.length);
versionsFile.setCompressedSize(bytes.length);
versionsFile.setCrc(crc.getValue());
sduJar.putNextEntry(versionsFile);
sduJar.write(bytes);
// Add all device package artifacts
Set keys = files.keySet();
for (File file : keys) {
String newPath = files.get(file);
// Create Parent folder structure
if (newPath.contains(JarSeparator)) {
createParent(sduJar, newPath.substring(0, newPath.lastIndexOf(JarSeparator)));
}
// Gather CRC
BufferedInputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(file), 1024);
crc.reset();
while ((read = in.read(buffer)) != -1) {
crc.update(buffer, 0, read);
}
} finally {
if (in != null) {
in.close();
}
}
// Copy the file into the .sdu
ZipEntry entry = new ZipEntry(newPath);
entry.setMethod(ZipEntry.STORED);
entry.setCompressedSize(file.length());
entry.setSize(file.length());
entry.setCrc(crc.getValue());
sduJar.putNextEntry(entry);
in = null;
try {
in = new BufferedInputStream(new FileInputStream(file), 1024);
while ((read = in.read(buffer)) != -1) {
sduJar.write(buffer, 0, read);
}
} finally {
if (in != null) {
in.close();
}
}
}
}
}
return sduFile;
}
/** This is the separator that JAR files require **/
private static String JarSeparator = "/"; // $NON-NLS-1$
/**
* This is the artifact path in the jar that ACPM requires
*/
private String getACPMPath(Artifact art) {
return art.getGroupId().replace(".", JarSeparator) + JarSeparator + art.getArtifactId() + JarSeparator
+ art.getBaseVersion() + JarSeparator;
}
/**
* Since we are adding files to the JAR 'randomly' we will keep track of
* what folders we have already created in the JAR so we do not accidently
* overwrite them with a new entry.
*/
Set jarMap = new HashSet();
/**
* Creates all the parent folders for a file path.
*/
private void createParent(JarOutputStream jarSDU, String path) throws IOException {
if (path == null || path.isEmpty())
return;
// Recursively create parent folder
if (path.contains(JarSeparator)) {
createParent(jarSDU, path.substring(0, path.lastIndexOf(JarSeparator)));
}
// The path MUST end with the sepatrator character
if (!path.endsWith(JarSeparator)) {
path += JarSeparator;
}
// If we have already added it then return
if (jarMap.contains(path)) {
return;
}
// And the JAR entry
JarEntry entry = new JarEntry(path);
jarSDU.putNextEntry(entry);
jarSDU.closeEntry();
// And add it to the map.
jarMap.add(path);
}
/**
* Creates the manifest for the SDU. Traverses over the list of device
* profile projects to specify the load order in the manifest.
*
* @param deviceProfileProjects
* The device profile projects that are part of this build
* @return The Manifest
* @throws MojoExecutionException
*/
private Manifest createManifest(Set artifacts) throws MojoExecutionException {
/** Header info **/
Manifest mf = new Manifest();
Attributes mfAttr = mf.getMainAttributes();
mfAttr.putValue("Manifest-Version", "1.0");
mfAttr.putValue("Created-By", "Cisco Systems, Inc. XMP");
/** Specify device profile load order for ACPM **/
Map entries = mf.getEntries();
DependencyTree dependencyTree = createDependencyTree(artifacts);
for (Node root : dependencyTree.getRoots()) {
addEntry(entries, root);
}
return mf;
}
/**
* Counter used by the following function to keep track of how many device
* profiles have been added to the manifest file already.
*/
private int numEntries = 0;
/**
* Recursively checks for any dependencies on a device profile in a POM. If
* one is found it will be added to the list of entries with a number
* associating it with the order it needs to be loaded by ACPM. The highest
* order (parent) profile will be marked as devicePackage0 signifying it
* should be loaded first, and the lowest order (child) profile will be
* marked as devicePackageN where N is the number of parent device profiles
* that were found.
*
* @param project
* - The projects to process
*
* @throws MojoExecutionException
* - If any error occurs. Such as not being able to load the
* model for a parent dependency from Nexus or not having
* permissions to read the file.
*/
private DependencyTree createDependencyTree(Set artifacts) throws MojoExecutionException {
DependencyTree dependencyTree = new DependencyTree();
for (Artifact artifact : artifacts) {
Model model = getModel(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion());
Properties properties = getAllProperties(model);
if (model.getPackaging().equals(PackagingConstants.POM_EXT)) {
for (Dependency dep : model.getDependencies()) {
if (PackagingConstants.ALL_DP_PACKAGING.contains(dep.getType())) {
recursiveAddModelToTree(dependencyTree, getModelForDependency(dep, properties));
}
}
} else {
recursiveAddModelToTree(dependencyTree, model);
}
}
return dependencyTree;
}
private Node recursiveAddModelToTree(DependencyTree dependencyTree, Model model)
throws MojoExecutionException {
Node returnNode = dependencyTree.find(model);
if (returnNode != null) {
return returnNode;
}
Node parentNode = null;
Properties properties = getAllProperties(model);
List deps = model.getDependencies();
for (Dependency dep : deps) {
if (PackagingConstants.ALL_DP_PACKAGING.contains(dep.getType())) {
String version = dep.getVersion();
if (version == null || version.startsWith("[") || version.startsWith("(")) {
String id = dep.getGroupId() + PackagingConstants.DOT + dep.getArtifactId();
// We saved a map of all the device package versions, lets
if (dependencyVersionMap != null && dependencyVersionMap.containsKey(id)) {
String resolvedVersion = dependencyVersionMap.get(id);
dep.setVersion(resolvedVersion);
}
}
Model depModel = getModelForDependency(dep, properties);
if (depModel == null) {
String id = dep.getGroupId() + ":" + dep.getArtifactId() + ":" + dep.getVersion() + ":pom";
error("Could not find model for " + id + ". SDU manifest may be incomplete.");
continue;
}
parentNode = dependencyTree.find(depModel);
if (parentNode == null) {
parentNode = recursiveAddModelToTree(dependencyTree, depModel);
}
}
}
return parentNode == null ? dependencyTree.addRoot(model) : parentNode.addChild(model);
}
private void addEntry(Map entries, Node node) throws MojoExecutionException {
Model model = node.getData();
Attributes attr = new Attributes();
String groupId = model.getGroupId();
if (StringUtils.isEmpty(groupId)) {
if (model.getParent() != null) {
groupId = model.getParent().getGroupId();
}
}
String artifactId = model.getArtifactId();
String version = model.getVersion();
if (StringUtils.isEmpty(version)) {
if (model.getParent() != null) {
version = model.getParent().getVersion();
}
}
if (StringUtils.isEmpty(groupId) || StringUtils.isEmpty(artifactId) || StringUtils.isEmpty(version)) {
throw new MojoExecutionException("An error occurred resolving groupId, artifactId, or version of model: "
+ model + ". groupId=" + groupId + ", artifactId=" + artifactId + ", version=" + version);
}
attr.putValue(SDU_MANIFEST_ATTR_GROUP_ID, groupId);
attr.putValue(SDU_MANIFEST_ATTR_ARTIFACT_ID, artifactId);
attr.putValue(SDU_MANIFEST_ATTR_VERSION, version);
attr.putValue(SDU_MANIFEST_ATTR_TYPE, node.getData().getPackaging());
entries.put(SDU_MANIFEST_ATTR_LOAD_ORDER + numEntries++, attr);
for (Node childNode : node.getChildren()) {
addEntry(entries, childNode);
}
}
/**
* Attempts to load the maven model for a dependency by querying Aether for
* the pom file from the nexus repository and then loading it as a POM.
*
* @param dep
* - The dependency
*
* @return - The POM
* @throws MojoExecutionException
* - If any error occurs
*/
private Model getModelForDependency(Dependency dep, Properties properties) throws MojoExecutionException {
return getModel(dep.getGroupId(), dep.getArtifactId(), resolve(properties, dep.getVersion()));
}
/**
* Uses Aether to find the pom file that is in the nexus repository for this
* dependency.
*
* @param dep
* - The dependency
*
* @return - The pom file, null if it was not found.
* @throws MojoExecutionException
* - If any error occurs
*/
private Model getParentModel(Parent parent) throws MojoExecutionException {
return getModel(parent.getGroupId(), parent.getArtifactId(), parent.getVersion());
}
private Model getModel(String groupId, String artifactId, String version) throws MojoExecutionException {
if (reactorProjects != null) {
Model modelInReactor = reactorProjects.parallelStream()
.filter(project -> project.getGroupId().equals(groupId)
&& project.getArtifactId().equals(artifactId) && project.getVersion().equals(version))
.map(project -> project.getModel()).findFirst().orElse(null);
if (modelInReactor != null) {
debug("Artifact found in reactor: " + groupId + ":" + artifactId + ":" + version + ":pom");
return modelInReactor;
}
}
org.eclipse.aether.artifact.Artifact art = new org.eclipse.aether.artifact.DefaultArtifact(groupId, artifactId,
PackagingConstants.POM_EXT, version);
return readModel(getArtifact(art).getFile());
}
/**
* Attempts to load the maven model for a dependency by querying Aether for
* the pom file from the nexus repository and then loading it as a POM.
*
* @param dep
* - The dependency
*
* @return - The POM
* @throws MojoExecutionException
* - If any error occurs
*/
private Model readModel(File pomFile) throws MojoExecutionException {
Model model = null;
if (pomFile != null && pomFile.exists()) {
DefaultModelReader reader = new DefaultModelReader();
try {
model = reader.read(pomFile, null);
} catch (IOException e) {
throw new MojoExecutionException(e.getMessage(), e);
}
}
return model;
}
/**
* Gets the artifact from the Nexus using Aether
*
* @param artifactName
* - Artifact name in format groupId:artifactId:type:version
*
* @return - The resulting artifact file
*/
private org.eclipse.aether.artifact.Artifact getArtifact(org.eclipse.aether.artifact.Artifact artifact)
throws MojoExecutionException {
if (artifact.getVersion().startsWith("[") || artifact.getVersion().startsWith("(")) {
VersionRangeRequest versionRequest = new VersionRangeRequest();
versionRequest.setArtifact(artifact);
versionRequest.setRepositories(remoteRepos);
try {
VersionRangeResult result = repoSystem.resolveVersionRange(repoSession, versionRequest);
Iterator iter = result.getVersions().iterator();
Version v = null;
while (iter.hasNext()) {
v = iter.next();
}
artifact = new org.eclipse.aether.artifact.DefaultArtifact(artifact.getGroupId(),
artifact.getArtifactId(), artifact.getExtension(), v.toString());
} catch (VersionRangeResolutionException e) {
throw new MojoExecutionException(e.getMessage(), e);
}
}
try {
ArtifactRequest request = new ArtifactRequest(artifact, remoteRepos, null);
ArtifactResult result = repoSystem.resolveArtifact(repoSession, request);
return result.getArtifact();
} catch (ArtifactResolutionException e) {
throw new MojoExecutionException(e.getMessage(), e);
}
}
private void debug(String msg) {
if (log != null) {
log.debug(msg);
}
}
private void info(String msg) {
if (log != null) {
log.info(msg);
}
}
private void error(String msg) {
if (log != null) {
log.error(msg);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy