com.sun.enterprise.module.maven.MavenProjectRepository Maven / Gradle / Ivy
Show all versions of hk2-maven Show documentation
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2007-2015 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.enterprise.module.maven;
import com.sun.enterprise.module.ManifestConstants;
import com.sun.enterprise.module.ModuleDefinition;
import com.sun.enterprise.module.Repository;
import com.sun.enterprise.module.common_impl.AbstractRepositoryImpl;
import com.sun.enterprise.module.common_impl.ModuleId;
import com.sun.enterprise.module.common_impl.AbstractFactory;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.model.Resource;
import org.apache.maven.project.MavenProject;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* {@link Repository} implementation that loads modules
* from the transitive dependencies set in a {@link MavenProject}.
*
* @author Kohsuke Kawaguchi
*/
public class MavenProjectRepository extends AbstractRepositoryImpl {
private final MavenProject project;
// needed to resolve additional artifacts
private final ArtifactResolver artifactResolver;
private final ArtifactRepository localRepository;
private final ArtifactFactory artifactFactory;
/**
* All {@link Artifact}s in the transitive dependency list
* keyed by their {@link Artifact#getId() id}.
*/
private final Map artifacts = new HashMap();
public MavenProjectRepository(MavenProject project, ArtifactResolver artifactResolver, ArtifactRepository localRepository, ArtifactFactory artifactFactory) {
super(project.getName(),project.getFile().toURI());
this.project = project;
this.artifactResolver = artifactResolver;
this.localRepository = localRepository;
this.artifactFactory = artifactFactory;
// adds the ones that we already know of.
Artifact ma = project.getArtifact();
if(ma.getFile()!=null) {
// if the 'ma' is the distribution module, it won't have its own output.
artifacts.put(ma.getId(),ma);
}
for (Artifact a : (Set) project.getArtifacts())
artifacts.put(a.getId(),a);
}
/**
* When creating {@link MavenProjectRepository} from the current project (which is used
* to launch mvn), and if the compile phase has run yet, then the main artifact is
* still null.
*
*
* However, it's often convenient to pick up the files that were left in the file system
* from the previous execution. This method checks this situation and updates {@link MavenProject}
* accordingly, so that it can be then passed to the constructor of {@link MavenProjectRepository}.
*
*
* Think of this as a pre-processing phase to compensate for the lack of the compile phase
* invocation.
*/
public static void prepareProject(MavenProject project) throws IOException {
Artifact ma = project.getArtifact();
if(!project.getPackaging().equals("pom") && ma.getFile()==null) {
File outdir = new File(project.getBuild().getOutputDirectory());
if(!outdir.exists())
logger.warning("No output directory "+outdir);
else
ma.setFile(outdir);
}
if(ma.getFile()!=null) {
// if the 'ma' is the distribution module, it won't have its own output.
if(ma.getFile().isDirectory()) {
// if the main artifact is from target/classes, create META-INF.MF
new Packager().writeManifest(project,ma.getFile());
}
}
}
@Override
protected void loadModuleDefs(Map moduleDefs, List libraries) throws IOException {
logger.info("Loading modules list from "+project.getFile());
MavenModuleDefinition main = buildModule(project.getArtifact(), moduleDefs, libraries);
if(main!=null) {
// artifact from the main project, in case those are not compiled yet
logger.info("Adding classpath entry: "+project.getBuild().getOutputDirectory());
main.addClasspath(new File(project.getBuild().getOutputDirectory()));
for (Resource res : (List)project.getBuild().getResources()) {
logger.info("Adding classpath entry: "+res.getDirectory());
main.addClasspath(new File(res.getDirectory()));
}
}
for (Artifact a : (List) project.getAttachedArtifacts()) {
buildModule(a, moduleDefs, libraries);
}
for (Artifact a : (Set) project.getArtifacts()) {
buildModule(a, moduleDefs, libraries);
}
if(moduleDefs.isEmpty()) {
// throw new Error("No modules found");// should this error check be done by the caller of loadModuleDefs?
logger.warning("No modules found");
}
}
private MavenModuleDefinition buildModule(Artifact a, Map moduleDefs, List libraries)
throws IOException {
File jarFile = a.getFile();
if(jarFile==null || (!jarFile.getName().endsWith(".jar") && !jarFile.isDirectory()))
// between the compile phase and the package phase, the main artifact is
// set to the target/classes. allow that to be used as a jar.
return null;
MavenModuleDefinition moduleDef = loadJar(jarFile);
if(moduleDef.getManifest().getMainAttributes().getValue(ManifestConstants.BUNDLE_NAME)==null) {
// project.getArtifacts() pick up all the transitive dependencies,
// including to the normal jar files through modules.
libraries.add(jarFile.toURI());
return null;
}
if(logger.isLoggable(Level.CONFIG))
logger.config("Adding module "+a.getId()+" trail: "+a.getDependencyTrail());
moduleDefs.put(AbstractFactory.getInstance().createModuleId(moduleDef), moduleDef);
return moduleDef;
}
/*package*/ File resolveArtifact(String id) throws IOException {
Artifact artifact = artifacts.get(id);
if(artifact!=null) return artifact.getFile();
try {
Matcher m = ID_PATTERN.matcher(id);
if(!m.matches())
throw new IllegalArgumentException("Wrong ID: "+id);
Artifact a = artifactFactory.createArtifactWithClassifier(
m.group(1), m.group(2), m.group(5), m.group(3), m.group(4)
);
artifactResolver.resolve(a, project.getRemoteArtifactRepositories(), localRepository );
artifacts.put(a.getId(),a);
return a.getFile();
} catch (ArtifactResolutionException e) {
throw new IOException2("Failed to resolve "+id,e);
} catch (ArtifactNotFoundException e) {
throw new IOException2("Failed to resolve "+id,e);
}
}
// the format is 'groupId:artifactId:type(:classifier)?:version
private static final String TOKEN = "([^:]+)";
private static final Pattern ID_PATTERN = Pattern.compile(MessageFormat.format("{0}:{0}:{0}(?:\\:{0})?:{0}",TOKEN));
protected MavenModuleDefinition loadJar(File jar) throws IOException {
return new MavenModuleDefinition(this,jar);
}
private static final Logger logger = Logger.getLogger(MavenProjectRepository.class.getName());
}