/*
* 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.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.exolab.castor.builder.SourceGenerator;
import org.exolab.castor.builder.binding.ExtendedBinding;
import org.exolab.castor.builder.factory.FieldInfoFactory;
import org.exolab.castor.builder.info.CollectionInfo;
/**
* Override Castor's SourceGenerator to inject exception handling. Code based on Castor XML code generator, release
* 1.1-M2
*/
class CastorSourceGenerator
extends SourceGenerator
{
/**
* {@link Log} instance to use for any logging.
*/
private Log log;
/**
* {@link FieldInfoFactory} instance to be used during code generation. We need to save this in order to override
* its properties later since SourceGenerator doesn't give us access to this and the properties are only read during
* the constructor call
*/
private FieldInfoFactory fieldInfoFactory;
/**
* Indicates whether logging should be verbose. As base class does not provide access to this variable, we intercept
* setting it and store its value here
*/
private boolean verbose;
/**
* Creates a default {@link CastorSourceGenerator} instance.
*/
public CastorSourceGenerator()
{
this( new FieldInfoFactory() );
}
/**
* Creates an instance of {@link CastorSourceGenerator}, configured with a field info factory.
*
* @param fieldInfoFactory {@link FieldInfoFactory} instance to be used during code generation.
*/
public CastorSourceGenerator( FieldInfoFactory fieldInfoFactory )
{
super( fieldInfoFactory );
this.fieldInfoFactory = fieldInfoFactory;
}
/**
* Creates an instance of {@link CastorSourceGenerator}, configured with a field info factory and a binding file.
*
* @param fieldInfoFactory {@link FieldInfoFactory} instance to be used during code generation.
* @param extendedBinding Binding file to be used during code generation.
*/
public CastorSourceGenerator( FieldInfoFactory fieldInfoFactory, ExtendedBinding extendedBinding )
{
super( fieldInfoFactory, extendedBinding );
this.fieldInfoFactory = fieldInfoFactory;
}
/**
* Factory method to create a {@link CastorSourceGenerator} instance, preset with default values.
*
* @param types A {@link FieldInfoFactory} type.
* @return a {@link CastorSourceGenerator} instance
* @throws MojoExecutionException To signal that an invalid type has been passed.
*/
public static CastorSourceGenerator createSourceGenerator( String types )
throws MojoExecutionException
{
// Create Source Generator with appropriate type factory
CastorSourceGenerator sgen;
if ( types != null )
{
try
{
String typ = "j2".equals( types ) ? "arraylist" : types;
FieldInfoFactory factory = new FieldInfoFactory( typ );
sgen = new CastorSourceGenerator( factory );
}
catch ( Exception e )
{
try
{
sgen = new CastorSourceGenerator( (FieldInfoFactory) Class.forName( types ).newInstance() );
}
catch ( Exception e2 )
{
throw new MojoExecutionException( "Invalid types \"" + types + "\": " + e.getMessage() );
}
}
}
else
{
sgen = new CastorSourceGenerator(); // default
}
return sgen;
}
/**
* Sets the {@link Log} instance to use for logging.
*
* @param log The {@link Log} instance to use for logging
*/
public void setLog( Log log )
{
this.log = log;
}
/**
* Returns the {@link Log} instance to use for logging.
*
* @return The {@link Log} instance to use for logging.
*/
public Log getLog()
{
return log;
}
/**
* Helper method to output log statements.
*
* @param msg The log message to be output.
*/
public void log( String msg )
{
getLog().info( msg );
}
/**
* Helper method to (conditionally) output a log statement.
*
* @param msg The log message to be output.
*/
public void verbose( String msg )
{
if ( verbose )
{
getLog().info( msg );
}
}
/**
* Sets a user-specified line separator stype on the {@link CastorSourceGenerator}.
*
* @param lineSeparator A user-specified line separator style.
* @throws MojoExecutionException If an invalid line separator stype has been specified.
*/
public void setLineSeparatorStyle( String lineSeparator )
throws MojoExecutionException
{
// Set Line Separator
String lineSep = System.getProperty( "line.separator" );
if ( lineSeparator != null )
{
if ( "win".equals( lineSeparator ) )
{
log( "Using Windows style line separation." );
lineSep = "\r\n";
}
else if ( "unix".equals( lineSeparator ) )
{
log( "Using UNIX style line separation." );
lineSep = "\n";
}
else if ( "mac".equals( lineSeparator ) )
{
log( "Using Macintosh style line separation." );
lineSep = "\r";
}
else
{
throw new MojoExecutionException( "Invalid value for lineseparator, must be win, unix, or mac." );
}
}
setLineSeparator( lineSep );
}
/**
* Indicates whether source generation should be 'verbose'.
*
* @param verbose True if source generation should be 'verbose'.
* @see org.exolab.castor.builder.SourceGenerator#setVerbose(boolean)
*/
public void setVerbose( final boolean verbose )
{
this.verbose = verbose;
super.setVerbose( verbose );
}
/**
* Sets a user-specific binding file to be used during code generation.
*
* @param bindingFile A user-specified binding file.
*/
public void setBindingFile( final File bindingFile )
{
setBinding( bindingFile.getAbsolutePath() );
}
/**
* Sets user-specific code generator properties for the code generation process.
*
* @param properties User-specific code generator properties.
* @throws MojoExecutionException Indicates that the user-specific properties cannot be accessed.
*/
public void setBuilderProperties( File properties )
throws MojoExecutionException
{
// Set Builder Properties;
if ( properties != null )
{
String filePath = properties.getAbsolutePath();
Properties customProperties = new Properties();
try
{
customProperties.load( new FileInputStream( filePath ) );
}
catch ( FileNotFoundException e )
{
throw new MojoExecutionException( "Properties file \"" + filePath + "\" not found" );
}
catch ( IOException e )
{
throw new MojoExecutionException( "Can't read properties file \"" + filePath + "\": " + e );
}
setDefaultProperties( customProperties );
// these properties are read at contstruction time and copied into FieldInfoFactory
// se we set them directly in the fieldInfoFactory here.
if ( generateExtraCollectionMethods() )
{
verbose( "Overriding default castorbuilder.properties and setting createExtraMethods to true" );
fieldInfoFactory.setCreateExtraMethods( true );
}
String suffix = getProperty( CollectionInfo.REFERENCE_SUFFIX_PROPERTY, null );
if ( suffix != null )
{
verbose( "Overriding default castorbuilder.properties and " + "setting referenceSuffixProperty to "
+ suffix );
}
fieldInfoFactory.setReferenceMethodSuffix( suffix );
if ( boundPropertiesEnabled() )
{
verbose( "Overriding default castorbuilder.properties and setting boundProperties to true" );
fieldInfoFactory.setBoundProperties( true );
}
}
}
}