All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.cargo.maven3.DependencyCalculator Maven / Gradle / Ivy

The newest version!
/*
 * ========================================================================
 *
 * Codehaus Cargo, copyright 2004-2011 Vincent Massol, 2012-2024 Ali Tokmen.
 *
 * 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.codehaus.cargo.maven3;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuilder;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.project.ProjectBuildingResult;
import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate;
import org.apache.maven.shared.transfer.artifact.install.ArtifactInstaller;
import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver;
import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver;

/**
 * This class is effectively an unmitigated hack. Any offers to do it 'properly' are gratefully
 * received from someone who can get the guts of Maven to do what want.

* Basically, given our 'uberwar' project, instead of simply merging WEB-INF/lib files, we wish to * treat those war files as ordinary dependencies, and to calculate the 'effective' list of jar * files that SHOULD be in WEB-INF/lib that way. I.E, if we are including A.WAR and B.WAR, both of * which use different versions of X.JAR, then we should calculate what the 'right' version of the * X.JAR that we ought to be using.

* This seems very hard to do given the tools provided by maven. There are alternate solutions, such * as WAR files producing their code in a JAR as well, but this relies on including BOTH the WAR and * the JAR, which is not pretty.

* This class does it a hacky way. For each of the war files in the dependency tree (including the * caller), it generates an alternate pom file, which 'pretends' that the WAR file is a POM, and * replaces any dependent WARS with equivalent dependencies of type POM with a different classifier. * It then invokes maven to resolve that project, which appears to resolve the versions (as would * have been done in an all-jar universe).

* A better way would probably be to be able to customise the dependency calculation system, but * this seems very bound up in all the project/artifact gubbins. */ public class DependencyCalculator { /** * Maven artifact resolver, used to dynamically resolve JARs for the containers and also to * resolve the JARs for the embedded container's classpaths. */ @Component private ArtifactResolver artifactResolver; /** * Maven dependency resolver, used to dynamically resolve dependencies of artifacts. */ @Component private DependencyResolver dependencyResolver; /** * Maven project building request. */ @Parameter( defaultValue = "${session.projectBuildingRequest}", readonly = true, required = true) private ProjectBuildingRequest projectBuildingRequest; /** * The Maven project. */ @Parameter(property = "project", readonly = true, required = true) private MavenProject mavenProject; /** * Maven project builder, used to calculate dependencies. */ @Component private ProjectBuilder mavenProjectBuilder; /** * Maven artifact installer, used to calculate dependencies. */ @Component private ArtifactInstaller installer; /** * Saves all attributes. * @param dependencyResolver Dependency resolver. * @param artifactResolver Artifact resolver. * @param projectBuildingRequest Maven 3 project building request. * @param mavenProject Maven 3 project. * @param mavenProjectBuilder Maven 3 project builder. * @param installer Artifact installer. */ public DependencyCalculator(DependencyResolver dependencyResolver, ArtifactResolver artifactResolver, ProjectBuildingRequest projectBuildingRequest, MavenProject mavenProject, ProjectBuilder mavenProjectBuilder, ArtifactInstaller installer) { this.dependencyResolver = dependencyResolver; this.artifactResolver = artifactResolver; this.projectBuildingRequest = projectBuildingRequest; this.mavenProject = mavenProject; this.mavenProjectBuilder = mavenProjectBuilder; this.installer = installer; } /** * Execute the dependency calculator. * @return List of dependency files. * @throws Exception If anything goes wrong. */ public Set execute() throws Exception { fixupProjectArtifact(); // Calculate the new deps Artifact art = mavenProject.getArtifact(); DefaultArtifactCoordinate containerArtifactCoordinate = new DefaultArtifactCoordinate(); containerArtifactCoordinate.setGroupId(art.getGroupId() + ".cargodeps"); containerArtifactCoordinate.setArtifactId(art.getArtifactId()); containerArtifactCoordinate.setVersion(art.getVersion()); containerArtifactCoordinate.setExtension("pom"); Artifact art2 = artifactResolver.resolveArtifact( projectBuildingRequest, containerArtifactCoordinate).getArtifact(); ProjectBuildingResult projectBuildingResult = mavenProjectBuilder.build(art2, projectBuildingRequest); Set filesToAdd = new HashSet(); for (Artifact artifact : projectBuildingResult.getProject().getArtifacts()) { if (artifact.getType().equals("jar")) { filesToAdd.add(artifact.getFile()); } } return filesToAdd; } /** * Fixup the project artifact. * @throws Exception If anything goes wrong. */ protected void fixupProjectArtifact() throws Exception { MavenProject mp2 = mavenProject.clone(); // For each of our dependencies.. for (Artifact artifact : mp2.getArtifacts()) { if (artifact.getType().equals("war")) { DefaultArtifactCoordinate containerArtifactCoordinate = new DefaultArtifactCoordinate(); containerArtifactCoordinate.setGroupId(artifact.getGroupId()); containerArtifactCoordinate.setArtifactId(artifact.getArtifactId()); containerArtifactCoordinate.setVersion(artifact.getVersion()); containerArtifactCoordinate.setExtension("pom"); Artifact art2 = artifactResolver.resolveArtifact( projectBuildingRequest, containerArtifactCoordinate).getArtifact(); fixupRepositoryArtifact(art2); } } // If we mess with this model, it's the 'REAL' model. So lets copy it Model pomFile = mp2.getModel(); File outFile = File.createTempFile("pom", ".xml"); MavenXpp3Writer pomWriter = new MavenXpp3Writer(); pomWriter.write(new FileWriter(outFile), pomFile); MavenXpp3Reader pomReader = new MavenXpp3Reader(); pomFile = pomReader.read(new FileReader(outFile)); Artifact art = mp2.getArtifact(); fixModelAndSaveInRepository(art, pomFile); outFile.delete(); } /** * Fixup an artifact. * @param artifact Artifact to fixup. * @throws Exception If anything goes wrong. */ protected void fixupRepositoryArtifact(Artifact artifact) throws Exception { File artifactFile = artifact.getFile(); ProjectBuildingResult projectBuildingResult = mavenProjectBuilder.build(artifact, projectBuildingRequest); for (Artifact createdArtifact : projectBuildingResult.getProject().getArtifacts()) { if (createdArtifact.getType().equals("war")) { DefaultArtifactCoordinate containerArtifactCoordinate = new DefaultArtifactCoordinate(); containerArtifactCoordinate.setGroupId(createdArtifact.getGroupId()); containerArtifactCoordinate.setArtifactId(createdArtifact.getArtifactId()); containerArtifactCoordinate.setVersion(createdArtifact.getVersion()); containerArtifactCoordinate.setExtension("pom"); Artifact art2 = artifactResolver.resolveArtifact( projectBuildingRequest, containerArtifactCoordinate).getArtifact(); fixupRepositoryArtifact(art2); } } MavenXpp3Reader pomReader = new MavenXpp3Reader(); Model pomFile = pomReader.read(new FileReader(artifactFile)); fixModelAndSaveInRepository(artifact, pomFile); } /** * Fix model and save in repository. * @param artifact Artifact. * @param pomFile Maven 3 model file. * @throws Exception If anything goes wrong. */ protected void fixModelAndSaveInRepository(Artifact artifact, Model pomFile) throws Exception { for (Object dependency : pomFile.getDependencies()) { Dependency art = (Dependency) dependency; if (art.getType().equals("war")) { art.setGroupId(art.getGroupId() + ".cargodeps"); art.setType("pom"); } } pomFile.setPackaging("pom"); String version = pomFile.getVersion(); if (version == null) { version = pomFile.getParent().getVersion(); } File outFile = File.createTempFile("pom", ".xml"); MavenXpp3Writer pomWriter = new MavenXpp3Writer(); pomWriter.write(new FileWriter(outFile), pomFile); DefaultArtifactCoordinate containerArtifactCoordinate = new DefaultArtifactCoordinate(); containerArtifactCoordinate.setGroupId(artifact.getGroupId() + ".cargodeps"); containerArtifactCoordinate.setArtifactId(artifact.getArtifactId()); containerArtifactCoordinate.setVersion(artifact.getVersion()); containerArtifactCoordinate.setExtension("pom"); Artifact art2 = artifactResolver.resolveArtifact( projectBuildingRequest, containerArtifactCoordinate).getArtifact(); List artifactList = new ArrayList(1); artifactList.add(art2); installer.install(projectBuildingRequest, artifactList); outFile.delete(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy