Java tutorial
/* * MicroJIAC - A Lightweight Agent Framework * This file is part of MicroJIAC MIDlet-Maven-Plugin. * * Copyright (c) 2007-2012 DAI-Labor, Technische Universitt Berlin * * This library includes software developed at DAI-Labor, Technische * Universitt Berlin (http://www.dai-labor.de) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> */ /* * $Id$ */ package de.jiac.micro.mojo; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URI; import java.net.URL; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; 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.ArtifactResolutionResult; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.model.Model; import org.apache.maven.model.Parent; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.DefaultProjectBuilderConfiguration; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectBuilder; import org.apache.maven.project.ProjectBuildingException; import org.apache.maven.project.artifact.InvalidDependencyVersionException; import org.apache.maven.project.artifact.MavenMetadataSource; import org.apache.maven.project.inheritance.ModelInheritanceAssembler; import org.apache.maven.project.interpolation.ModelInterpolationException; import org.apache.maven.project.interpolation.ModelInterpolator; import org.slf4j.Logger; import de.jiac.micro.config.generator.AbstractConfiguration; import de.jiac.micro.config.generator.ConfigurationGenerator; import de.jiac.micro.util.ModifiedURLClassLoader; /** * Generates all configuration classes for nodes and agents. * * @goal genconfig * @requiresDependencyResolution compile * @description Generates the configurator class to ease the obfuscation. * * @author Marcel Patzlaff * @version $Revision$ */ public class ConfiguratorMojo extends AbstractMojo { public static final String GENERATED_CONFIGURATIONS_KEY = "Generated-Configurations"; /** * The Maven project reference. * * @parameter expression="${project}" * @required * @readonly */ private MavenProject project; /** * The directory for the compiled classes. * * @parameter expression="${project.build.outputDirectory}" * @required * @readonly */ private File outputDirectory; /** * @parameter expression="${project.build.directory}/generated-src" * @required */ private File generatedSourceDirectory; /** * Defines the namespace where the application definition is located * * @parameter * @required */ private String applicationDefinition; /** * The reference to an artifact resolver. * * @component * @required */ private ArtifactResolver artifactResolver; /** * The factory to create artifacts with. * * @component * @required */ private ArtifactFactory artifactFactory; /** * The source to creata artifact meta data from. * * @component * @required */ private ArtifactMetadataSource metadataSource; /** * The Maven project builder. * * @component * @required */ private MavenProjectBuilder mavenProjectBuilder; /** * The reference to the default model inheritance assembler. * * @component * @required */ private ModelInheritanceAssembler modelInheritanceAssembler; /** * The reference to the default model interpolator. * * @component * @required */ private ModelInterpolator modelInterpolator; /** * The reference to the local artifact repository. * * @parameter expression="${localRepository}" * @required * @readonly */ private ArtifactRepository localRepository; /** * The list of remote artifact repositories. * * @parameter expression="${project.remoteArtifactRepositories}" * @required * @readonly */ private List<ArtifactRepository> remoteRepositories; /** * Processes all dependencies first and then creates a new JVM to * generate the configurator implementation with. */ public void execute() throws MojoExecutionException { ClassLoader classloader; try { classloader = createClassLoader(); } catch (Exception e) { throw new MojoExecutionException("could not create classloader from dependencies", e); } AbstractConfiguration[] configurations; try { configurations = ConfigurationGenerator.execute(generatedSourceDirectory, applicationDefinition, classloader, getSLF4JLogger()); } catch (Exception e) { throw new MojoExecutionException("could not generate the configurator", e); } getPluginContext().put(GENERATED_CONFIGURATIONS_KEY, configurations); project.addCompileSourceRoot(generatedSourceDirectory.getPath()); } private ClassLoader createClassLoader() throws Exception { Set<URI> classpath = new HashSet<URI>(); // the current projects runtime dependencies HashSet<Artifact> artifacts = new HashSet<Artifact>(); // artifacts.addAll(project.getSystemArtifacts()); // artifacts.addAll(project.getRuntimeArtifacts()); artifacts.addAll(project.getCompileArtifacts()); for (Artifact artifact : artifacts) { File file = artifact.getFile(); if (file != null) { classpath.add(file.toURI()); } else { getLog().warn("could not find artifact file for '" + artifact.getArtifactId()); } } classpath.add(outputDirectory.toURI()); // plugin dependencies, because we want to run a class from this plugin MavenXpp3Reader reader = new MavenXpp3Reader(); InputStreamReader in = new InputStreamReader(getPluginPOM(classpath)); Model pluginModel = checkModel(reader.read(in)); Set pluginDeps = transitivelyResolvePomDependencies(pluginModel.getGroupId(), pluginModel.getArtifactId(), pluginModel.getVersion()); for (Object artObj : pluginDeps) { File file = ((Artifact) artObj).getFile(); if (file != null) { classpath.add(file.toURI()); } } URL[] urls = new URL[classpath.size()]; int i = 0; for (URI uri : classpath) { urls[i++] = uri.toURL(); } return new ModifiedURLClassLoader(urls); } private InputStream getPluginPOM(Set<URI> classpath) throws IOException { File file = new File(getClass().getProtectionDomain().getCodeSource().getLocation().getFile()); classpath.add(file.toURI()); JarFile jarFile = new JarFile(file); for (JarEntry entry : Collections.list(jarFile.entries())) { if (entry.getName().endsWith("pom.xml")) { return jarFile.getInputStream(entry); } } return null; } private Set transitivelyResolvePomDependencies(String groupId, String artifactId, String version) throws ProjectBuildingException, InvalidDependencyVersionException, ArtifactResolutionException, ArtifactNotFoundException { //get the pom as an Artifact Artifact pomArtifact = artifactFactory.createPluginArtifact(groupId, artifactId, VersionRange.createFromVersion(version)); //load the pom as a MavenProject MavenProject tempProject = mavenProjectBuilder.buildFromRepository(pomArtifact, remoteRepositories, localRepository); //get all of the dependencies for the project List dependencies = tempProject.getDependencies(); //make Artifacts of all the dependencies Set dependencyArtifacts = MavenMetadataSource.createArtifacts(artifactFactory, dependencies, null, null, null); //not forgetting the Artifact of the project itself dependencyArtifacts.add(tempProject.getArtifact()); //resolve all dependencies transitively to obtain a comprehensive list of jars ArtifactResolutionResult result = artifactResolver.resolveTransitively(dependencyArtifacts, pomArtifact, Collections.EMPTY_MAP, localRepository, remoteRepositories, metadataSource, null, Collections.EMPTY_LIST); return result.getArtifacts(); } private Model checkModel(Model model) throws ModelInterpolationException, ProjectBuildingException { if (model.getParent() != null) { Parent parent = model.getParent(); Artifact parentArt = artifactFactory.createArtifact(parent.getGroupId(), parent.getArtifactId(), parent.getVersion(), "compile", "pom"); MavenProject parentProj = mavenProjectBuilder.buildFromRepository(parentArt, remoteRepositories, localRepository); Model parentModel = parentProj.getModel(); if (parentModel.getParent() != null) { parentModel = checkModel(parentModel); } modelInheritanceAssembler.assembleModelInheritance(model, parentModel); } DefaultProjectBuilderConfiguration projectBuilderConfig = new DefaultProjectBuilderConfiguration(); projectBuilderConfig.setExecutionProperties(model.getProperties()); return modelInterpolator.interpolate(model, null, projectBuilderConfig, true); } private Logger getSLF4JLogger() { return new Logger() { public String getName() { return "ConfiguratorMojo"; } public void debug(String message, Throwable t) { getLog().debug(message, t); } public void debug(String message) { getLog().debug(message); } public void error(String message, Throwable t) { getLog().error(message, t); } public void error(String message) { getLog().error(message); } public void info(String message, Throwable t) { getLog().info(message, t); } public void info(String message) { getLog().info(message); } public boolean isDebugEnabled() { return getLog().isDebugEnabled(); } public boolean isErrorEnabled() { return getLog().isErrorEnabled(); } public boolean isInfoEnabled() { return getLog().isInfoEnabled(); } public boolean isTraceEnabled() { return getLog().isDebugEnabled(); } public boolean isWarnEnabled() { return getLog().isWarnEnabled(); } public void trace(String message, Throwable t) { getLog().debug(message, t); } public void trace(String message) { getLog().debug(message); } public void warn(String message, Throwable t) { getLog().warn(message, t); } public void warn(String message) { getLog().warn(message); } }; } }