All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.apache.openejb.maven.plugin.spi.SpiMojo Maven / Gradle / Ivy
/**
* 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.
*/
package org.apache.openejb.maven.plugin.spi;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
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.artifact.versioning.VersionRange;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.apache.xbean.finder.Annotated;
import org.apache.xbean.finder.AnnotationFinder;
import org.apache.xbean.finder.archive.Archive;
import org.apache.xbean.finder.archive.ClasspathArchive;
import org.apache.xbean.finder.archive.FileArchive;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
/**
* @goal generate
* @requiresDependencyResolution compile+runtime
* @phase compile
*/
public class SpiMojo extends AbstractMojo {
private static final String PROFILE_PATH = "org/apache/xbean/profile.properties";
/**
* @parameter default-value="${project.build.outputDirectory}"
* @required
*/
private File module;
/**
* @parameter default-value="${project}"
* @required
* @readonly
*/
private MavenProject project;
/**
* @parameter
*/
private List annotations;
/**
* @parameter
*/
private List subclasses;
/**
* @parameter
*/
private List implementations;
/**
* @parameter
*/
private List profiles;
/**
* @parameter expression="${spi.output}" default-value="${project.build.outputDirectory}/META-INF/scan.xml"
*
* for webapp: ${project.build.directory}/${project.build.finalName}/WEB-INF/classes/META-INF/scan.xml
*/
private String outputFilename;
/**
* @parameter expression="${spi.meta}" default-value="false"
*/
private boolean useMeta;
/**
* @parameter expression="${spi.aggregated-archive}" default-value="true"
*/
private boolean useAggregatedArchiveIfWar;
/**
* @parameter default-value="${project.packaging}"
* @readonly
*/
private String packaging;
/**
* @parameter expression="${project.pluginArtifactRepositories}"
* @required
* @readonly
*/
private List remotePluginRepositories;
/**
* @parameter expression="${localRepository}"
* @readonly
* @required
*/
private ArtifactRepository local;
/**
* @component
*/
protected ArtifactResolver resolver;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
final Map loadedProfiles = loadProfiles();
//
// create profiles to use
//
final List profileToUse = new ArrayList();
if (profiles != null) {
for (String profile : profiles) {
if (loadedProfiles.containsKey(profile)) {
profileToUse.add(loadedProfiles.get(profile));
} else {
getLog().info("can't find profile " + profile + ", available ones are " + loadedProfiles.keySet());
}
}
}
if (annotations != null || subclasses != null || implementations != null) {
profileToUse.add(new Profile(annotations, subclasses, implementations));
}
if (profileToUse.isEmpty() && loadedProfiles.size() > 0) {
final Map.Entry profile = loadedProfiles.entrySet().iterator().next();
getLog().info("using profile " + profile.getKey());
profileToUse.add(profile.getValue());
}
if (profileToUse.isEmpty()) {
getLog().warn("no profile or configuration, nothing will be done");
return;
}
//
// creating the archive and its classloader
//
// war is different since it will contain a single descriptor for its lib too (not an ear)
boolean war = "war".equals(packaging);
final Archive archive;
final URLClassLoader loader = createClassLoader(providedDependenciesClassLoader());
if (war && useAggregatedArchiveIfWar) {
archive = new ClasspathArchive(loader, loader.getURLs());
getLog().info("using an aggregated archive");
} else {
archive = new FileArchive(loader, module);
getLog().info("using a file archive");
}
// the result
final Set classes = new TreeSet();
try {
final AnnotationFinder finder = new AnnotationFinder(archive);
finder.link();
//
// find classes
//
for (Profile profile : profileToUse) {
if (profile.getAnnotations() != null) {
for (String annotation : profile.getAnnotations()) {
final Class extends Annotation> annClazz;
try {
annClazz = (Class extends Annotation>) load(loader, annotation);
} catch (MojoFailureException mfe) {
getLog().warn("can't find " + annotation);
continue;
}
if (!useMeta) {
for (Class> clazz : finder.findAnnotatedClasses(annClazz)) {
classes.add(clazz.getName());
}
} else {
for (Annotated> clazz : finder.findMetaAnnotatedClasses(annClazz)) {
classes.add(clazz.get().getName());
}
}
if (!useMeta) {
for (Field clazz : finder.findAnnotatedFields(annClazz)) {
classes.add(clazz.getDeclaringClass().getName());
}
} else {
for (Annotated clazz : finder.findMetaAnnotatedFields(annClazz)) {
classes.add(clazz.get().getDeclaringClass().getName());
}
}
if (!useMeta) {
for (Method clazz : finder.findAnnotatedMethods(annClazz)) {
classes.add(clazz.getDeclaringClass().getName());
}
} else {
for (Annotated clazz : finder.findMetaAnnotatedMethods(annClazz)) {
classes.add(clazz.get().getDeclaringClass().getName());
}
}
}
}
if (profile.getSubclasses() != null) {
for (String subclass : profile.getSubclasses()) {
try {
for (Class> clazz : finder.findSubclasses(load(loader, subclass))) {
classes.add(clazz.getName());
}
} catch (MojoFailureException mfe) {
getLog().warn("can't find " + subclass);
}
}
}
if (profile.getImplementations() != null) {
for (String implementation : profile.getImplementations()) {
try {
for (Class> clazz : finder.findImplementations(load(loader, implementation))) {
classes.add(clazz.getName());
}
} catch (MojoFailureException mfe) {
getLog().warn("can't find " + implementation);
}
}
}
}
//
// dump found classes
//
final File output = new File(outputFilename);
if (!output.getParentFile().exists() && !output.getParentFile().mkdirs()) {
getLog().error("can't create " + output.getParent());
return;
}
final XMLStreamWriter out = XMLOutputFactory.newInstance().createXMLStreamWriter(new FileWriter(outputFilename));
try {
out.writeStartDocument();
out.writeStartElement("scan");
out.writeCharacters("\n");
out.writeCharacters(" ");
out.writeStartElement("classes");
out.writeCharacters("\n");
for (String clazz : classes) {
out.writeCharacters(" ");
out.writeStartElement("class");
out.writeCharacters(clazz);
out.writeEndElement();
out.writeCharacters("\n");
}
out.writeCharacters(" ");
out.writeEndElement();
out.writeCharacters("\n");
out.writeCharacters(" ");
out.writeStartElement("packages");
out.writeCharacters("\n ");
out.writeEndElement();
out.writeCharacters("\n");
out.writeEndElement();
out.writeEndDocument();
} finally {
out.flush();
out.close();
}
getLog().info("generated " + output.getPath());
} catch (Exception e) {
getLog().error(e);
}
}
private Map loadProfiles() {
final Map profiles = new HashMap();
try {
final Enumeration urls = Thread.currentThread().getContextClassLoader().getResources(PROFILE_PATH);
while (urls.hasMoreElements()) {
final URL url = urls.nextElement();
final Properties properties = new Properties();
properties.load(new BufferedInputStream(url.openStream()));
final String name = properties.getProperty("name");
if (name == null) {
getLog().warn("ignoring " + url.toExternalForm() + " since it doesn't contain a name");
}
final List profileAnnotations = list(properties.getProperty("annotations"));
final List profileSubclasses = list(properties.getProperty("subclasses"));
final List profileImplementations = list(properties.getProperty("implementations"));
profiles.put(name, new Profile(profileAnnotations, profileSubclasses, profileImplementations));
}
} catch (Exception e) {
getLog().warn("can't look for profiles");
}
return profiles;
}
private static List list(final String commaSeparatedList) {
final List list = new ArrayList();
if (commaSeparatedList != null) {
for (String value : commaSeparatedList.split(",")) {
final String trimmed = value.trim();
if (!trimmed.isEmpty()) {
list.add(trimmed);
}
}
}
return list;
}
private ClassLoader providedDependenciesClassLoader() {
final Set urls = new HashSet();
// provided artifacts
for (Artifact artifact : (Set) project.getDependencyArtifacts()) {
if (!"provided".equals(artifact.getScope())) {
continue;
}
try {
urls.add(artifact.getFile().toURI().toURL());
} catch (MalformedURLException e) {
getLog().warn("can't use artifact " + artifact.toString());
}
}
// plugin dependencies
final Plugin thisPlugin = (Plugin) project.getBuild().getPluginsAsMap().get("org.apache.openejb:spi-helper-maven-plugin");
if (thisPlugin != null && thisPlugin.getDependencies() != null) {
for (Dependency artifact : thisPlugin.getDependencies()) {
final Artifact resolved = new DefaultArtifact(
artifact.getGroupId(), artifact.getArtifactId(), VersionRange.createFromVersion(artifact.getVersion()),
artifact.getScope(), artifact.getType(), artifact.getClassifier(), new DefaultArtifactHandler());
try {
resolver.resolve(resolved, remotePluginRepositories, local);
urls.add(resolved.getFile().toURI().toURL());
} catch (ArtifactResolutionException e) {
getLog().warn("can't resolve " + artifact.getArtifactId());
} catch (ArtifactNotFoundException e) {
getLog().warn("can't find " + artifact.getArtifactId());
} catch (MalformedURLException e) {
getLog().warn("can't get url of " + resolved.getFile() + " for artifact " + resolved.getArtifactId());
}
}
}
return new URLClassLoader(urls.toArray(new URL[urls.size()]), ClassLoader.getSystemClassLoader());
}
private Class> load(final ClassLoader loader, final String name) throws MojoFailureException {
try {
return loader.loadClass(name);
} catch (ClassNotFoundException e) {
throw new MojoFailureException("can't load " + name, e);
}
}
private URLClassLoader createClassLoader(final ClassLoader parent) {
final List urls = new ArrayList();
for (Artifact artifact : (Set) project.getArtifacts()) {
try {
urls.add(artifact.getFile().toURI().toURL());
} catch (MalformedURLException e) {
getLog().warn("can't use artifact " + artifact.toString());
}
}
if (module.exists()) {
try {
urls.add(module.toURI().toURL());
} catch (MalformedURLException e) {
getLog().warn("can't use path " + module.getPath());
}
} else {
getLog().warn("can't find " + module.getPath());
}
return new URLClassLoader(urls.toArray(new URL[urls.size()]), parent);
}
public static final class Profile {
private List annotations;
private List subclasses;
private List implementations;
public Profile(final List annotations, final List subclasses, final List implementations) {
this.annotations = annotations;
this.subclasses = subclasses;
this.implementations = implementations;
}
public List getAnnotations() {
return annotations;
}
public List getSubclasses() {
return subclasses;
}
public List getImplementations() {
return implementations;
}
}
}