//Source file: H:\\temp\\generated\\modTransf\\rules\\codeGenerator\\GenerateAction.java
package modTransf.rules.codeGenerator;
import java.io.Writer;
import java.io.Reader;
import modTransf.engine.RuleContext;
import modTransf.engine.TransformationException;
import java.io.*;
import org.apache.velocity.app.Velocity;
/**
* An action generating code from a specified template.
* The action specifies the template to use, and optionally the writer name.
* If the writer is specified, the action retrieves the writer from the context.
* If no writer is specifies, try to get the current writer from the context. The
* currrent writer is set by surrounding generate action in case of nested templates.
* Throw an error if no writer can be found.
* <p>Titre : ModTransf V3</p>
* <p>Description : </p>
* <p>Copyright : Copyright (c) 2005</p>
* <p>Soci�t� : </p>
* @author Cedric Dumoulin
* @version 3.0
*/
public class GenerateAction extends CodeGeneratorBase
{
/**
* The template to use.
*/
protected String template;
/**
* The inline template
*/
protected String inlineTemplate;
/**
* The name of the writer to use.
* The writer should be open and set in the context.
* If no writer is specified, use the current writer from the context.
*/
protected String writerName;
/**
* The writer descriptor, if any.
*/
protected WriterDescriptor writerDesc;
/**
* The name under which the current writer is stored.
*/
public static final String CURRENT_WRITER_ATTRIBUTE = GenerateAction.class.getName()+ ".currentWriter";
/**
* Constructor.
*/
public GenerateAction()
{
}
/**
* Constructor.
*/
public GenerateAction( String template)
{
initialize( template);
}
/**
* Constructor.
*/
public GenerateAction(String writerName, String template)
{
initialize(writerName, template);
}
/**
* Constructor.
*/
public GenerateAction(WriterDescriptor desc, String template)
{
initialize(desc, template);
}
/**
* @param desc
* @param templateFile
*/
public void initialize(WriterDescriptor desc, String templateFile)
{
this.writerDesc = desc;
this.template = templateFile;
}
/**
* @param writerName Name of the writer.
* @param templateFile
*/
public void initialize(String writerName, String templateFile)
{
this.writerName = writerName;
this.template = templateFile;
}
/**
* @param writerName Name of the writer.
* @param templateFile
*/
public void initialize(String templateFile)
{
this.template = templateFile;
}
/**
* @param desc
* @param inlineTemplate
*/
public void initializeInline(WriterDescriptor desc, String inlineTemplate)
{
this.writerDesc = desc;
this.inlineTemplate = inlineTemplate;
}
/**
* @param writerName
* @param inlineTemplate
*/
public void initializeInline(String writerName, String inlineTemplate)
{
this.writerName = writerName;
this.inlineTemplate = inlineTemplate;
}
/**
* @param writerName
* @param inlineTemplate
*/
public void initializeInline(String inlineTemplate)
{
this.inlineTemplate = inlineTemplate;
}
/**
* Access method for the template property.
*
* @return the current value of the template property
*/
public String getTemplate()
{
return template;
}
/**
* Sets the value of the template property.
*
* @param aTemplate the new value of the template property
*/
public void setTemplate(String aTemplate)
{
template = aTemplate;
}
/**
* Access method for the writerName property.
*
* @return the current value of the writerName property
*/
public String getWriterName()
{
return writerName;
}
public String getInlineTemplate()
{
return inlineTemplate;
}
/**
* Sets the value of the writerName property.
*
* @param aWriterName the new value of the writerName property
*/
public void setWriterName(String aWriterName)
{
writerName = aWriterName;
}
public void setInlineTemplateString(String inlineTemplate)
{
this.inlineTemplate = inlineTemplate;
}
/**
* Get the writer for generation.
* If a writerName is specified, get it from the context.
* If no writerName is specified, try to retrieve the current one.
* Throw an exception if no writer can be found.
* @return Writer
*/
public Writer getWriter(RuleContext context)
throws TransformationException
{
Writer writer;
if( writerName != null )
{
writer = (Writer)context.getAttribute(writerName);
if( writer == null )
throw new TransformationException("Can't find a writer under name '" + writerName + "'.");
}
else if(writerDesc !=null )
{
writer = writerDesc.create(context);
}
else
{
writer = getCurrentWriter(context);
if( writer == null )
throw new TransformationException("Can't find a writer. (no current and no writerName)");
}
return writer;
}
/**
* Get the default writer, if any.
* @param context
* @return Writer
*/
protected Writer getCurrentWriter(RuleContext context)
{
return (Writer)context.getAttribute( CURRENT_WRITER_ATTRIBUTE);
}
/**
* Set the default writer.
* @param writer
* @param context
*/
protected void setCurrentWriter(Writer writer, RuleContext context)
{
context.setAttribute( CURRENT_WRITER_ATTRIBUTE, writer );
}
/**
* Get the reader for the template.
* @return Reader
*/
protected Reader getTemplateReader(RuleContext context)
throws TransformationException
{
try
{
return getReaderWriterFactory(context).createReader(template);
}
catch(IOException ex)
{
throw new TransformationException(ex);
}
}
/**
* execute
*
* @param bean Object
* @param request RuleContext
* @return Object
*/
public Object execute(Object bean, RuleContext context)
throws TransformationException
{
// open writer
Writer writer = getWriter(context);
Writer oldWriter = null;
// generate code
try
{
Velocity.init();
//VelocityContext context = new VelocityContext(bean, request);
VelocityContext velContext = new VelocityTemplateDirectives(context);
// Push the current writer
oldWriter = getCurrentWriter(context);
if( oldWriter != writer )
setCurrentWriter( writer, context );
// Process the template
if(template!=null)
{
Velocity.mergeTemplate(template, "ISO-8859-1", velContext, writer);
}
else if(inlineTemplate!=null)
{
Velocity.evaluate(velContext, writer, "template", inlineTemplate);
} // end if
else
{
throw new TransformationException("Can't generate code: no template or inline template specified.");
}
}
catch(TransformationException ex)
{
throw ex;
}
catch(Exception ex)
{
throw new TransformationException(ex);
}
finally
{
// pop the oldWriter
if( oldWriter != null && oldWriter != writer )
setCurrentWriter(oldWriter, context);
}
// close writer if needed
closeWriter( writer );
return null;
}
/**
* Close the writer if it has been opened
*
* @param writer Writer
*/
protected void closeWriter(Writer writer)
throws TransformationException
{
if(writerDesc !=null )
{
try
{
writer.close();
}
catch(IOException ex)
{
throw new TransformationException(ex);
}
}
}
}