/** * Copyright (C) 2009 Original Authors * * This file is part of Spring ME. * * Spring ME 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 2, or (at your option) any * later version. * * Spring ME 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 Spring ME; see the file COPYING. If not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. * * Linking this library statically or dynamically with other modules is * making a combined work based on this library. Thus, the terms and * conditions of the GNU General Public License cover the whole * combination. * * As a special exception, the copyright holders of this library give you * permission to link this library with independent modules to produce an * executable, regardless of the license terms of these independent * modules, and to copy and distribute the resulting executable under * terms of your choice, provided that you also meet, for each linked * independent module, the terms and conditions of the license of that * module. An independent module is a module which is not derived from or * based on this library. If you modify this library, you may extend this * exception to your version of the library, but you are not obligated to * do so. If you do not wish to do so, delete this exception statement * from your version. */ package me.springframework.di.maven; import com.thoughtworks.qdox.JavaDocBuilder; import me.springframework.di.Configuration; import me.springframework.di.spring.AutowiringAugmentation; import me.springframework.di.spring.QDoxAugmentation; import me.springframework.di.spring.SinkAugmentation; import me.springframework.di.spring.SpringConfigurationLoader; 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.filter.ArtifactFilter; 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.maven.project.artifact.InvalidDependencyVersionException; import org.apache.maven.project.artifact.MavenMetadataSource; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * A base class for all plugins processing a {@link Configuration} loaded from Spring. * * @author Wilfred Springer (wis) * */ public abstract class AbstractGeneratorMojo extends AbstractMojo { /** * The project in which the plugin is included. * * @parameter expression="${project}" * @required */ private MavenProject project; /** * Local Maven repository. * * @parameter expression="${localRepository}" */ private ArtifactRepository localRepository; /** * @component */ protected ArtifactFactory artifactFactory; /** * The factories to be generated. * * @parameter */ private List<Factory> factories = new ArrayList<Factory>(); /** * The name of the bean factory to be generated. * * @parameter */ private String className; /** * @parameter expression="{dotFile}" */ private File dotFile; /** * The XML file containing the definitions of your beans. * * @parameter */ private File contextFile; // JavaDoc inherited final public void execute() throws MojoExecutionException, MojoFailureException { for (BeanFactory factory : getBeanFactories()) { Configuration configuration = load(new FileSystemResource(factory.getContextFile())); process(configuration, factory); } } private List<BeanFactory> getBeanFactories() { List<BeanFactory> result = new ArrayList<BeanFactory>(); if (factories != null && factories.size() > 0) { // Treat the other configuration as defaults for (Factory factoryConfig : factories) { result.add(new ChainingBeanFactory(factoryConfig, new MojoBeanFactory())); } } else { result.add(new MojoBeanFactory()); } return result; } private Configuration load(Resource resource) throws MojoExecutionException { JavaDocBuilder builder = createJavaDocBuilder(); QDoxAugmentation augmentation = new QDoxAugmentation(builder); augmentation.setLoggingKitAdapter(new MavenLoggingKitAdapter(getLog())); AutowiringAugmentation autowire = new AutowiringAugmentation(builder); SinkAugmentation sink = new SinkAugmentation(); SpringConfigurationLoader loader = new SpringConfigurationLoader(augmentation, autowire, sink); return loader.load(resource); } /** * Processes the configuration passed in. * * @param config The configuration to be processed. */ public abstract void process(Configuration config, BeanFactory factory) throws MojoExecutionException, MojoFailureException; /** * Produces the {@link JavaDocBuilder} used to analyze classes and source files. * * @return The {@link JavaDocBuilder} used to analyze classes and source files. * @throws MojoExecutionException If we fail to produce the {@link JavaDocBuilder}. (Fail * early.) */ @SuppressWarnings("unchecked") private JavaDocBuilder createJavaDocBuilder() throws MojoExecutionException { JavaDocBuilder builder = new JavaDocBuilder(); builder.addSourceTree(new File(project.getBuild().getSourceDirectory())); // Quick and dirty hack for adding Classloaders with the definitions of // classes the sources depend upon. try { Set<Artifact> artifacts = MavenMetadataSource.createArtifacts(artifactFactory, project.getDependencies(), Artifact.SCOPE_RUNTIME, new ArtifactFilter() { public boolean include(Artifact artifact) { return true; } }, project); List<URL> urls = new ArrayList<URL>(); for (Artifact artifact : artifacts) { if (getLog().isDebugEnabled()) { getLog().debug("Adding artifact " + artifact.getId()); } if (Artifact.SCOPE_SYSTEM.equals(artifact.getScope())) { urls.add(artifact.getFile().toURL()); } else { urls.add(new File(localRepository.getBasedir(), localRepository.pathOf(artifact)).toURL()); } } URL[] template = new URL[0]; URLClassLoader loader = new URLClassLoader(urls.toArray(template)); builder.getClassLibrary().addClassLoader(loader); } catch (InvalidDependencyVersionException idve) { idve.printStackTrace(); } catch (MalformedURLException e) { throw new MojoExecutionException("Malformed artifact URLs."); } return builder; } /** * A project reference, providing a context for the MOJO execution. * * @return The project reference, providing a context for execution of the Mojo. */ protected MavenProject getProject() { return project; } private class MojoBeanFactory implements BeanFactory { public String getClassName() { return className; } public File getDotFile() { return dotFile; } public File getContextFile() { return contextFile; } } }