package org.codehaus.mojo.appfuse.mojo; /* * Copyright 2006 The Apache Software Foundation. * * 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 java.io.File; import java.util.List; import java.util.Properties; import org.apache.maven.plugin.MojoExecutionException; import org.codehaus.mojo.appfuse.utility.AntUtilities; import org.codehaus.mojo.appfuse.utility.AppfuseProperties; import org.codehaus.mojo.appfuse.utility.FileUtilities; import org.hibernate.cfg.Configuration; import org.hibernate.tool.hbm2x.POJOExporter; /** * This class will serve as a base class for all mojos that process java objects using freemarker and the hbm.xml file. * * @author <a href="mailto:scott@theryansplace.com">Scott Ryan</a> * @version $Id$ */ public abstract class PojoMojoBase extends MojoBase { /** * Creates a new PojoMojoBase object. */ protected PojoMojoBase() { super(); this.setMojoName( "PojoMojoBase" ); } /** * This method will run the database conversion to hbm file mojo task. * * @throws MojoExecutionException * Thrown if we fail to obtain an appfuse resource. */ public void execute() throws MojoExecutionException { if ( getLog().isInfoEnabled() ) { getLog().info( "Running the " + this.getMojoName() + " mojo with properties " + this ); } // Get a Hibernate Mapping Exporter POJOExporter exporter = new POJOExporter(); // Allow the class to set, update or delete property settings before they are handed into the exporter. We use // the passed back property set so that the original on remains intact. Properties updatedProperties = null; // Make sure we have a properties object. if ( this.getProcessingProperties() == null ) { updatedProperties = new Properties(); } else { updatedProperties = this.getProcessingProperties(); } // Allow the mojo to modify the properties validateProperties( updatedProperties ); // Set any custom properties that might have been passed in. exporter.setProperties( updatedProperties ); // call create to set up the configuration. Configuration configuration = new Configuration(); List files = this.getListOfFilesToProcess(); getLog().info( "Processing " + files.size() + " files based on pattern match " ); for ( int j = 0; j < files.size(); j++ ) { String fileName = ( String ) files.get( j ); if ( getLog().isDebugEnabled() ) { getLog().debug( "Adding file " + fileName + " to the processing list" ); } configuration.addFile( fileName ); } // set the configuratino into the exporter exporter.setConfiguration( configuration ); // Set the destination directory if ( ( this.getOutputDirectory() != null ) && ( getOutputDirectory().length() > 0 ) ) { exporter.setOutputDirectory( new File( getOutputDirectory() ) ); } else { throw new MojoExecutionException( "output directory cannot be null or empty" ); } // Set the file pattern model for the ouput files exporter.setFilePattern( getOutputPattern() ); // Set the template information. exporter.setTemplateName( getTemplateName() ); // run the exporter. exporter.start(); } /** * This method is called before properties are sent to the exporter for processing. This gives the class a chance to * review the properties that were passed in by the user and modify, delete or update them to match what is required * by the particular mojo. These properties are passed in to the generator and are accessable within the processing * templates. The new property list is handed back so the original one is still intact. * * @param inProperties * The project properties that already have been populated. * */ protected abstract void validateProperties( final Properties inProperties ); /** * Getter for property template name to be used in processing the mojo. An example might be appfusepojo/Pojo.ftl. By * implementing this getter the mojo can use a unique name to indentify their template in the configuration file * without intefereing with this generic method. * * @return The value of template name. */ protected abstract String getTemplateName(); /** * Getter for the file output pattern to be used when generating output files. An example might be like * com/appfuse/servicekit/manager/{class-name}Manager.java. By implementing this getter the mojo can use a unique * name to indentify their template in the configuration file without intefereing with this generic method. * * @return The value of output pattern. */ public abstract String getOutputPattern(); /** * This method will look in the mojo properties to see if the user passed in a new template name and if so pass that * back otherwise it passes the default back to the caller. * * @param inDefaultTemplateName * The name of the default template. * @param inTemplatePropertyKey * The key in the property map to look for a new template name possibly passed in by the user on the * maven properties. * @return The name of the template to use. */ public String locateTemplate( final String inDefaultTemplateName, final String inTemplatePropertyKey ) { // See if a template name was passed in otherwise use the default. String templateName = inDefaultTemplateName; // See if there is a model package extension in the properties if ( this.getProcessingProperties() != null && this.getProcessingProperties().containsKey( inTemplatePropertyKey ) ) { templateName = ( String ) this.getProcessingProperties().get( inTemplatePropertyKey ); } return templateName; } /** * This method will build up the output pattern for a generated artifact. It will locate the output pattern and * combine that with the package name to build up a location (dot notation) and then convert that location to a file * location and pass that back to the caller. * * @param inDefaultOutputPattern * The default output pattern for the artifact in question. * @param inOutputPatternPropertyKey * The property key to use to see if the user passed it in with the maven properties for the project. * @param inPackageName * The package name to prepend to the output pattern to construct the full location. * @return The file location of the output for this set of artifacts. */ public String buildOutputPattern( final String inDefaultOutputPattern, final String inOutputPatternPropertyKey, final String inPackageName ) { // See if an output pattern was passed in otherwise use the default. String outputPattern = inDefaultOutputPattern; // See if there is a model package extension in the properties if ( this.getProcessingProperties() != null && this.getProcessingProperties().containsKey( inOutputPatternPropertyKey ) ) { outputPattern = ( String ) this.getProcessingProperties().get( inOutputPatternPropertyKey ); } // We need to build up the entire file pattern from the package name and the file pattern String packageLocation = FileUtilities.convertPackageNameToFileLocation( inPackageName ); // Combine the package name and the file pattern String pattern = packageLocation + "/" + outputPattern; return pattern; } /** * This method will create a full package name for an artifact based on the base package name and an extension and * will return the full package name for the artifact. * * @param inDefaultPackageExtension * The default package extension to use for this artifact. * @param inPackageExtensionPropertyKey * The key in the maven properties file where a user can override the default value. * @return The full package name for the artifact. */ public String buildPackageName( final String inDefaultPackageExtension, final String inPackageExtensionPropertyKey ) { String packageExtension = inDefaultPackageExtension; // See if there is a dao package extension in the properties if ( this.getProcessingProperties() != null && this.getProcessingProperties().containsKey( inPackageExtensionPropertyKey ) ) { packageExtension = ( String ) this.getProcessingProperties().get( inPackageExtensionPropertyKey ); } return this.getBasePackageName() + "." + packageExtension; } /** * This class will locate the helper class to be used to provide additional support inside the template environment. * This clas has a default that can be overriden by the user but the class must always extend the appfuse base * class. * * @return The name of the template helper class. */ public String getTemplateHelperClassName() { // See if a class name was passed in otherwise use the default. String className = AppfuseProperties.DEFAULT_TEMPLATE_HELPER_CLASS; // See if there is a model package extension in the properties if ( this.getProcessingProperties() != null && this.getProcessingProperties().containsKey( AppfuseProperties.TEMPLATE_HELPER_CLASS_PROPERTY_KEY ) ) { className = ( String ) this.getProcessingProperties().get( AppfuseProperties.TEMPLATE_HELPER_CLASS_PROPERTY_KEY ); } return className; } /** * This method takes the ant based file pattern and adds the proper suffix onto it for the type of processing the * mojo needs to do. The default is to add hbm.xml to the end however if you need a different suffix or need to * manipulate the pattern in some way you can overload this method. * * @param inFilePattern * The initial file pattern requested for processing. * @return An augmented file pattern with the type hbm.xml added to it. */ public String augmentFilePattern( final String inFilePattern ) { return inFilePattern + ".hbm.xml"; } /** * This method will use the file pattern or a default file pattern appended with a suffix specific to the mojo to * locate all the files that need to be processed by the mojo. * * @return A list of fully qualified filename strings to be processed based on the file pattern and suffix. */ public List getListOfFilesToProcess() { // If no file pattern set then use the default String pattern = this.getFilePattern(); if ( ( pattern == null ) || ( pattern.length() == 0 ) ) { String defaultFilePattern = "**/*"; getLog().info( "The attribute filePattern for this mojo was not set so using default value of " + defaultFilePattern ); pattern = defaultFilePattern; } // Call the method to allow the mojo to add the proper suffix onto the pattern. pattern = augmentFilePattern( pattern ); getLog().info( "Using final file pattern of " + pattern + " to process the data" ); // get the list of files to process based on the list of patterns List files = AntUtilities.generateFileNameListFromPattern( this.getModelDirectory(), pattern ); return files; } /** * toString methode: creates a String representation of the object * * @return the String representation * */ public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append( super.toString() ); buffer.append( "PojoMojoBase[" ); buffer.append( "templateName = " ).append( this.getTemplateName() ); buffer.append( ", outputPattern = " ).append( this.getOutputPattern() ); buffer.append( "]" ); return buffer.toString(); } }