package org.codehaus.mojo.hibernate3;
/*
* Copyright 2005 Johann Reyes.
*
* 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.
*/
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.codehaus.mojo.hibernate3.configuration.ComponentConfiguration;
import org.codehaus.mojo.hibernate3.exporter.Component;
import org.hibernate.tool.hbm2x.Exporter;
import java.util.List;
import java.util.Iterator;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Properties;
import java.net.URLClassLoader;
import java.net.URL;
import java.io.File;
/**
* Base class for the different hibernate3 goals based on the Ant tasks of hibernate tools.
*
* @author <a href="mailto:jreyes@hiberforum.org">Johann Reyes</a>
* @author <a href="mailto:tobrien@codehaus.org">Tim O'Brien</a>
* @version $Id$
* @requiresDependencyResolution test
*/
public abstract class HibernateExporterMojo
extends AbstractMojo
implements ExporterMojo
{
// ------------------------------ FIELDS ------------------------------
/**
* Parameter that holds components definitions specified by the user.
*
* @parameter
* @noinspection MismatchedQueryAndUpdateOfCollection
*/
private List components = new ArrayList();
/**
* Map holding the default component values for this goal.
*/
private Map defaultComponents = new HashMap();
/**
* Parameter that holds component properties defined by the user. More information can be found at the
* <a href="componentproperties.html">Component Properties Configuration</a> page.
*
* @parameter
* @noinspection MismatchedQueryAndUpdateOfCollection
*/
private Map componentProperties = new HashMap();
/**
* Spefic components configuration. More information can be found at the
* <a href="components.html">Components Configuration</a> page.
*
* @component role="org.codehaus.mojo.hibernate3.configuration.ComponentConfiguration"
* @noinspection MismatchedQueryAndUpdateOfCollection
*/
private List componentConfigurations = new ArrayList();
/**
* <i>Maven Internal</i>: Project to interact with.
*
* @parameter expression="${project}"
* @required
* @readonly
* @noinspection UnusedDeclaration
*/
private MavenProject project;
// --------------------- GETTER / SETTER METHODS ---------------------
/**
* @see ExporterMojo#getProject()
*/
public MavenProject getProject()
{
return project;
}
// ------------------------ INTERFACE METHODS ------------------------
// --------------------- Interface ExporterMojo ---------------------
/**
* @see ExporterMojo#getComponentProperty(String)
*/
public String getComponentProperty( String key )
{
return getComponentProperty( key, null );
}
/**
* @see ExporterMojo#getComponentProperty(String,boolean)
*/
public boolean getComponentProperty( String key, boolean defaultValue )
{
String s = getComponentProperty( key );
if ( s == null )
{
return defaultValue;
}
else
{
//noinspection UnnecessaryUnboxing
return Boolean.valueOf( s ).booleanValue();
}
}
// --------------------- Interface Mojo ---------------------
/**
* @see org.apache.maven.plugin.Mojo#execute()
*/
public void execute()
throws MojoExecutionException, MojoFailureException
{
Thread currentThread = Thread.currentThread();
ClassLoader oldClassLoader = currentThread.getContextClassLoader();
try
{
currentThread.setContextClassLoader( getClassLoader() );
if ( getComponentProperty( "skip", false ) )
{
getLog().info( "skipping hibernate3 execution" );
}
else
{
doExecute();
}
}
finally
{
currentThread.setContextClassLoader( oldClassLoader );
}
}
// -------------------------- OTHER METHODS --------------------------
/**
* Adds a default goal.
*
* @param outputDirectory Default output directory
* @param implementation Default configuration implementation
* @param jdk5 Is this goal being setup for jdk15?
* @noinspection unchecked
*/
protected void addDefaultComponent( String outputDirectory, String implementation, boolean jdk5 )
{
Component component = new Component();
component.setName( getName() );
component.setOutputDirectory( outputDirectory );
component.setImplementation( implementation );
defaultComponents.put( ( jdk5 ) ? "jdk15" : "jdk14", component );
}
/**
* Configures the Exporter.
*
* @param exporter Exporter to configure
* @return Exporter
* @throws MojoExecutionException if there is an error configuring the exporter
* @noinspection unchecked
*/
protected Exporter configureExporter( Exporter exporter )
throws MojoExecutionException
{
String implementation = getComponentProperty( "implementation", getComponent().getImplementation() );
ComponentConfiguration componentConfiguration = getComponentConfiguration( implementation );
getLog().info( "using " + componentConfiguration.getName() + " task." );
Properties properties = new Properties();
properties.putAll( componentProperties );
exporter.setProperties( properties );
exporter.setConfiguration( componentConfiguration.getConfiguration( this ) );
exporter.setOutputDirectory( new File( getProject().getBasedir(), getComponent().getOutputDirectory() ) );
File outputDir = new File( getProject().getBasedir(), getComponent().getOutputDirectory() );
if ( getComponent().isCompileSourceRoot() )
{
// add output directory to compile roots
getProject().addCompileSourceRoot( outputDir.getPath() );
}
// now let's set the template path for custom templates if the directory exists
// template path would need to be found inside the project directory
String templatePath = getComponentProperty( "templatepath", "/src/main/config/templates" );
File templatePathDir = new File( getProject().getBasedir(), templatePath );
if ( templatePathDir.exists() && templatePathDir.isDirectory() )
{
getLog().info( "Exporter will use templatepath : " + templatePathDir.getPath() );
exporter.setTemplatePath( new String[]{templatePathDir.getPath()} );
}
return exporter;
}
/**
* Returns the ComponentConfiguration for this maven goal.
*
* @param name Configuration task name
* @return ComponentConfiguration
* @throws MojoExecutionException if there is an error finding the ConfigurationTask
* @noinspection ForLoopReplaceableByForEach
*/
protected ComponentConfiguration getComponentConfiguration( String name )
throws MojoExecutionException
{
for ( Iterator it = componentConfigurations.iterator(); it.hasNext(); )
{
ComponentConfiguration componentConfiguration = (ComponentConfiguration) it.next();
if ( componentConfiguration.getName().equals( name ) )
{
return componentConfiguration;
}
}
throw new MojoExecutionException( "Could not get ConfigurationTask." );
}
/**
* @see ExporterMojo#getComponentProperty(String,String)
*/
public String getComponentProperty( String key, String defaultValue )
{
String value = (String) componentProperties.get( key );
if ( value == null || "".equals( value.trim() ) )
{
return defaultValue;
}
return value;
}
/**
* Gets the hibernate tool exporter based on the goal that is being called.
*
* @return Goal exporter
*/
protected abstract Exporter createExporter();
/**
* Executes the plugin in an isolated classloader.
*
* @throws MojoExecutionException When there is an erro executing the plugin
*/
protected void doExecute()
throws MojoExecutionException
{
configureExporter( createExporter() ).start();
}
/**
* Returns the an isolated classloader.
*
* @return ClassLoader
* @noinspection unchecked
*/
private ClassLoader getClassLoader()
{
try
{
List classpathElements = project.getCompileClasspathElements();
classpathElements.add( project.getBuild().getOutputDirectory() );
classpathElements.add( project.getBuild().getTestOutputDirectory() );
URL urls[] = new URL[classpathElements.size()];
for ( int i = 0; i < classpathElements.size(); ++i )
{
urls[i] = new File( (String) classpathElements.get( i ) ).toURL();
}
return new URLClassLoader( urls, this.getClass().getClassLoader() );
}
catch ( Exception e )
{
getLog().debug( "Couldn't get the classloader." );
return this.getClass().getClassLoader();
}
}
/**
* Returns the parsed goal to the exporter.
*
* @return Component
* @noinspection ForLoopReplaceableByForEach
*/
protected Component getComponent()
{
Component defaultGoal = (Component) defaultComponents.get( HibernateUtils.getJavaVersion() );
if ( !components.isEmpty() )
{
// add an alias to the report goal
String name = getName();
if ( "report".equals( name ) )
{
name = "hbm2doc";
}
// now iterate throught the goals
for ( Iterator it = components.iterator(); it.hasNext(); )
{
Component component = (Component) it.next();
if ( name.equals( component.getName() ) )
{
if ( component.getImplementation() == null )
{
component.setImplementation( defaultGoal.getImplementation() );
}
if ( component.getOutputDirectory() == null )
{
component.setOutputDirectory( defaultGoal.getOutputDirectory() );
}
return component;
}
}
}
return defaultGoal;
}
}