Sigh ... and now the attachments. :-)
Index: src/java/org/apache/velocity/texen/ant/TexenTask.java
===================================================================
--- src/java/org/apache/velocity/texen/ant/TexenTask.java (revision 345291)
+++ src/java/org/apache/velocity/texen/ant/TexenTask.java (working copy)
@@ -22,13 +22,19 @@
import java.io.InputStream;
import java.io.Writer;
import java.util.Date;
+import java.util.Enumeration;
import java.util.Iterator;
+import java.util.Properties;
import java.util.StringTokenizer;
+import java.util.Vector;
import org.apache.commons.collections.ExtendedProperties;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.Ant;
+import org.apache.tools.ant.taskdefs.Property;
+import org.apache.tools.ant.types.PropertySet;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
@@ -147,6 +153,9 @@
protected String useResourceLoaderCache = "false";
protected String resourceLoaderModificationCheckInterval = "2";
+ protected Vector properties = new Vector();
+ protected Vector propertySets = new Vector();
+
/**
* [REQUIRED] Set the control template for the
* generating process.
@@ -368,7 +377,27 @@
{
this.resourceLoaderModificationCheckInterval = resourceLoaderModificationCheckInterval;
}
+
/**
+ * Corresponds to <code><ant></code>'s
+ * nested <code><property></code> element.
+ *
+ * @param p the property to pass on explicitly to the sub-build.
+ */
+ public void addProperty(Property p) {
+ properties.addElement(p);
+ }
+
+ /**
+ * Corresponds to <code><ant></code>'s
+ * nested <code><propertyset></code> element.
+ * @param ps the propertset
+ */
+ public void addPropertyset(PropertySet ps) {
+ propertySets.addElement(ps);
+ }
+
+ /**
* Creates a VelocityContext.
*
* @return new Context
@@ -391,6 +420,53 @@
public void execute ()
throws BuildException
{
+ checkAttributes();
+ try
+ {
+ final VelocityEngine ve = initVelocityEngine();
+ final Generator generator = initGenerator(ve);
+ final String path = outputDirectory + File.separator + outputFile;
+ log("Generating to file " + path, Project.MSG_INFO);
+ final ExtendedProperties contextPropertiesCopy =
+ initContextPropertiesCopy();
+ // Feed all the options into the initial
+ // control context so they are available
+ // in the control/worker templates.
+ final Context c = initContext(contextPropertiesCopy);
+ final Writer writer = generator.getWriter(path, outputEncoding);
+ writer.write(generator.parse(controlTemplate, c));
+ writer.flush();
+ writer.close();
+ generator.shutdown();
+ cleanup();
+ }
+ catch( BuildException e)
+ {
+ throw e;
+ }
+ catch( MethodInvocationException e )
+ {
+ throw new BuildException(
+ "Exception thrown by '" + e.getReferenceName() + "." +
+ e.getMethodName() +"'" + ERR_MSG_FRAGMENT,
+ e.getWrappedThrowable());
+ }
+ catch( ParseErrorException e )
+ {
+ throw new BuildException("Velocity syntax error" + ERR_MSG_FRAGMENT ,e);
+ }
+ catch( ResourceNotFoundException e )
+ {
+ throw new BuildException("Resource not found" + ERR_MSG_FRAGMENT,e);
+ }
+ catch( Exception e )
+ {
+ throw new BuildException("Generation failed" + ERR_MSG_FRAGMENT ,e);
+ }
+ }
+
+ private void checkAttributes()
+ {
// Make sure the template path is set.
if (templatePath == null && useClasspath == false)
{
@@ -398,191 +474,182 @@
"The template path needs to be defined if you are not using " +
"the classpath for locating templates!");
}
-
// Make sure the control template is set.
if (controlTemplate == null)
{
throw new BuildException("The control template needs to be defined!");
}
-
// Make sure the output directory is set.
if (outputDirectory == null)
{
throw new BuildException("The output directory needs to be defined!");
}
-
// Make sure there is an output file.
if (outputFile == null)
{
throw new BuildException("The output file needs to be defined!");
}
+ }
- VelocityEngine ve = new VelocityEngine();
+ private VelocityEngine initVelocityEngine()
+ throws Exception
+ {
+ final VelocityEngine ve = new VelocityEngine();
+ // Setup the Velocity Runtime.
+ if (templatePath != null)
+ {
+ log("Using templatePath: " + templatePath, Project.MSG_VERBOSE);
+ ve.setProperty(
+ RuntimeConstants.FILE_RESOURCE_LOADER_PATH, templatePath);
+ }
+ if (useClasspath)
+ {
+ log("Using classpath");
+ ve.addProperty(
+ VelocityEngine.RESOURCE_LOADER, "classpath");
+ ve.setProperty(
+ "classpath." + VelocityEngine.RESOURCE_LOADER + ".class",
+ "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+ ve.setProperty(
+ "classpath." + VelocityEngine.RESOURCE_LOADER +
+ ".cache", useResourceLoaderCache);
+ ve.setProperty(
+ "classpath." + VelocityEngine.RESOURCE_LOADER +
+ ".modificationCheckInterval", resourceLoaderModificationCheckInterval);
+ }
+ if (this.logFile != null)
+ {
+ ve.setProperty(RuntimeConstants.RUNTIME_LOG, this.logFile);
+ }
+ ve.init();
+ return ve;
+ }
- try
+ private Generator initGenerator(final VelocityEngine ve)
+ {
+ // Create the text generator.
+ final Generator generator = Generator.getInstance();
+ generator.setVelocityEngine(ve);
+ generator.setOutputPath(outputDirectory);
+ generator.setInputEncoding(inputEncoding);
+ generator.setOutputEncoding(outputEncoding);
+ if (templatePath != null)
{
- // Setup the Velocity Runtime.
- if (templatePath != null)
- {
- log("Using templatePath: " + templatePath, Project.MSG_VERBOSE);
- ve.setProperty(
- RuntimeConstants.FILE_RESOURCE_LOADER_PATH, templatePath);
- }
+ generator.setTemplatePath(templatePath);
+ }
+ // Make sure the output directory exists, if it doesn't
+ // then create it.
+ final File file = new File(outputDirectory);
+ if (! file.exists())
+ {
+ file.mkdirs();
+ }
+ return generator;
+ }
- if (useClasspath)
+ private ExtendedProperties initContextPropertiesCopy()
+ {
+ final ExtendedProperties contextPropertiesCopy = new ExtendedProperties();
+ if (contextProperties != null)
+ {
+ contextPropertiesCopy.combine(contextProperties);
+ }
+ for (final Enumeration i = properties.elements(); i.hasMoreElements();)
+ {
+ final Property p = (Property) i.nextElement();
+ final String pName = p.getName().replace('.', '_');
+ contextPropertiesCopy.addProperty(pName, p.getValue());
+ }
+ for (final Enumeration i = propertySets.elements(); i.hasMoreElements();)
+ {
+ final PropertySet propertySet = (PropertySet) i.nextElement();
+ final Properties properties = propertySet.getProperties();
+ for (final Enumeration j = properties.propertyNames(); j.hasMoreElements();)
{
- log("Using classpath");
- ve.addProperty(
- VelocityEngine.RESOURCE_LOADER, "classpath");
-
- ve.setProperty(
- "classpath." + VelocityEngine.RESOURCE_LOADER + ".class",
- "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
-
- ve.setProperty(
- "classpath." + VelocityEngine.RESOURCE_LOADER +
- ".cache", useResourceLoaderCache);
-
- ve.setProperty(
- "classpath." + VelocityEngine.RESOURCE_LOADER +
- ".modificationCheckInterval", resourceLoaderModificationCheckInterval);
+ final String propertyName = (String) j.nextElement();
+ final String velocityPropertyName = propertyName.replace('.', '_');
+ final String propertyValue = properties.getProperty(propertyName);
+ contextPropertiesCopy.addProperty(velocityPropertyName, propertyValue);
}
+ }
+ return contextPropertiesCopy;
+ }
- if (this.logFile != null)
- {
- ve.setProperty(RuntimeConstants.RUNTIME_LOG, this.logFile);
- }
-
- ve.init();
+ private Context initContext(final ExtendedProperties contextPropertiesCopy)
+ throws Exception
+ {
+ // The generator and the output path should
+ // be placed in the init context here and
+ // not in the generator class itself.
+ final Context context = initControlContext();
+ // Everything in the generator class should be
+ // pulled out and placed in here. What the generator
+ // class does can probably be added to the Velocity
+ // class and the generator class can probably
+ // be removed all together.
+ populateInitialContext(context);
+ if (contextPropertiesCopy.size() != 0)
+ {
+ fillContext(contextPropertiesCopy, context);
+ }
+ return context;
+ }
- // Create the text generator.
- Generator generator = Generator.getInstance();
- generator.setVelocityEngine(ve);
- generator.setOutputPath(outputDirectory);
- generator.setInputEncoding(inputEncoding);
- generator.setOutputEncoding(outputEncoding);
-
- if (templatePath != null)
+ private void fillContext(
+ final ExtendedProperties contextPropertiesCopy, final Context c)
+ throws IOException
+ {
+ final Iterator i = contextPropertiesCopy.getKeys();
+ while (i.hasNext())
+ {
+ String property = (String) i.next();
+ String value = contextPropertiesCopy.getString(property);
+ // Now lets quickly check to see if what
+ // we have is numeric and try to put it
+ // into the context as an Integer.
+ try
{
- generator.setTemplatePath(templatePath);
+ c.put(property, new Integer(value));
}
-
- // Make sure the output directory exists, if it doesn't
- // then create it.
- File file = new File(outputDirectory);
- if (! file.exists())
+ catch (NumberFormatException nfe)
{
- file.mkdirs();
- }
-
- String path = outputDirectory + File.separator + outputFile;
- log("Generating to file " + path, Project.MSG_INFO);
- Writer writer = generator.getWriter(path, outputEncoding);
-
- // The generator and the output path should
- // be placed in the init context here and
- // not in the generator class itself.
- Context c = initControlContext();
-
- // Everything in the generator class should be
- // pulled out and placed in here. What the generator
- // class does can probably be added to the Velocity
- // class and the generator class can probably
- // be removed all together.
- populateInitialContext(c);
-
- // Feed all the options into the initial
- // control context so they are available
- // in the control/worker templates.
- if (contextProperties != null)
- {
- Iterator i = contextProperties.getKeys();
-
- while (i.hasNext())
+ // Now we will try to place the value into
+ // the context as a boolean value if it
+ // maps to a valid boolean value.
+ final String booleanString =
+ contextPropertiesCopy.testBoolean(value);
+ if (booleanString != null)
{
- String property = (String) i.next();
- String value = contextProperties.getString(property);
-
- // Now lets quickly check to see if what
- // we have is numeric and try to put it
- // into the context as an Integer.
- try
+ c.put(property, new Boolean(booleanString));
+ }
+ else
+ {
+ // We are going to do something special
+ // for properties that have a "file.contents"
+ // suffix: for these properties will pull
+ // in the contents of the file and make
+ // them available in the context. So for
+ // a line like the following in a properties file:
+ //
+ // license.file.contents = license.txt
+ //
+ // We will pull in the contents of license.txt
+ // and make it available in the context as
+ // $license. This should make texen a little
+ // more flexible.
+ if (property.endsWith("file.contents"))
{
- c.put(property, new Integer(value));
+ // We need to turn the license file from relative to
+ // absolute, and let Ant help :)
+ value = StringUtils.fileContentsToString(
+ project.resolveFile(value).getCanonicalPath());
+ property = property.substring(
+ 0, property.indexOf("file.contents") - 1);
}
- catch (NumberFormatException nfe)
- {
- // Now we will try to place the value into
- // the context as a boolean value if it
- // maps to a valid boolean value.
- String booleanString =
- contextProperties.testBoolean(value);
-
- if (booleanString != null)
- {
- c.put(property, new Boolean(booleanString));
- }
- else
- {
- // We are going to do something special
- // for properties that have a "file.contents"
- // suffix: for these properties will pull
- // in the contents of the file and make
- // them available in the context. So for
- // a line like the following in a properties file:
- //
- // license.file.contents = license.txt
- //
- // We will pull in the contents of license.txt
- // and make it available in the context as
- // $license. This should make texen a little
- // more flexible.
- if (property.endsWith("file.contents"))
- {
- // We need to turn the license file from relative to
- // absolute, and let Ant help :)
- value = StringUtils.fileContentsToString(
- project.resolveFile(value).getCanonicalPath());
-
- property = property.substring(
- 0, property.indexOf("file.contents") - 1);
- }
-
- c.put(property, value);
- }
- }
+ c.put(property, value);
}
}
-
- writer.write(generator.parse(controlTemplate, c));
- writer.flush();
- writer.close();
- generator.shutdown();
- cleanup();
}
- catch( BuildException e)
- {
- throw e;
- }
- catch( MethodInvocationException e )
- {
- throw new BuildException(
- "Exception thrown by '" + e.getReferenceName() + "." +
- e.getMethodName() +"'" + ERR_MSG_FRAGMENT,
- e.getWrappedThrowable());
- }
- catch( ParseErrorException e )
- {
- throw new BuildException("Velocity syntax error" + ERR_MSG_FRAGMENT ,e);
- }
- catch( ResourceNotFoundException e )
- {
- throw new BuildException("Resource not found" + ERR_MSG_FRAGMENT,e);
- }
- catch( Exception e )
- {
- throw new BuildException("Generation failed" + ERR_MSG_FRAGMENT ,e);
- }
}
/**
Index: xdocs/docs/texen.xml
===================================================================
--- xdocs/docs/texen.xml (revision 345313)
+++ xdocs/docs/texen.xml (working copy)
@@ -145,6 +145,10 @@
href="http://jakarta.apache.org/builds/jakarta-turbine/release/">here</a>.
</p>
+<p>
+ <strong>Attributes</strong>
+</p>
+
<table border="0">
<tr>
<th>Name</th>
@@ -226,6 +230,35 @@
</tr>
</table>
+<p>
+ <strong>Nested elements</strong>
+</p>
+
+ <table border="0">
+ <tr>
+ <th>Name</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>property</td>
+ <td>
+ Adds this property to the context.
+ <b>Please note that since ':' and '.' can't be used
+ in a Velocity variable name they are replaced by '_'.
+ So an Ant property name like 'ns:a.b.c' may be accessed
+ as '$ns_a_b_c' in a Velocity template.</b>
+ </td>
+ </tr>
+ <tr>
+ <td>propertyset</td>
+ <td>
+ The properties in this property set will be added to
+ the context. Any ':' and '.' characters in the property
+ names will be replaced by '_' characters.
+ </td>
+ </tr>
+ </table>
+
</section>
<section name="Predefined Context Objects" href="PredefinedContextObjects">
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]