/* * Copyright 2005 The Codehaus. * * 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.mojo.castor; import java.io.File; import java.io.FileWriter; import java.io.Writer; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.Iterator; import java.util.List; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DependencyResolutionRequiredException; 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.exolab.castor.tools.MappingTool; /** * A mojo that uses Castor MappingTool to generate mapping files from a Class. <a * href="http://castor.codehaus.org/javadoc/org/exolab/castor/tools/MappingTool.html"> MappingTool</a>. * * @author nicolas <nicolas@apache.org> */ public abstract class AbstractMappingMojo extends AbstractMojo { /** * The Maven project to act upon. * * @parameter expression="${project}" * @required */ private MavenProject project; /** * Whether to force generation of mapping file where one already exists. * * @parameter default-value="false" */ private boolean force; /** * The output directory. * * @parameter default-value="${project.build.outputDirectory}/" */ private File outputDirectory; /** * Private (project) class loader. */ private ClassLoader projectClassLoader; /** * {@inheritDoc} * * @see org.apache.maven.plugin.Mojo#execute() */ public void execute() throws MojoExecutionException, MojoFailureException { try { outputDirectory.mkdirs(); getLog().info( "Generate mapping " + getMappingName() + " for class " + getClassName() ); ClassLoader cl = getProjectClassLoader(); MappingTool tool = new MappingTool(); // As of Castor 1.2, an InternalContext needs to be set; using reflection // to set it or not Class<?> internalContextClass; try { internalContextClass = Class.forName( "org.castor.xml.InternalContext" ); Class<?> backwardsCompatibilityClass = Class.forName( "org.castor.xml.BackwardCompatibilityContext" ); Method setter = MappingTool.class.getMethod( "setInternalContext", new Class[] { internalContextClass } ); if ( setter != null ) { getLog().info( "About to invoke 'setInternalContext()' on org.exolab.castor.tools.MappingTool" ); setter.invoke( tool, new Object[] { backwardsCompatibilityClass.newInstance() } ); } } catch ( ClassNotFoundException e ) { // nothing to do as we check whether the class(es) exist or not } Class<?> clazz = cl.loadClass( getClassName() ); tool.addClass( clazz ); File file = new File( outputDirectory, getMappingName().trim() ); if ( file.exists() && ( !force ) ) { getLog().info( getMappingName() + " allready generated" ); return; } Writer writer = new FileWriter( file ); tool.write( writer ); } catch ( Exception e ) { throw new MojoExecutionException( "Failed to generate mapping for " + getClassName(), e ); } } /** * Returns the private project {@link ClassLoader}. * * @return A project-specific {@link ClassLoader}. * @throws DependencyResolutionRequiredException If a dependecy cannot be resolved. * @throws MalformedURLException If an URL is malformed. */ protected ClassLoader getProjectClassLoader() throws DependencyResolutionRequiredException, MalformedURLException { if ( projectClassLoader != null ) { return projectClassLoader; } List compile = project.getCompileClasspathElements(); URL[] urls = new URL[compile.size()]; int i = 0; for ( Iterator iterator = compile.iterator(); iterator.hasNext(); ) { Object object = (Object) iterator.next(); if ( object instanceof Artifact ) { urls[i] = ( (Artifact) object ).getFile().toURL(); } else { urls[i] = new File( (String) object ).toURL(); } i++; } projectClassLoader = new URLClassLoader( urls, getClass().getClassLoader().getSystemClassLoader() ); return projectClassLoader; } /** * Returns the class name. * * @return the classname */ protected abstract String getClassName(); /** * Returns the name of the mapping file. * * @return the mappingName */ protected abstract String getMappingName(); }