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>&lt;ant&gt;</code>'s
+     * nested <code>&lt;property&gt;</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>&lt;ant&gt;</code>'s
+     * nested <code>&lt;propertyset&gt;</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]

Reply via email to