You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by Hiroaki Nakamura <hn...@v003.vaio.ne.jp> on 2003/01/21 00:19:54 UTC

[PATCH] Velocity task

Hi.
I made the Jakarta-Velocity task for Ant.
Please take a look and consider to accept it as a new optional task.

The <velocity> task is meant to be a richer version of filter function
of the <copy> task. I have been using the filter function for replacing
parameters in configuration files. But I need more functionality than
just replacing. I think this is where Velocity comes in. This template
engine has directives like #if and #foreach, so it is more powerful.

The <velocity> task has attributes and nested elements similar to the
<copy> task. I thought it would be easy to use. But not all of <copy>
attributes are supported. Please see the velocity.html in the patch.

Here is a example of calling a <velocity> task:

    <velocity todir="c" propertyfile="velocity.properties">
      <velocitycontext>
        <contextdata key="a" value="A1"/>
        <contextdata key="b" value="B1" if="SOME_PROP"/>
        <contextdata key="b" value="B2" unless="SOME_PROP"/>
        <contextdata key="str" classname="my.package.StringTool"/>
      </velocitycontext>
      <fileset dir="a">
        <include name="**/*.vm"/>
      </fileset>
      <mapper type="glob" from="*.vm" to="*.html"/>
    </velocity>

Opinions and suggestions are welcome.

--
)Hiroaki Nakamura) hnakamur@v003.vaio.ne.jp


Here is the patch for the <velocity> task:

diff -ruN jakarta-ant-1.5.1.orig/docs/manual/OptionalTasks/velocity.html jakarta-ant-1.5.1/docs/manual/OptionalTasks/velocity.html
--- jakarta-ant-1.5.1.orig/docs/manual/OptionalTasks/velocity.html 1970-01-01 09:00:00.000000000 +0900
+++ jakarta-ant-1.5.1/docs/manual/OptionalTasks/velocity.html 2003-01-21 07:39:03.000000000 +0900
@@ -0,0 +1,232 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<title>Velocity Task</title>
+</head>
+
+<body>
+
+<h2><a name="velocity">Velocity</a></h2>
+<h3>Description</h3>
+<p>Run <a href="http://jakarta.apache.org/velocity/index.html" target="_top">Jakarta-Velocity</a> on a file or FileSet to a new
file or directory.
+By default, files are only copied if the source file is newer than the
+destination file, or when the destination file does not exist.  However,
+you can explicitly overwrite files with the <code>overwrite</code> attribute.</p>
+<p><a href="../CoreTypes/fileset.html">FileSet</a>s are used to select a
+set of files to copy.
+To use a <code>&lt;fileset&gt;</code>, the <code>todir</code> attribute
+must be set.</p>
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <td valign="top"><b>Attribute</b></td>
+    <td valign="top"><b>Description</b></td>
+    <td align="center" valign="top"><b>Required</b></td>
+  </tr>
+  <tr>
+    <td valign="top">propertyfile</td>
+     <td valign="top">The property file which is used to initialize Velocity.
+     </td>
+     <td valign="top" align="center">Yes</td>
+  </tr>
+  <tr>
+    <td valign="top">file</td>
+    <td valign="top">The file to copy.</td>
+    <td valign="top" align="center">Yes, unless a nested
+    <code>&lt;fileset&gt;</code> element is used.</td>
+  </tr>
+  <tr>
+    <td valign="top">tofile</td>
+    <td valign="top">The file to copy to.</td>
+    <td valign="top" align="center" rowspan="2">With the <code>file</code>
+      attribute, either <code>tofile</code> or <code>todir</code> can be used.
+      With nested <code>&lt;fileset&gt;</code> elements, if the set of files
+      is greater than 1, or if only the <code>dir</code> attribute is
+      specified in the <code>&lt;fileset&gt;</code>, or if the
+      <code>file</code> attribute is also specified, then only
+      <code>todir</code> is allowed.</td>
+  </tr>
+  <tr>
+    <td valign="top">todir</td>
+    <td valign="top">The directory to copy to.</td>
+  </tr>
+  <tr>
+    <td valign="top">overwrite</td>
+    <td valign="top">Overwrite existing files even if the destination
+      files are newer.</td>
+    <td valign="top" align="center">No; defaults to false.</td>
+  </tr>
+  <tr>
+    <td valign="top">flatten</td>
+    <td valign="top">Ignore the directory structure of the source files,
+      and copy all files into the directory specified by the <code>todir</code>
+      attribute.  Note that you can achieve the same effect by using a
+      <a href="../CoreTypes/mapper.html#flatten-mapper">flatten mapper</a>.</td>
+    <td valign="top" align="center">No; defaults to false.</td>
+  </tr>
+  <tr>
+    <td valign="top">failonerror</td>
+     <td valign="top">Log a warning message, but do not stop the build,
+       when the file to copy does not exist.
+       Only meaningful when copying a single file.
+     </td>
+     <td valign="top" align="center">No; defaults to true.</td>
+  </tr>
+  <tr>
+    <td valign="top">templatebasedir</td>
+     <td valign="top">The template base directory. This is used to
+       caclutate a relative path of a template file. Velocity receives a
+       relative path and searches a template file in Velocity's search paths.
+     </td>
+     <td valign="top" align="center">No; defaults to project basedir.</td>
+  </tr>
+</table>
+<h3>Parameters specified as nested elements</h3>
+
+<h4>velocitycontext</h4>
+ <p>A &lt;velocitycontext&gt; is used to specify the VelocityContext data.
+ It has nested &lt;contextdata&gt; elements.</p>
+
+<h4>contextdata</h4>
+ <p>A &lt;contextdata&gt; is a nested element of &lt;velocitycontext&gt;
+ and is used to specify a VelocityContext datum.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+  <tr>
+    <td valign="top"><b>Attribute</b></td>
+    <td valign="top"><b>Description</b></td>
+    <td align="center" valign="top"><b>Required</b></td>
+  </tr>
+  <tr>
+    <td valign="top">key</td>
+     <td valign="top">The key of a VelocityContext datum.
+     </td>
+     <td valign="top" align="center">Yes</td>
+  </tr>
+  <tr>
+    <td valign="top">value</td>
+    <td valign="top">The value of a VelocityContext datum.</td>
+    <td valign="top" align="center" rowspan="2">One of either <var>value</var>
+    or <var>classname</var>.</td>
+  </tr>
+  <tr>
+    <td valign="top">classname</td>
+    <td valign="top">An instance of this classname is used as a VelocityContext
+    datum. The specified class must have the public non-argument constructor.
+    And if the class has a public method
+    <code>setContext(org.apache.velocity.context.Context)</code>,
+    it is invoked by reflection.
+    </td>
+  </tr>
+  <tr>
+    <td valign="top">if</td>
+    <td valign="top">Only use this data if the named property is set.</td>
+    <td align="center" valign="top">No</td>
+  </tr>
+  <tr>
+    <td valign="top">unless</td>
+    <td valign="top">Only use this data if the named property is
+       <b>not</b> set.</td>
+    <td align="center" valign="top">No</td>
+  </tr>
+</table>
+
+<h4>fileset</h4>
+ <p><a href="../CoreTypes/fileset.html">FileSet</a>s are used to select
+sets of files to run velocity on.
+ To use a fileset, the <code>todir</code> attribute must be set.</p>
+
+<h4>mapper</h4>
+ <p>You can define filename transformations by using a nested <a
+ href="../CoreTypes/mapper.html">mapper</a> element. The default mapper used by
+ <code>&lt;velocity&gt;</code> is the <a
+ href="../CoreTypes/mapper.html#identity-mapper">identity mapper</a>.</p>
+
+<h3>Examples</h3>
+<p><b>Run velocity on a single file</b></p>
+<pre>
+  &lt;velocity file=&quot;myfile.txt&quot; tofile=&quot;mycopy.txt&quot;
+      propertyfile=&quot;velocity.properties&quot;&gt;
+    &lt;velocitycontext&gt;
+      &lt;contextdata key=&quot;key1&quot; value=&quot;value1&quot;/&gt;
+      &lt;contextdata key=&quot;key2&quot; classname=&quot;some.Class1&quot;/&gt;
+      &lt;contextdata key=&quot;key3&quot; value=&quot;value3&quot; if=&quot;SOME_PROPERTY&quot;/&gt;
+      &lt;contextdata key=&quot;key4&quot; value=&quot;value4&quot; unless=&quot;SOME_PROPERTY&quot;/&gt;
+    &lt;/velocitycontext&gt;
+  &lt;/velocity&gt;
+</pre>
+<p><b>Run velocity on a single file to a directory</b></p>
+<pre>
+  &lt;velocity file=&quot;myfile.txt&quot; todir=&quot;../some/other/dir&quot;
+      propertyfile=&quot;velocity.properties&quot;&gt;
+    &lt;velocitycontext&gt;
+      &lt;contextdata key=&quot;key1&quot; value=&quot;value1&quot;/&gt;
+      &lt;contextdata key=&quot;key2&quot; classname=&quot;some.Class1&quot;/&gt;
+      &lt;contextdata key=&quot;key3&quot; value=&quot;value3&quot; if=&quot;SOME_PROPERTY&quot;/&gt;
+      &lt;contextdata key=&quot;key4&quot; value=&quot;value4&quot; unless=&quot;SOME_PROPERTY&quot;/&gt;
+    &lt;/velocitycontext&gt;
+  &lt;/velocity&gt;
+</pre>
+<p><b>Run velocity on a set of files to a directory</b></p>
+<pre>
+  &lt;velocity todir=&quot;../dest/dir&quot;
+      propertyfile=&quot;velocity.properties&quot;&gt;
+    &lt;velocitycontext&gt;
+      &lt;contextdata key=&quot;key1&quot; value=&quot;value1&quot;/&gt;
+      &lt;contextdata key=&quot;key2&quot; classname=&quot;some.Class1&quot;/&gt;
+      &lt;contextdata key=&quot;key3&quot; value=&quot;value3&quot; if=&quot;SOME_PROPERTY&quot;/&gt;
+      &lt;contextdata key=&quot;key4&quot; value=&quot;value4&quot; unless=&quot;SOME_PROPERTY&quot;/&gt;
+    &lt;/velocitycontext&gt;
+    &lt;fileset dir=&quot;src_dir&quot;&gt;
+      &lt;exclude name=&quot;**/*.java&quot;/&gt;
+    &lt;/fileset&gt;
+  &lt;/velocity&gt;
+
+  &lt;velocity todir=&quot;../dest/dir&quot;
+      propertyfile=&quot;velocity.properties&quot;&gt;
+    &lt;velocitycontext&gt;
+      &lt;contextdata key=&quot;key1&quot; value=&quot;value1&quot;/&gt;
+      &lt;contextdata key=&quot;key2&quot; classname=&quot;some.Class1&quot;/&gt;
+      &lt;contextdata key=&quot;key3&quot; value=&quot;value3&quot; if=&quot;SOME_PROPERTY&quot;/&gt;
+      &lt;contextdata key=&quot;key4&quot; value=&quot;value4&quot; unless=&quot;SOME_PROPERTY&quot;/&gt;
+    &lt;/velocitycontext&gt;
+    &lt;fileset dir=&quot;src_dir&quot; excludes=&quot;**/*.java&quot;/&gt;
+  &lt;/velocity&gt;
+</pre>
+<p><b>Run velocity on a set of files to a directory, appending
+<code>.bak</code> to the file name on the fly</b></p>
+<pre>
+  &lt;velocity todir=&quot;../backup/dir&quot;
+      propertyfile=&quot;velocity.properties&quot;&gt;
+    &lt;velocitycontext&gt;
+      &lt;contextdata key=&quot;key1&quot; value=&quot;value1&quot;/&gt;
+      &lt;contextdata key=&quot;key2&quot; classname=&quot;some.Class1&quot;/&gt;
+      &lt;contextdata key=&quot;key3&quot; value=&quot;value3&quot; if=&quot;SOME_PROPERTY&quot;/&gt;
+      &lt;contextdata key=&quot;key4&quot; value=&quot;value4&quot; unless=&quot;SOME_PROPERTY&quot;/&gt;
+    &lt;/velocitycontext&gt;
+    &lt;fileset dir=&quot;src_dir&quot;/&gt;
+    &lt;mapper type=&quot;glob&quot; from=&quot;*&quot; to=&quot;*.bak&quot;/&gt;
+  &lt;/velocity&gt;
+</pre>
+
+<p><strong>Unix Note:</strong> Destination file permissions are not the same as
+the template files; they end up with the default <code>UMASK</code> permissions
+instead. This
+is caused by the lack of any means to query or set file permissions in the
+current Java runtimes.
+</p>
+
+<p><strong>Windows Note:</strong> If you a destination file already exists,
+but with different casing, the destination file takes on the case of the
+original. The workaround is to
+<a href="delete.html">delete</a>
+the file in the destination directory before you run velocity.
+</p>
+
+<hr><p align="center">Copyright &copy; 2003 Apache Software Foundation.
+All rights Reserved.</p>
+
+</body>
+</html>
+
diff -ruN jakarta-ant-1.5.1.orig/docs/manual/install.html jakarta-ant-1.5.1/docs/manual/install.html
--- jakarta-ant-1.5.1.orig/docs/manual/install.html 2002-10-02 11:10:18.000000000 +0900
+++ jakarta-ant-1.5.1/docs/manual/install.html 2003-01-21 07:37:06.000000000 +0900
@@ -381,6 +381,12 @@
     <td><a href="http://www.clarkware.com/software/JDepend.html"
         target="_top">http://www.clarkware.com/software/JDepend.html</a></td>
   </tr>
+  <tr>
+    <td>Velocity JAR(s)</td>
+    <td>velocity task</td>
+    <td><a href="http://jakarta.apache.org/velocity/index.html"
+        target="_top">http://jakarta.apache.org/velocity/index.html</a></td>
+  </tr>
 </table>
 <br>
 <hr>
diff -ruN jakarta-ant-1.5.1.orig/docs/manual/optionaltasklist.html jakarta-ant-1.5.1/docs/manual/optionaltasklist.html
--- jakarta-ant-1.5.1.orig/docs/manual/optionaltasklist.html 2002-10-02 11:10:06.000000000 +0900
+++ jakarta-ant-1.5.1/docs/manual/optionaltasklist.html 2003-01-20 09:40:43.000000000 +0900
@@ -62,6 +62,7 @@
 <a href="OptionalTasks/test.html">Test</a><br>
 <a href="OptionalTasks/translate.html">Translate</a><br>
 <a href="Integration/VAJAntTool.html#tasks">Visual Age for Java Tasks</a><br>
+<a href="OptionalTasks/velocity.html">Velocity</a><br>
 <a href="OptionalTasks/vss.html#tasks">Microsoft Visual SourceSafe Tasks</a><br>
 <a href="OptionalTasks/wljspc.html">Weblogic JSP Compiler</a><br>
 <a href="OptionalTasks/xmlvalidate.html">XmlValidate</a><br>
diff -ruN jakarta-ant-1.5.1.orig/src/main/org/apache/tools/ant/taskdefs/defaults.properties
jakarta-ant-1.5.1/src/main/org/apache/tools/ant/taskdefs/defaults.properties
--- jakarta-ant-1.5.1.orig/src/main/org/apache/tools/ant/taskdefs/defaults.properties 2002-10-02 11:08:34.000000000 +0900
+++ jakarta-ant-1.5.1/src/main/org/apache/tools/ant/taskdefs/defaults.properties 2003-01-21 07:29:56.000000000 +0900
@@ -169,6 +169,7 @@
 jarlib-available=org.apache.tools.ant.taskdefs.optional.extension.JarLibAvailableTask
 jarlib-resolve=org.apache.tools.ant.taskdefs.optional.extension.JarLibResolveTask
 setproxy=org.apache.tools.ant.taskdefs.optional.net.SetProxy
+velocity=org.apache.tools.ant.taskdefs.optional.VelocityTask

 # deprecated ant tasks (kept for back compatibility)
 starteam=org.apache.tools.ant.taskdefs.optional.scm.AntStarTeamCheckOut
diff -ruN jakarta-ant-1.5.1.orig/src/main/org/apache/tools/ant/taskdefs/optional/VelocityTask.java
jakarta-ant-1.5.1/src/main/org/apache/tools/ant/taskdefs/optional/VelocityTask.java
--- jakarta-ant-1.5.1.orig/src/main/org/apache/tools/ant/taskdefs/optional/VelocityTask.java 1970-01-01 09:00:00.000000000 +0900
+++ jakarta-ant-1.5.1/src/main/org/apache/tools/ant/taskdefs/optional/VelocityTask.java 2003-01-20 10:48:52.000000000 +0900
@@ -0,0 +1,478 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Ant", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.tools.ant.taskdefs.optional;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Mapper;
+import org.apache.tools.ant.types.optional.velocity.VelocityContext;
+import org.apache.tools.ant.util.FileNameMapper;
+import org.apache.tools.ant.util.FileUtils;
+import org.apache.tools.ant.util.FlatFileNameMapper;
+import org.apache.tools.ant.util.IdentityMapper;
+import org.apache.velocity.app.Velocity;
+import org.apache.velocity.context.Context;
+
+
+/**
+ * Run velocity on a file or a fileset to a new file
+ * or directory.  Velocity is only run for a file which is newer
+ * than the destination file, or when the destination file does not
+ * exist.  It is possible to explicitly overwrite existing files.</p>
+ *
+ * <p>This task is supposed to be a richer version of filter function
+ * of copy task, and has similar attributes and nested elements.</p>
+ *
+ * @author <a href="mailto:hnakamur@v003.vaio.ne.jp">Hiroaki Nakamura</a>
+ *
+ * @version $Revision$
+ */
+public class VelocityTask extends Task {
+    protected File templateBaseDir = null;
+    protected File file = null; // the template file
+    protected File destFile = null; // the destination file
+    protected File destDir = null;  // the destination directory
+    protected String encoding = System.getProperty("file.encoding"); // template and output file encoding
+    protected File propertyFile = null; // the destination file
+    protected VelocityContext velocityContext; // the <velocitycontext> nested element
+    protected Vector filesets = new Vector();
+
+    protected boolean forceOverwrite = false;
+    private boolean failonerror = true;
+
+    protected boolean flatten = false;
+    protected Mapper mapperElement = null;
+
+    private FileUtils fileUtils;
+
+    /**
+     * Velocity task constructor.
+     */
+    public VelocityTask() {
+        fileUtils = FileUtils.newFileUtils();
+    }
+
+    protected FileUtils getFileUtils() {
+        return fileUtils;
+    }
+
+    /**
+     * Sets template files base directory.
+     */
+    public void setTemplateBaseDir(File dir) {
+        this.templateBaseDir = dir;
+    }
+
+    /**
+     * @return templatebasedir attribute value or project basedir if templatebasedir is not set.
+     */
+    protected File getTemplateBaseDir() {
+        return templateBaseDir == null
+                ? project.getBaseDir() : templateBaseDir;
+    }
+
+    /**
+     * Sets a single source file to copy.
+     */
+    public void setFile(File file) {
+        this.file = file;
+    }
+
+    /**
+     * Sets the destination file.
+     */
+    public void setTofile(File destFile) {
+        this.destFile = destFile;
+    }
+
+    /**
+     * Sets the destination directory.
+     */
+    public void setTodir(File destDir) {
+        this.destDir = destDir;
+    }
+
+    /**
+     * Sets the Velocity propertyfile.
+     */
+    public void setPropertyFile(File propertyFile) {
+        this.propertyFile = propertyFile;
+    }
+
+    /**
+     * Sets the encoding.
+     */
+    public void setEncoding(String encoding) {
+        this.encoding = encoding;
+    }
+
+    /**
+     * Create a nested velocitycontext element.
+    */
+    public VelocityContext createVelocityContext() throws BuildException {
+        if (velocityContext != null) {
+            throw new BuildException("Cannot define more than one velocitycontext",
+                                     location);
+        }
+        velocityContext = new VelocityContext();
+        return velocityContext;
+    }
+
+    /**
+     * Adds a set of files to copy.
+     */
+    public void addFileset(FileSet set) {
+        filesets.addElement(set);
+    }
+
+    /**
+     * Overwrite any existing destination file(s).
+     */
+    public void setOverwrite(boolean overwrite) {
+        this.forceOverwrite = overwrite;
+    }
+
+    /**
+     * If false, note errors to the output but keep going.
+     * @param failonerror true or false
+     */
+     public void setFailOnError(boolean failonerror) {
+         this.failonerror = failonerror;
+     }
+
+    /**
+     * When copying directory trees, the files can be "flattened"
+     * into a single directory.  If there are multiple files with
+     * the same name in the source directory tree, only the first
+     * file will be copied into the "flattened" directory, unless
+     * the forceoverwrite attribute is true.
+     */
+    public void setFlatten(boolean flatten) {
+        this.flatten = flatten;
+    }
+
+    /**
+     * Defines the mapper to map source to destination files.
+     */
+    public Mapper createMapper() throws BuildException {
+        if (mapperElement != null) {
+            throw new BuildException("Cannot define more than one mapper",
+                                     location);
+        }
+        mapperElement = new Mapper(project);
+        return mapperElement;
+    }
+
+    /**
+     * Performs the velocity template merge operation.
+     */
+    public void execute() throws BuildException {
+        File savedFile = file; // may be altered in validateAttributes
+        File savedDestFile = destFile;
+        File savedDestDir = destDir;
+        FileSet savedFileSet = null;
+        if (file == null && destFile != null && filesets.size() == 1) {
+            // will be removed in validateAttributes
+            savedFileSet = (FileSet) filesets.elementAt(0);
+        }
+
+        validateAttributes();
+
+        try {
+            initVelocity();
+            Context ctx = createContext();
+            File tmplBaseDir = getTemplateBaseDir();
+
+            if (file != null) {
+                if (!file.exists()) {
+                    String message = "Warning: Could not find template file "
+                        + file.getAbsolutePath() + ".";
+                    if (!failonerror) {
+                        log(message);
+                    } else {
+                        throw new BuildException(message);
+                    }
+                }
+
+                if (destFile == null) {
+                    destFile = new File(destDir, file.getName());
+                }
+
+                mergeTemplateUnlessUpToDate(
+                    tmplBaseDir,
+                    file,
+                    ctx,
+                    destFile);
+            }
+
+            if (filesets != null) {
+                FileNameMapper mapper = getFileNameMapper();
+                for (Enumeration en = filesets.elements(); en.hasMoreElements();) {
+                    FileSet fs = (FileSet) en.nextElement();
+                    DirectoryScanner ds = fs.getDirectoryScanner(project);
+                    File dsBaseDir = ds.getBasedir();
+                    String[] files = ds.getIncludedFiles();
+                    for (int i = 0; i < files.length; i++) {
+                        String srcRelativePath = files[i];
+                        File srcFile = new File(dsBaseDir, srcRelativePath);
+                        String[] destRelativePaths = mapper.mapFileName(srcRelativePath);
+                        for (int j = 0; j < destRelativePaths.length; j++) {
+                            String destRelativePath = destRelativePaths[j];
+                            File curDestFile = new File(destDir, destRelativePath);
+                            mergeTemplateUnlessUpToDate(
+                                tmplBaseDir,
+                                srcFile,
+                                ctx,
+                                curDestFile);
+                        }
+                    }
+                }
+            }
+        } finally {
+            // clean up again, so this instance can be used a second
+            // time
+            file = savedFile;
+            destFile = savedDestFile;
+            destDir = savedDestDir;
+            if (savedFileSet != null && filesets.size() == 0) {
+                filesets.insertElementAt(savedFileSet, 0);
+            }
+        }
+    }
+
+//************************************************************************
+//  protected and private methods
+//************************************************************************
+
+    /**
+     * Ensure we have a consistent and legal set of attributes, and set
+     * any internal flags necessary based on different combinations
+     * of attributes.
+     */
+    protected void validateAttributes() throws BuildException {
+        if (file == null && filesets.size() == 0) {
+            throw new BuildException("Specify at least one source "
+                                     + "- a file or a fileset.");
+        }
+
+        if (destFile != null && destDir != null) {
+            throw new BuildException("Only one of tofile and todir "
+                                     + "may be set.");
+        }
+
+        if (destFile == null && destDir == null) {
+            throw new BuildException("One of tofile or todir must be set.");
+        }
+
+        if (file != null && file.exists() && file.isDirectory()) {
+            throw new BuildException("Use a fileset to copy directories.");
+        }
+
+        if (destFile != null && filesets.size() > 0) {
+            if (filesets.size() > 1) {
+                throw new BuildException(
+                    "Cannot concatenate multiple files into a single file.");
+            } else {
+                FileSet fs = (FileSet) filesets.elementAt(0);
+                DirectoryScanner ds = fs.getDirectoryScanner(project);
+                String[] srcFiles = ds.getIncludedFiles();
+
+                if (srcFiles.length == 0) {
+                    throw new BuildException(
+                        "Cannot perform operation from directory to file.");
+                } else if (srcFiles.length == 1) {
+                    if (file == null) {
+                        file = new File(ds.getBasedir(), srcFiles[0]);
+                        filesets.removeElementAt(0);
+                    } else {
+                        throw new BuildException("Cannot concatenate multiple "
+                                                 + "files into a single file.");
+                    }
+                } else {
+                    throw new BuildException("Cannot concatenate multiple "
+                                             + "files into a single file.");
+                }
+            }
+        }
+
+        if (destFile != null) {
+            destDir = fileUtils.getParentFile(destFile);
+        }
+
+    }
+
+    /**
+     * @return FileNameMapper instance
+     */
+    protected FileNameMapper getFileNameMapper() {
+        FileNameMapper mapper = null;
+        if (mapperElement != null) {
+            mapper = mapperElement.getImplementation();
+        } else if (flatten) {
+            mapper = new FlatFileNameMapper();
+        } else {
+            mapper = new IdentityMapper();
+        }
+        return mapper;
+    }
+
+    /**
+     * Initializes Velocity.
+     */
+    protected void initVelocity() throws BuildException {
+        if (propertyFile == null) {
+            throw new BuildException("propertyfile must be set");
+        }
+        try {
+            Velocity.init(propertyFile.getPath());
+        } catch (Exception ex) {
+            throw new BuildException(ex);
+        }
+    }
+
+    /**
+     * Merge Velocity template file to the corresponding destination file
+     * if the destination file is older than the template file or does not exist.
+     */
+    protected void mergeTemplateUnlessUpToDate(
+        File templateBaseDir,
+        File templateFile,
+        Context ctx,
+        File destFile)
+        throws BuildException {
+
+        if (forceOverwrite ||
+            (templateFile.lastModified() > destFile.lastModified())) {
+            String templatePath = getRelativePath(templateFile, templateBaseDir);
+            mergeTemplate(templatePath, ctx, destFile);
+        } else {
+            log(templateFile + " omitted as " + destFile
+                + " is up to date.", Project.MSG_VERBOSE);
+        }
+    }
+
+    /**
+     * Merge Velocity template file to the corresponding destination file.
+     */
+    protected void mergeTemplate(
+        String templateRelativePath,
+        Context ctx,
+        File destFile)
+        throws BuildException {
+        try {
+            File destDir = fileUtils.getParentFile(destFile);
+            if (!destDir.exists()) {
+                destDir.mkdirs();
+            }
+
+            OutputStreamWriter osw = null;
+            FileOutputStream fos = new FileOutputStream(destFile);
+            try {
+                osw = new OutputStreamWriter(fos, encoding);
+                try {
+                    Velocity.mergeTemplate(
+                        templateRelativePath,
+                        encoding,
+                        ctx,
+                        osw);
+                } finally {
+                    osw.close();
+                    fos = null;
+                }
+            } finally {
+                if (fos != null) {
+                    fos.close();
+                }
+            }
+        } catch (Exception ex) {
+            throw new BuildException(ex);
+        }
+    }
+
+    /**
+     * @return relative path of file from baseDir
+     */
+    protected String getRelativePath(File file, File baseDir) {
+        int trimLen = baseDir.getAbsolutePath().length();
+        if (!isRootDirectory(baseDir)) {
+            trimLen++;
+        }
+        return file.getAbsolutePath().substring(trimLen);
+    }
+
+    /**
+     * @return whether dir is root directory or not.
+     */
+    protected boolean isRootDirectory(File dir) {
+        return dir.getParent() == null;
+    }
+
+    /**
+     * @return Velocity context created.
+     */
+    protected Context createContext()
+        throws BuildException {
+        return velocityContext.createRealContext();
+    }
+}
diff -ruN jakarta-ant-1.5.1.orig/src/main/org/apache/tools/ant/types/optional/velocity/VelocityContext.java
jakarta-ant-1.5.1/src/main/org/apache/tools/ant/types/optional/velocity/VelocityContext.java
--- jakarta-ant-1.5.1.orig/src/main/org/apache/tools/ant/types/optional/velocity/VelocityContext.java 1970-01-01 09:00:00.000000000
+0900
+++ jakarta-ant-1.5.1/src/main/org/apache/tools/ant/types/optional/velocity/VelocityContext.java 2003-01-20 11:00:10.000000000 +0900
@@ -0,0 +1,258 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Ant", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.tools.ant.types.optional.velocity;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.DataType;
+import org.apache.velocity.context.Context;
+
+/**
+ * A VelocityContext is a nested element of Velocity task.
+ * It has nested <code>&ltcontextdata&gt;</code> elements.
+ *
+ * @author <a href="mailto:hnakamur@v003.vaio.ne.jp">Hiroaki Nakamura</a>
+ *
+ * @version $Revision$
+ */
+public class VelocityContext extends DataType {
+    private Vector contextData = new Vector();
+
+    /**
+     * Creates the nested <code>&ltcontextdata&gt;</code> element.
+     */
+    public ContextData createContextData() throws BuildException {
+        ContextData cd = new ContextData();
+        contextData.addElement(cd);
+        return cd;
+    }
+
+    /**
+     * @return real org.apache.velocity.VelocityContext specified by
+     * <code>&ltvelocitycontext&gt;</code> element.
+     */
+    public Context createRealContext()
+        throws BuildException {
+        Context context = new org.apache.velocity.VelocityContext();
+        populateContext(context);
+        return context;
+    }
+
+    /**
+     * Populates org.apache.velocity.VelocityContext with data specified by
+     * nested <code>&ltcontextdata&gt;</code> elements.
+     */
+    protected void populateContext(Context context)
+        throws BuildException {
+        for (Enumeration en = contextData.elements(); en.hasMoreElements();) {
+            Object o = en.nextElement();
+            ContextData cd = (ContextData) o;
+            cd.addIfValid(context);
+        }
+    }
+
+    /**
+     * ContextData represents a nested <code>&ltcontextdata&gt;</code> element.
+     * The attribute <code>key</code> is necessary. One of attribute <code>value</code>
+     * or <code>className</code> is necessary. The attribute <code>value</code>
+     * is used to create immediate Context data. The attribute <code>className</code>
+     * is used to create a "tool" object which is later used from template files.
+     * The attribute <code>if</code> and <code>unless</code> are optional, which
+     * are used to control of enabling or disabling of a <code>&ltcontextdata&gt;</code>
+     * element.
+     */
+    public class ContextData {
+        protected String key;
+        protected String value;
+        protected String ifCond;
+        protected String className;
+        protected String unlessCond;
+
+        /**
+         * Sets the key.
+         * @param name The key to set
+         */
+        public void setKey(String key) {
+            this.key = key;
+        }
+
+        /**
+         * Sets the value.
+         * @param value The value to set
+         */
+        public void setValue(String value) {
+            this.value = value;
+        }
+
+        /**
+         * Sets the className.
+         * @param className The className to set
+         */
+        public void setClassName(String className) {
+            this.className = className;
+        }
+
+        /**
+         * Sets the ifCond.
+         * @param ifCond The ifCond to set
+         */
+        public void setIf(String ifCond) {
+            this.ifCond = ifCond;
+        }
+
+        /**
+         * Sets the unlessCond.
+         * @param unlessCond The unlessCond to set
+         */
+        public void setUnless(String unlessCond) {
+            this.unlessCond = unlessCond;
+        }
+
+        /**
+         * @return whether this element is valid or not
+         */
+        public boolean isValid() {
+            Project p = getProject();
+            if (ifCond != null && p.getProperty(ifCond) == null) {
+                return false;
+            } else if (unlessCond != null && p.getProperty(unlessCond) != null) {
+                return false;
+            }
+            return true;
+        }
+
+        /**
+         * Add to a context if this element is valid.
+         */
+        public void addIfValid(Context context)
+            throws BuildException {
+            if (!isValid()) {
+                return;
+            }
+
+            if (key == null) {
+                throw new BuildException("name must be set");
+            }
+
+            if (value != null && className != null) {
+                throw new BuildException("value and className cannot both be set");
+            } else if (value == null && className == null) {
+                throw new BuildException("value or className must be set");
+            }
+
+            if (value != null) {
+                context.put(key, value);
+            } else if (className != null) {
+                Object instance = createInstance(className);
+                invokeSetContext(instance, context);
+                context.put(key, instance);
+            }
+        }
+
+        /**
+         * @return an instance of the specified class.
+         */
+        protected Object createInstance(String className)
+            throws BuildException {
+            try {
+                return Class.forName(className).newInstance();
+            } catch (ClassNotFoundException ex) {
+                throw new BuildException(ex);
+            } catch (IllegalAccessException ex) {
+                throw new BuildException(ex);
+            } catch (InstantiationException ex) {
+                throw new BuildException(ex);
+            }
+        }
+
+        protected void invokeSetContext(Object instance, Context context)
+            throws BuildException {
+            try {
+                Class[] paramTypes = { Context.class };
+                Method method = instance.getClass().getMethod("setContext", paramTypes);
+                Object[] args = { context };
+                method.invoke(instance, args);
+            } catch (NoSuchMethodException ex) {
+                // ignore
+            } catch (IllegalAccessException ex) {
+                throw new BuildException(ex);
+            } catch (InvocationTargetException ex) {
+                throw new BuildException(ex);
+            }
+        }
+
+        /**
+         * @return a string representation of an instance.
+         */
+        public String toString() {
+            return "ContextVar[name="
+                + key
+                + ", value="
+                + value
+                + ", className="
+                + className
+                + ", if="
+                + ifCond
+                + ", unless="
+                + unlessCond
+                + "]";
+        }
+    }
+}



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
Just for the record, I'm +0 on adding this to Ant.  Not +1 because I'm 
too busy to do this commit the justice it deserves :)

	Erik

On Monday, January 20, 2003, at 06:34  PM, Conor MacNeill wrote:
> Hiroaki Nakamura wrote:
>>
>> Opinions and suggestions are welcome.
>
>
> I like the idea - I'll try and review and commit tonight. Could you 
> open
> a Bugzilla issue to track this and attach everything as a zip.
>
> Conor
>
>
>
> --
> To unsubscribe, e-mail:   
> <ma...@jakarta.apache.org>
> For additional commands, e-mail: 
> <ma...@jakarta.apache.org>
>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Conor MacNeill <co...@cortexebusiness.com.au>.
Hiroaki Nakamura wrote:
> 
> Opinions and suggestions are welcome.


I like the idea - I'll try and review and commit tonight. Could you open
a Bugzilla issue to track this and attach everything as a zip.

Conor



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Stefan Bodewig <bo...@apache.org>.
On Tue, 21 Jan 2003, Hiroaki Nakamura <hn...@v003.vaio.ne.jp>
wrote:

> But I wish this task to be committed and released. I have been
> watching Velocity-dev ML for a while, but there is still no release
> after velocity-1.3.1-rc2 (July 25, 2002),

Even if we'd accept your submission (quite likely, it seems 8-), it
would go into Ant 1.6 which isn't expected to get released too soon
either (middle of the year, maybe).  This is just to make sure you
don't expect too much.

I haven't looked at the code, but from your description "filterchain"
came to my mind immediately.

Stefan

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
On Monday, January 20, 2003, at 09:24  PM, Hiroaki Nakamura wrote:
> I got the latest sources from CVS and tried build.xml in proposal/xdocs
> directory. Also I saw @ant tags in other tasks.
>
> After all, I added
>  * @ant.task name="velocity" category="other"
> to VelocityTask.java, and
>  * @ant.datatype name="velocitycontext"
> to VelocityContext.java.
>
> That's all, it it?

Yes, thats all.  In fact, you don't even really need these (although 
the category is nice) if your task is named VelocityTask and its 
mapping is to "velocity".  The XDoclet code has some smarts that strip 
off the trailing "Task" automatically.

	Erik


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Hiroaki Nakamura <hn...@v003.vaio.ne.jp>.
Erik Hatcher wrote:
> Since Conor has picked this up, lets let him decide where he wants to 
> go with it first.  I'm happy to have it within Ant's codebase, 
> personally.

Me too.

> Look at other Ant tasks in the Ant codebase and see the @tags on 
> several of them.  Eventually I'll document these tags more thoroughly 
> than just referring to the source code, but that will give you an idea 
> of whats going on.  The goal is to have the XML generated be sufficient 
> enough to generate Ant's task/datatype documentation eventually.

I got the latest sources from CVS and tried build.xml in proposal/xdocs
directory. Also I saw @ant tags in other tasks.

After all, I added
 * @ant.task name="velocity" category="other"
to VelocityTask.java, and
 * @ant.datatype name="velocitycontext"
to VelocityContext.java.

That's all, it it?

And when I compiled the velocity task with the latest Ant sources,
I noticed that my codes call deprecated methods.
I will fix them and post the patch to Bugzilla.

--
)Hiroaki Nakamura) hnakamur@v003.vaio.ne.jp



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Hiroaki Nakamura <hn...@v003.vaio.ne.jp>.
Hi,
Sorry I was wrong about the explicitly listed context data feature.
It *is* supported in VPP. Please see FAQ
"Q. What other kinds of properties can be put into the velocity context?"

So things like below are not needed:

Hiroaki Nakamura wrote:
> Thank you for your summarization. I think all my needs are fulfilled by
> your implementation. As for the explicitly listed context data feature,
> it can be easily done in separate velocity template files like:
> #set($a = $ant.get("a"))
> #set($b = $ant.get("b"))

--
)Hiroaki Nakamura) hnakamur@v003.vaio.ne.jp


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Hiroaki Nakamura <hn...@v003.vaio.ne.jp>.
Hi,
Thank you for changing the license of VPP to BSD. Now I can
download and look into VPP. Yesterday I couldn't, because I was
developing Apache-style licensed program. To tell the truth,
if I found VPP before, I did not create my velocity task in the first place.

Thank you for requesting VPP to be listed in Ant related projects.
When it is done, nobody is going to waste time like me.

Thank you for your summarization. I think all my needs are fulfilled by
your implementation. As for the explicitly listed context data feature,
it can be easily done in separate velocity template files like:
#set($a = $ant.get("a"))
#set($b = $ant.get("b"))

So I am totally happy with VPP. Now I have no reason for pushing
my velocity task included in future Ant distributions, so I think I
should cancel my bugzilla entry. Is it OK?

--
)Hiroaki Nakamura) hnakamur@v003.vaio.ne.jp



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: [PATCH] Velocity task

Posted by didge <di...@foundrylogic.com>.
VPP was originally developed to be a javac preprocessor, but on suggestion
by Bill Burton, I broke out the preprocessor as a filter for general purpose
use.  In addition, the latest release is now BSD licensed, includes a FAQ
and a few more examples.  See http://vpp.sourceforge.net.

Both Hiroaki's <velocity> task and VPP have a good amount of overlap.
Following is my summarization of the differences between them.  This is not
a critique, but simply to help those trying to understand the differences
between the two tools.:
- The core fuctionality of <velocity> is implemented as a task with a subset
of the <copy> task's functionality.
- The core functionality of VPP is implemented as a FilterChain and can be
used by any task that supports filter chains.
- <vpp> extends the org.apache.tools.ant.taskdefs.Copy.  Therefore, <vpp>
provides a superset of the <copy> functionality, not a subset.
- Both tools support passing properties and instances to the
VelocityContext.
- <velocity> populates the context with only those properties that are
explicitly listed and satisfying an optional condition.
- VPP populates the context with the current project instance automatically,
giving access to all project properties implicitly.
- <velocity> uses a single instance of Velocity for all tasks.
- VPP initializes a new VelocityEngine for each individual task to allow
each task to have a custom configuration.
- <velocity> initializes the Velocity runtime from a property file.
- VPP initializes each VelocityEngine using properties defined by the task.

> From: Hiroaki Nakamura [mailto:hnakamur@v003.vaio.ne.jp]
> Do you plan to submit your work to included in Ant project? If yes,
> it might be better to merge both features and implementations.

I have offered VPP to the Ant Project in the past and I am happy to make all
or part of it available now.  But I also agree with the sentiment that Ant
is growing very large.  To that end, I am going to request in a separate
email that VPP be listed as an Ant Related Project.

I'd also be happy to work with you on merging our ideas together to create
an even more flexible and easy to use tool.

didge


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Hiroaki Nakamura <hn...@v003.vaio.ne.jp>.
didge,

Thanks for info. I didn't know VPP project. Now I have read the document
at http://vpp.sourceforge.net, but not sources.

didge wrote:
> You may also be interested in VPP (http://vpp.sourceforge.net).  It provides
> the following:
> 
> - VPPFilter, a FilterReader supporting VTL.
> - VPP, an extenson of the Copy task integrating VPPFilter.
> - VPPJavaC, an extension of the Javac task also integrating VPPFilter for
> preprocessing .java files before compilation using VTL.

I like your idea on implementing template processing as a filter.
I wonder I should change my VelocityTask implementation,
but currently I am a very beginner about ant filterchains.
What do you think? > all.

> 
> In addition to being able to use VTL, you also have access to all of your
> Ant project properties via the key $ant.  For example, you can get your
> project's name with $ant.get("ant.project.name") in your templates.

To provide similar functions, I think it maybe useful if the Project and the
current Task instance are automatically put into the velocity context with
key like "project" and "task" respetively. You can get a project property 
with $project.getProperty(propertyName). Well, but I don't think of cases
I actually use these values at the moment.

> 
> In addition to the Anakia ant task, Velocity also supports Texen, a simple
> ant task that launches Velocity using a 'control template'.

Again, thanks for info. I didn't notice the texen task. But after looking at
TexenTask.java, I think this is too simple to fill my needs.
Texen task can only deal with one template file. I want a fileset.
And texen task populate a velocity context by values in property files.

My plan is to put most of context data in separate velocity template file
such as "config_a.vm" and "config_b.vm", which are selectively included
in the main template "main.vm" like below:
    #include("$configfile")

And you can select which file to include in a velocity task like:
    <velocity todir="c" propertyfile="velocity.properties">
      <velocitycontext>
        <contextdata key="configfile" value="config_a.vm" if="SOME_PROP"/>
        <contextdata key="configfile" value="config_b.vm" unless="SOME_PROP"/>
      </velocitycontext>
      <fileset dir="a">
        <include name="**/*.vm"/>
      </fileset>
      <mapper type="glob" from="*.vm" to="*.html"/>
    </velocity>

Or if you set the ant property "configfile", you can write:
    <velocity todir="c" propertyfile="velocity.properties">
      <velocitycontext>
        <contextdata key="configfile" value="$configfile"/>
      </velocitycontext>
      <fileset dir="a">
        <include name="**/*.vm"/>
      </fileset>
      <mapper type="glob" from="*.vm" to="*.html"/>
    </velocity>

It is more configurable to set context data in velocity template files than in
plain old property files, because you can use all velocity features.

Also you can put an instance of the class name specified like:
        <contextdata key="str" classname="my.package.StringTool"/>
The class must have public non-argument constructor. If the class has
public setContext(org.apache.velocity.context.Context) method, it is
invoked by reflection.

With these features, I think you can setup context data almost arbitarily.

> 
> The current release of vpp is licensed under LGPL, but I will be moving the
> next release to a BSD license soon.

Do you plan to submit your work to included in Ant project? If yes,
it might be better to merge both features and implementations.

--
)Hiroaki Nakamura) hnakamur@v003.vaio.ne.jp



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: [PATCH] Velocity task

Posted by didge <di...@foundrylogic.com>.
You may also be interested in VPP (http://vpp.sourceforge.net).  It provides
the following:

- VPPFilter, a FilterReader supporting VTL.
- VPP, an extenson of the Copy task integrating VPPFilter.
- VPPJavaC, an extension of the Javac task also integrating VPPFilter for
preprocessing .java files before compilation using VTL.

In addition to being able to use VTL, you also have access to all of your
Ant project properties via the key $ant.  For example, you can get your
project's name with $ant.get("ant.project.name") in your templates.

In addition to the Anakia ant task, Velocity also supports Texen, a simple
ant task that launches Velocity using a 'control template'.

The current release of vpp is licensed under LGPL, but I will be moving the
next release to a BSD license soon.

didge


> -----Original Message-----
> From: Erik Hatcher [mailto:jakarta-ant@ehatchersolutions.com]
> Sent: Monday, January 20, 2003 4:42 PM
> To: Ant Developers List
> Subject: Re: [PATCH] Velocity task
>
>
> On Monday, January 20, 2003, at 07:28  PM, Hiroaki Nakamura wrote:
> > No, the Velocity does not have Ant tasks.
>
> Just the Anakia ones, I guess.  I'm kinda surprised there isn't more
> Ant integration with Velocity.  I'm actually in the midst of doing a
> static blog site generation Ant task using Velocity (the generator will
> be pluggable, but Velocity is the primary templating engine I'm using
> now).
>
> > Well, I am not sure on this. I think it's OK that the velocity task is
> > distributed in either Ant or Velocity. But I wish this task to be
> > committed and released. I have been watching Velocity-dev ML
> > for a while, but there is still no release after velocity-1.3.1-rc2
> > (July 25, 2002), and proposed features seems to be neglected
> > after short discussions...
>
> *sigh* - While I can appreciate the effort it takes to do a final
> release of a Jakarta project (deep bow to Magesh!) I find that the
> Velocity/Turbine projects suffer more than other Jakarta projects and
> live in perpetual beta/RC state.  Such a shame.
>
> > I just added this patch to Bugzilla, Ant's area.
> > Should I post this patch to Velocity-dev ML also? Opinions please >
> > all.
>
> Since Conor has picked this up, lets let him decide where he wants to
> go with it first.  I'm happy to have it within Ant's codebase,
> personally.
>
> > As for XDoclet tags, I will look into it from now. Would you give me
> > a pointer of documentations I should read?
>
> First, just for fun, run the build in proposal/xdocs (be sure to have
> the latest from CVS).  If you encounter problems, let me know.  Then
> look at what it generates in the build directory.  If your task is part
> of the binary of Ant you are running and in the Ant source tree on your
> local machine then you should see your task documentation generated.
> Check it for accuracy.
>
> Look at other Ant tasks in the Ant codebase and see the @tags on
> several of them.  Eventually I'll document these tags more thoroughly
> than just referring to the source code, but that will give you an idea
> of whats going on.  The goal is to have the XML generated be sufficient
> enough to generate Ant's task/datatype documentation eventually.
>
> 	Erik
>
>
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
On Monday, January 20, 2003, at 07:28  PM, Hiroaki Nakamura wrote:
> No, the Velocity does not have Ant tasks.

Just the Anakia ones, I guess.  I'm kinda surprised there isn't more 
Ant integration with Velocity.  I'm actually in the midst of doing a 
static blog site generation Ant task using Velocity (the generator will 
be pluggable, but Velocity is the primary templating engine I'm using 
now).

> Well, I am not sure on this. I think it's OK that the velocity task is
> distributed in either Ant or Velocity. But I wish this task to be
> committed and released. I have been watching Velocity-dev ML
> for a while, but there is still no release after velocity-1.3.1-rc2
> (July 25, 2002), and proposed features seems to be neglected
> after short discussions...

*sigh* - While I can appreciate the effort it takes to do a final 
release of a Jakarta project (deep bow to Magesh!) I find that the 
Velocity/Turbine projects suffer more than other Jakarta projects and 
live in perpetual beta/RC state.  Such a shame.

> I just added this patch to Bugzilla, Ant's area.
> Should I post this patch to Velocity-dev ML also? Opinions please > 
> all.

Since Conor has picked this up, lets let him decide where he wants to 
go with it first.  I'm happy to have it within Ant's codebase, 
personally.

> As for XDoclet tags, I will look into it from now. Would you give me
> a pointer of documentations I should read?

First, just for fun, run the build in proposal/xdocs (be sure to have 
the latest from CVS).  If you encounter problems, let me know.  Then 
look at what it generates in the build directory.  If your task is part 
of the binary of Ant you are running and in the Ant source tree on your 
local machine then you should see your task documentation generated.  
Check it for accuracy.

Look at other Ant tasks in the Ant codebase and see the @tags on 
several of them.  Eventually I'll document these tags more thoroughly 
than just referring to the source code, but that will give you an idea 
of whats going on.  The goal is to have the XML generated be sufficient 
enough to generate Ant's task/datatype documentation eventually.

	Erik


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Hiroaki Nakamura <hn...@v003.vaio.ne.jp>.
Erik,

Thanks for your comments. Yes, it took me a whole weekend, but I think
it's worth :-)

Erik Hatcher wrote:
> Wow, you've put a lot of work into this.  I'm actually doing more and 
> more with Velocity myself, so this is intriguing.  But doesn't the 
> Velocity project have its own Ant task(s)?

No, the Velocity does not have Ant tasks.

> 
> While it would be cool to have this within Ant's own codebase and 
> distribution, I think the general consensus is that this really should 
> be housed with the Velocity project itself, with perhaps a standalone 
> JAR distributed as part of the main Velocity distribution.

Well, I am not sure on this. I think it's OK that the velocity task is
distributed in either Ant or Velocity. But I wish this task to be
committed and released. I have been watching Velocity-dev ML
for a while, but there is still no release after velocity-1.3.1-rc2
(July 25, 2002), and proposed features seems to be neglected
after short discussions...

> 
> I'm very impressed with the attention to detail you've give to your 
> contribution.  At the very least add this to Bugzilla, either Ant's or 
> Velocity's area, with all the details as patch and source attachments 
> so that this is not lost.

I just added this patch to Bugzilla, Ant's area.
Should I post this patch to Velocity-dev ML also? Opinions please > all.

As for XDoclet tags, I will look into it from now. Would you give me
a pointer of documentations I should read?

--
)Hiroaki Nakamura) hnakamur@v003.vaio.ne.jp



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
Hiroaki,

Wow, you've put a lot of work into this.  I'm actually doing more and 
more with Velocity myself, so this is intriguing.  But doesn't the 
Velocity project have its own Ant task(s)?

While it would be cool to have this within Ant's own codebase and 
distribution, I think the general consensus is that this really should 
be housed with the Velocity project itself, with perhaps a standalone 
JAR distributed as part of the main Velocity distribution.

I'm very impressed with the attention to detail you've give to your 
contribution.  At the very least add this to Bugzilla, either Ant's or 
Velocity's area, with all the details as patch and source attachments 
so that this is not lost.

	Erik



On Monday, January 20, 2003, at 06:19  PM, Hiroaki Nakamura wrote:
> Hi.
> I made the Jakarta-Velocity task for Ant.
> Please take a look and consider to accept it as a new optional task.
>
> The <velocity> task is meant to be a richer version of filter function
> of the <copy> task. I have been using the filter function for replacing
> parameters in configuration files. But I need more functionality than
> just replacing. I think this is where Velocity comes in. This template
> engine has directives like #if and #foreach, so it is more powerful.
>
> The <velocity> task has attributes and nested elements similar to the
> <copy> task. I thought it would be easy to use. But not all of <copy>
> attributes are supported. Please see the velocity.html in the patch.
>
> Here is a example of calling a <velocity> task:
>
>     <velocity todir="c" propertyfile="velocity.properties">
>       <velocitycontext>
>         <contextdata key="a" value="A1"/>
>         <contextdata key="b" value="B1" if="SOME_PROP"/>
>         <contextdata key="b" value="B2" unless="SOME_PROP"/>
>         <contextdata key="str" classname="my.package.StringTool"/>
>       </velocitycontext>
>       <fileset dir="a">
>         <include name="**/*.vm"/>
>       </fileset>
>       <mapper type="glob" from="*.vm" to="*.html"/>
>     </velocity>
>
> Opinions and suggestions are welcome.


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: xdocs Gump

Posted by Stefan Bodewig <bo...@apache.org>.
On Mon, 3 Feb 2003, Erik Hatcher <ja...@ehatchersolutions.com>
wrote:

> So, is there any special logging configuration in place?

Not that I was aware of.

This is the snippet that I would use to run the build next night:

export CLASSPATH=$JAVA_HOME/lib/tools.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/jakarta-ant/dist/lib/ant.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/jakarta-ant/dist/lib/nodeps.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/jakarta-ant/dist/lib/ant-junit.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/jakarta-ant/dist/lib/ant-stylebook.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/jakarta-ant/dist/lib/ant-swing.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/jakarta-ant/dist/lib/ant-trax.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/jakarta-ant/dist/lib/ant-xalan2.jar
export CLASSPATH=/home/bodewig/dev/gump/xml-xerces2/java/build/xercesImpl.jar:$CLASSPATH
export CLASSPATH=/home/bodewig/dev/gump/xml-xerces2/java/build/xmlParserAPIs.jar:$CLASSPATH
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-apache-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-bea-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-borland-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-caucho-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-ejb-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-exolab-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-hibernate-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-hp-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-ibm-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-java-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-jboss-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-jdo-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-jmx-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-libelis-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-macromedia-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-mvcsoft-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-mx4j-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-objectweb-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-orion-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-pramati-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-solarmetric-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-sybase-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-tjdo-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-web-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-webwork-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xdoclet/target/lib/xdoclet-xdoclet-module-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/jakarta-commons/logging/dist/commons-logging.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/jakarta-commons/logging/dist/commons-logging-api.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/jakarta-log4j/log4j-20030203.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/jakarta-commons/collections/dist/commons-collections.jar
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/jakarta-bcel/bin/bcel.jar
export CLASSPATH=/home/bodewig/dev/gump/xml-commons/java/external/build/xml-apis.jar:$CLASSPATH
export CLASSPATH=$CLASSPATH:/home/bodewig/dev/gump/xjavadoc/build/lib/xdoclet-xjavadoc-uc-20030203.jar
cd /home/bodewig/dev/gump/jakarta-ant/proposal/xdocs $OUT 2>&1
/usr/local/bin/timeout 1200 java -Xbootclasspath/p:/home/bodewig/dev/gump/xml-xerces2/java/build/xercesImpl.jar:/home/bodewig/dev/gump/xml-xerces2/java/build/xmlParserAPIs.jar:/home/bodewig/dev/gump/xml-commons/java/external/build/xml-apis.jar -Xmx256m org.apache.tools.ant.Main -Dbuild.sysclasspath=only -Dant.home=/home/bodewig/dev/gump/jakarta-ant/dist $TARGET </dev/null $OUT 2>&1

Stefan

Re: xdocs Gump

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
On Monday, February 3, 2003, at 09:41  AM, Stefan Bodewig wrote:
> On Mon, 3 Feb 2003, Erik Hatcher <ja...@ehatchersolutions.com>
> wrote:
>
>> XDoclet uses Commons Logging exclusively, so if log4j is there then
>> its using that, or JDK 1.4 logging (but Gump isn't running JDK 1.4,
>> I don't think).
>
> Gump *is* running JDK 1.4.

Ah, cool.

So, is there any special logging configuration in place?  Or just using 
the default?  It seems a lot of DEBUG level output is coming out in the 
Gump runs.

I'm still running JDK 1.3.1 (until Apple releases JDK 1.4 in final 
form).

	Erik


Re: xdocs Gump

Posted by Stefan Bodewig <bo...@apache.org>.
On Mon, 3 Feb 2003, Erik Hatcher <ja...@ehatchersolutions.com>
wrote:

> XDoclet uses Commons Logging exclusively, so if log4j is there then
> its using that, or JDK 1.4 logging (but Gump isn't running JDK 1.4,
> I don't think).

Gump *is* running JDK 1.4.

Stefan

Re: xdocs Gump

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
On Monday, February 3, 2003, at 09:16  AM, Stefan Bodewig wrote:
> I still find it hard to move to all the information and filter out
> relevant parts.  Is there any way to make the output less noisy?
>

Its not noisy for me at the command-line, so it has to do with the 
logging JAR's that are available to the Gump run, I presume.  XDoclet 
uses Commons Logging exclusively, so if log4j is there then its using 
that, or JDK 1.4 logging (but Gump isn't running JDK 1.4, I don't 
think).  Is there a log4j.properties file that is perhaps being made 
available to it somehow?

I'll dig into this more after the next Gump run.

Thanks again, Stefan.

	Erik


Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Stefan Bodewig <bo...@apache.org>.
On Mon, 3 Feb 2003, Erik Hatcher <ja...@ehatchersolutions.com>
wrote:

>> There are two occurances of
>>
>> java.lang.IllegalStateException: Engine is null?!
> 
> 
> But last night was not with the 256m setting, right?

Correct.

> The OutOfMemory is still the kicker here, I think.

So wait for next night's nag 8-)

I still find it hard to move to all the information and filter out
relevant parts.  Is there any way to make the output less noisy?

Stefan

Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
On Monday, February 3, 2003, at 09:04  AM, Stefan Bodewig wrote:
> actually there are error messages even in last nights build, I don't
> know whether they are significant:
> <http://cvs.apache.org/builds/gump/latest/ant-xdocs-proposal.html>
>
> There are two occurances of
>
> java.lang.IllegalStateException: Engine is null?!


But last night was not with the 256m setting, right?  The OutOfMemory 
is still the kicker here, I think.  Until that is resolved I don't 
think any of the other junk is spews is that relevant.  Although I 
could be wrong about that.  I know I saw lots of errors until I got the 
memory thing solved for myself.

	Erik


Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Stefan Bodewig <bo...@apache.org>.
actually there are error messages even in last nights build, I don't
know whether they are significant:
<http://cvs.apache.org/builds/gump/latest/ant-xdocs-proposal.html>

There are two occurances of 

java.lang.IllegalStateException: Engine is null?!

Stefan

Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
On Monday, February 3, 2003, at 08:36  AM, Stefan Bodewig wrote:
> On 03 Feb 2003, Stefan Bodewig <bo...@apache.org> wrote:
>
>> I've committed something that is supposed to work.
>
> "supposed to" because:
>
> Scrolling back through all the noise I find this one here
>
> ,----
> | [antdoclet] java.lang.ClassNotFoundException: 
> org.apache.tools.ant.taskdefs.optional.sound.SoundTask
> `----
>
> Is this the cause?  Can XDoclet deal with finding sources without the
> corresponding classes?  Gump will not compile all optional tasks
> because we have not added all possible third party libraries.

I've cloned all the <selector>'s from Ant's main build.xml - so it 
should only process the source files that it has classes for, but 
perhaps there is an issue with it.  I'll look into it sometime soon.

	Erik


Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Stefan Bodewig <bo...@apache.org>.
On 03 Feb 2003, Stefan Bodewig <bo...@apache.org> wrote:

> I've committed something that is supposed to work.

"supposed to" because:

,----
| BUILD FAILED
| file:///home/bodewig/dev/gump/jakarta-ant/proposal/xdocs/build.xml:387: Unexpected error
| 
| Total time: 2 minutes 31 seconds
`----

Scrolling back through all the noise I find this one here 

,----
| [antdoclet] java.lang.ClassNotFoundException: org.apache.tools.ant.taskdefs.optional.sound.SoundTask
`----

Is this the cause?  Can XDoclet deal with finding sources without the
corresponding classes?  Gump will not compile all optional tasks
because we have not added all possible third party libraries.

Stefan

Re: xdocs Gump

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
On Monday, February 3, 2003, at 08:46  AM, Conor MacNeill wrote:
> Erik Hatcher wrote:
>> Wow!
>> You're my hero.  So do I need to lobby for the 256m, or did you set 
>> that up already too?
>
> Erik, just curiosity more than anything else since I don't know the 
> internals of xdoclet at all - why does it need so much memory?

Its actually xjavadoc that needs the memory - the parsing of source 
code (using a JavaCC-based Java parser) apparently takes a lot of 
memory.  I'm clueless to what is going on under the hood of xjavadoc, 
so I can't say for sure.

	Erik


Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Conor MacNeill <co...@cortexebusiness.com.au>.
Erik Hatcher wrote:
> Wow!
> 
> You're my hero.  So do I need to lobby for the 256m, or did you set that 
> up already too?
> 

Erik, just curiosity more than anything else since I don't know the 
internals of xdoclet at all - why does it need so much memory?

Conor



Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
Wow!

You're my hero.  So do I need to lobby for the 256m, or did you set 
that up already too?

I look forward to the lack of a nag mail tomorrow :))

	Erik


On Monday, February 3, 2003, at 08:30  AM, Stefan Bodewig wrote:
> On 31 Jan 2003, Stefan Bodewig <bo...@apache.org> wrote:
>> On Thu, 30 Jan 2003, Erik Hatcher
>> <ja...@ehatchersolutions.com> wrote:
>>
>>> Again, it'd take a Gump expert only a little bit of time probably,
>>
>> I'm not sure.
>
> It didn't take a Gump expert or an XSLT expert, it turned out to be
> rather easy 8-)
>
> I've committed something that is supposed to work.
>
> Stefan
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ant-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: ant-dev-help@jakarta.apache.org
>
>


Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Stefan Bodewig <bo...@apache.org>.
On 31 Jan 2003, Stefan Bodewig <bo...@apache.org> wrote:
> On Thu, 30 Jan 2003, Erik Hatcher
> <ja...@ehatchersolutions.com> wrote:
> 
>> Again, it'd take a Gump expert only a little bit of time probably,
> 
> I'm not sure.

It didn't take a Gump expert or an XSLT expert, it turned out to be
rather easy 8-)

I've committed something that is supposed to work.

Stefan

Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Stefan Bodewig <bo...@apache.org>.
On Sat, 01 Feb 2003, Conor MacNeill <co...@cortexebusiness.com.au>
wrote:

> Then run
> 
> ant -Dworkspace=erik.xml

And make sure you have an XSLT transformer on your CLASSPATH (or use
JDK 1.4).  The full JAXP 1.1 program is all you should need AFAIK.

Stefan

Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Conor MacNeill <co...@cortexebusiness.com.au>.
Erik Hatcher wrote:
> On Friday, January 31, 2003, at 05:48  AM, Stefan Bodewig wrote:
> 
>>> Or is this back in my hands?
>>
>>
>> Why not?
> 
> 
> I got jakarta-gump from CVS yesterday, and tried:
> 
>     ant
> 

I created a workspace file (conor.xml) as follows

<?xml version="1.0" ?>
<workspace basedir="[gump_home]" pkgdir="/opt"
            sync="rsync -r -a --delete" version="0.3">

   <property name="build.sysclasspath" value="only"/>

   <profile href="profile/gump.xml"/>

</workspace>

Let's call your's erik.xml (if you use gen.sh, it needs to be the hostname, 
I think)

Replace the basedir value with wherever you want to have Gump download and 
build things.

Then run

ant -Dworkspace=erik.xml

If you want to check for packages you will need to download and install do this

ant -Dworkspace=erik.xml check

HTH
Conor


Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Stefan Bodewig <bo...@apache.org>.
On Sat, 1 Feb 2003, Erik Hatcher <ja...@ehatchersolutions.com>
wrote:

> Neither succeeded for me.

There is some hardcoded path to Xalan in it, that may need to get
overridden (I use the XALAN env variable for this).

> Is Gump runnable out-of-the-box these days?

More or less, yes.  You have to define a workspace, though.

>> Do you want to do some of the things that are higher on my priority
>> list so we can swap 8-)
> 
> I don't think you'd want to swap with my TODO list either :)

;-)

Didn't mean to imply that.  I know that you know, but ...

Stefan

Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
On Friday, January 31, 2003, at 05:48  AM, Stefan Bodewig wrote:
>> Or is this back in my hands?
>
> Why not?

I got jakarta-gump from CVS yesterday, and tried:

	ant

and

	gen.sh

Neither succeeded for me.  Is Gump runnable out-of-the-box these days?  
I got compile errors on Jenny.  Missing the DOM classes (Element, for 
example).  Do I need to tweak with my environment to add dependencies 
just to get Gump to build?

>> Again, it'd take a Gump expert only a little bit of time probably,
>
> I'm not sure.  You'd basically have to modify XSLT stylesheets, and
> even if I'd consider myself above the rookie level when it comes to
> Gump, I'm more or less XSLT ignorant.
>
> Do you want to do some of the things that are higher on my priority
> list so we can swap 8-)

I don't think you'd want to swap with my TODO list either :)  In fact, 
I wouldn't wish mine upon my worst enemies at this point.  But we're 
all in the same boat with things to do, no question.  I'll see what I 
can do with this when time permits.  Thanks for your help in getting 
the build set up as much as you have so far.

I know XSLT ok enough to probably get this working, but I'll need a 
functioning Gump first.  I'll get on the Gump list when I start 
fighting with this again and get it going.

	Erik


Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Stefan Bodewig <bo...@apache.org>.
On Thu, 30 Jan 2003, Erik Hatcher <ja...@ehatchersolutions.com>
wrote:

> Is this in progress?

If you are waiting for me, well it might be in progress but at a
rather low priority, sorry.

> Or is this back in my hands?

Why not?

> Again, it'd take a Gump expert only a little bit of time probably,

I'm not sure.  You'd basically have to modify XSLT stylesheets, and
even if I'd consider myself above the rookie level when it comes to
Gump, I'm more or less XSLT ignorant.

Do you want to do some of the things that are higher on my priority
list so we can swap 8-)

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: ant-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: ant-dev-help@jakarta.apache.org


Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
On Thursday, January 30, 2003, at 03:40  AM, Stefan Bodewig wrote:
> On Wed, 29 Jan 2003, Erik Hatcher <ja...@ehatchersolutions.com>
> wrote:
>
>> What else needs to be done?
>
> Gump's stylesheets need to get patched to understand some kind of
> <jvmarg> element inside <ant> and add the content to the generated
> build scripts.

Is this in progress?  Or is this back in my hands?  Again, it'd take a 
Gump expert only a little bit of time probably, and it'd take me a fair 
bit longer - but I know the open-source way, if you want it done, do it 
yourself :)

But I think the effort will be well worth it - and folks will then get 
to see first hand what can be generated and evolving it will be much 
more visible and effective I think.

Thanks,
	Erik


---------------------------------------------------------------------
To unsubscribe, e-mail: ant-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: ant-dev-help@jakarta.apache.org


Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Stefan Bodewig <bo...@apache.org>.
On Wed, 29 Jan 2003, Erik Hatcher <ja...@ehatchersolutions.com>
wrote:

> What else needs to be done?

Gump's stylesheets need to get patched to understand some kind of
<jvmarg> element inside <ant> and add the content to the generated
build scripts.

After that, add the new born element to the docs and to the descriptor
for the xdocs stuff (and maybe ask whether 256m is OK with all people
using the default Gump profile before that).

Stefan

---------------------------------------------------------------------
To unsubscribe, e-mail: ant-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: ant-dev-help@jakarta.apache.org


Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
Stefan,

I just checked the Gump e-mail archives and see the two commits you did 
yesterday to get started on this.  What else needs to be done?

Many thanks for your work to get this incorporated into the nightly 
Gump builds!

	Erik


On Tuesday, January 28, 2003, at 12:07  PM, Erik Hatcher wrote:
> On Tuesday, January 28, 2003, at 04:47  AM, Stefan Bodewig wrote:
>>> ANT_OPTS = -Xmx1000m
>>
>> Uhm, that's a little too tough IMHO.
>
> 256m works fine on my machine also.
>
> 	Erik
>
>
> --
> To unsubscribe, e-mail:   
> <ma...@jakarta.apache.org>
> For additional commands, e-mail: 
> <ma...@jakarta.apache.org>
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: ant-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: ant-dev-help@jakarta.apache.org


Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
On Tuesday, January 28, 2003, at 04:47  AM, Stefan Bodewig wrote:
>> ANT_OPTS = -Xmx1000m
>
> Uhm, that's a little too tough IMHO.

256m works fine on my machine also.

	Erik


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Stefan Bodewig <bo...@apache.org>.
On Tue, 28 Jan 2003, Erik Hatcher <ja...@ehatchersolutions.com>
wrote:

> The JAR is xdoclet-xjavadoc-uc-<VERSION>.jar
> 
> Chances are both were built with Gump, right?

Both get built, but Gump doesn't know about the uc one.  Yet.

> But the classpath ordering is crucial here.

I'll drop the xjavadoc in favor of xjavadoc-uc from Gump completely.

> ANT_OPTS = -Xmx1000m

Uhm, that's a little too tough IMHO.

> Definitely more VM memory is needed to run this.

Any idea how much?  If it turns out to be more than I'd like to see
consumed on say nagoya, I'll remove the descriptor from Gump's default
profile and tell people who are interested how to put it into their
own workspace.

As for your request to publish the stuff:  gump@jakarta.apache.org may
be the better list.

Stefan

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
On Tuesday, January 28, 2003, at 04:27  AM, Stefan Bodewig wrote:
> [antdoclet] Error parsing File  
> /home/bodewig/dev/gump/jakarta-ant/src/main/org/apache/tools/ant/ 
> listener/AnsiColorLogger.java:Lexical error: xjavadoc.TokenMgrError:  
> Lexical error at line 163, column 44.  Encountered: "u" (117), after :  
> "\"\\"

This is because the wrong xjavadoc JAR is being used in the classpath.   
The Unicode JAR is needed, which apparently runs slightly slower than  
the non-Unicode parser - but its needed to get the '\...' stuff to  
parse.

The JAR is xdoclet-xjavadoc-uc-<VERSION>.jar

Chances are both were built with Gump, right?  But the classpath  
ordering is crucial here.

> BUILD FAILED
> java.lang.OutOfMemoryError
>
> Total time: 46 seconds
>
> Which is likely to happen in nightly builds as well.
>
> I'll see whether I can patch Gump to accept JVM arguments and up the
> memory and will commit what I currently have as-is.

I run with this:

ANT_OPTS = -Xmx1000m  
- 
Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLo 
g

Definitely more VM memory is needed to run this.

	Erik


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: xdocs Gump (was [PATCH] Velocity task)

Posted by Stefan Bodewig <bo...@apache.org>.
On 28 Jan 2003, Stefan Bodewig <bo...@apache.org> wrote:
> On Tue, 28 Jan 2003, Erik Hatcher
> <ja...@ehatchersolutions.com> wrote:

>> But this should be a one-liner that only takes a second for you to
>> set up, right?
> 
> Unlikely, I'd bet it will take at least five lines 8-)

Actually

  <project name="ant-xdocs-proposal">
    <ant basedir="proposal/xdocs" target="docs-from-scratch">
      <property name="ant.home" reference="home" project="jakarta-ant"/>
    </ant>
    <depend project="jakarta-ant"/>
    <depend project="xml-xerces"/>
    <depend project="xdoclet" inherit="runtime"/>
    <nag to="ant-dev@jakarta.apache.org"
         from="Erik Hatcher &lt;jakarta-ant@ehatchersolutions.com&gt;"/>
  </project>

Man is this noisy, literally hundreds of lines looking like

[antdoclet] (ConfigParamIntrospector.fillConfigParamsHashMapUsingReflectionFor 232 ) configs.size()=55
[antdoclet] (XDocletMain.start                   32  ) Context successfully loaded.

Some strange messages like this

[antdoclet] Error parsing File /home/bodewig/dev/gump/jakarta-ant/src/main/org/apache/tools/ant/listener/AnsiColorLogger.java:Lexical error: xjavadoc.TokenMgrError: Lexical error at line 163, column 44.  Encountered: "u" (117), after : "\"\\"

for a perfectly valid unicode escape.

And in the end

BUILD FAILED
java.lang.OutOfMemoryError

Total time: 46 seconds

Which is likely to happen in nightly builds as well.

I'll see whether I can patch Gump to accept JVM arguments and up the
memory and will commit what I currently have as-is.

Stefan

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Stefan Bodewig <bo...@apache.org>.
On Tue, 28 Jan 2003, Erik Hatcher <ja...@ehatchersolutions.com>
wrote:

> I'm sure it keeps getting easier and easier to configure though.

No, not at all.

If you want to avoid bootstrapping everything, make everything an
installed package.

> DVSL is used to generate the docs currently.  That relies on
> Velocity too.

I'll add it.

> Commons Logging and Commons Collections are also in the lib
> directory, but these should be picked up with the dependency on
> XDoclet.

They are.

Stefan

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
On Tuesday, January 28, 2003, at 04:01  AM, Stefan Bodewig wrote:
> You know you have commit acces to jakarta-gump?

Yes, I know.... but changing something would require that I test it 
first, and that would take me a while to get configured and run.  I've 
run Gump in the past, but it took a while for me to get configured to 
run it properly, especially trying to avoid bootstrapping the entire 
world.  I'm sure it keeps getting easier and easier to configure though.

> build file here is proposal/xdocs/build.xml, right?

yes.

>
> What dependencies do we have?  Ant, Xerces, Xdoclet and all its
> runtime dependencies, ... Anything else?

DVSL is used to generate the docs currently.  That relies on Velocity 
too.

Commons Logging and Commons Collections are also in the lib directory, 
but these should be picked up with the dependency on XDoclet.

> I'll take care of it.

Many thanks!

>> Could the files in build/docs be made web accessible also?
>
> But not of this (needs Sam's interaction), if you want this to happen
> during the normal "nightly" Gump runs.

Yeah, I figured this was the tougher part.  Let me know if there is 
anything I can do to help with the publishing piece.  If directory 
browsing is enabled on the web view, that would be ideal -  if not then 
I'll have to create an index page to point to each of the task docs 
somehow.

	Erik


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Stefan Bodewig <bo...@apache.org>.
On Tue, 28 Jan 2003, Erik Hatcher <ja...@ehatchersolutions.com>
wrote:

> Sam, could you get proposal/xdocs/build.xml run during your usual
> Gump runs?

You know you have commit acces to jakarta-gump?

> But this should be a one-liner that only takes a second for you to
> set up, right?

Unlikely, I'd bet it will take at least five lines 8-)

> I've added a convenience target "docs-from-scratch" to the build
> that runs the gen and docs target in one shot (they aren't directly
> dependent on one another at this point in order to re-gen docs
> without re-gen'ing the descriptors).

build file here is proposal/xdocs/build.xml, right?

What dependencies do we have?  Ant, Xerces, Xdoclet and all its
runtime dependencies, ... Anything else?

I'll take care of it.

> Could the files in build/docs be made web accessible also?

But not of this (needs Sam's interaction), if you want this to happen
during the normal "nightly" Gump runs.

Stefan

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
Explicitly CC'ing Sam...

On Monday, January 27, 2003, at 02:17  PM, Steve Loughran wrote:
>> worth a look just to see how good the XDoclet
>> documentation gneeration is working :)
>
> how about getting Gump to do the docs every day, a snapshot of what the
> future docs will be...

Excellent idea.

Sam, could you get proposal/xdocs/build.xml run during your usual Gump 
runs?  Or let me know what I need to do in order to make that happen?  
I know, you'll tell me that all Jakarta committers are Gump committers, 
right?  :)  But this should be a one-liner that only takes a second for 
you to set up, right?  Whereas it'd take me much much longer.

I've added a convenience target "docs-from-scratch" to the build that 
runs the gen and docs target in one shot (they aren't directly 
dependent on one another at this point in order to re-gen docs without 
re-gen'ing the descriptors).

Could the files in build/docs be made web accessible also?  That would 
allow us to peruse the output and discuss where to go from here with it.

Thanks,
	Erik


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Steve Loughran <st...@iseran.com>.
----- Original Message -----
From: "Erik Hatcher" <ja...@ehatchersolutions.com>
To: "Ant Developers List" <an...@jakarta.apache.org>
Sent: Monday, January 20, 2003 15:40
Subject: Re: [PATCH] Velocity task


> worth a look just to see how good the XDoclet
> documentation gneeration is working :)

how about getting Gump to do the docs every day, a snapshot of what the
future docs will be...


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PATCH] Velocity task

Posted by Erik Hatcher <ja...@ehatchersolutions.com>.
One minor detail about adding new tasks to Ant - lets try to be sure  
that any XDoclet tags that need to be added are added.  The way to test  
this is  to run the proposal/xdocs build and look at the results in the  
build/gen directory to ensure that the task is documented properly.   
For this particular task it would require that Velocity and any other  
dependencies be placed in ANT_HOME/lib and a version of Ant containing  
this task built and used when running the xdocs process.

 From what I can tell, not much if anything would need to be done to  
this task, but its worth a look just to see how good the XDoclet  
documentation gneeration is working :)

	Erik



On Monday, January 20, 2003, at 06:19  PM, Hiroaki Nakamura wrote:

> Hi.
> I made the Jakarta-Velocity task for Ant.
> Please take a look and consider to accept it as a new optional task.
>
> The <velocity> task is meant to be a richer version of filter function
> of the <copy> task. I have been using the filter function for replacing
> parameters in configuration files. But I need more functionality than
> just replacing. I think this is where Velocity comes in. This template
> engine has directives like #if and #foreach, so it is more powerful.
>
> The <velocity> task has attributes and nested elements similar to the
> <copy> task. I thought it would be easy to use. But not all of <copy>
> attributes are supported. Please see the velocity.html in the patch.
>
> Here is a example of calling a <velocity> task:
>
>     <velocity todir="c" propertyfile="velocity.properties">
>       <velocitycontext>
>         <contextdata key="a" value="A1"/>
>         <contextdata key="b" value="B1" if="SOME_PROP"/>
>         <contextdata key="b" value="B2" unless="SOME_PROP"/>
>         <contextdata key="str" classname="my.package.StringTool"/>
>       </velocitycontext>
>       <fileset dir="a">
>         <include name="**/*.vm"/>
>       </fileset>
>       <mapper type="glob" from="*.vm" to="*.html"/>
>     </velocity>
>
> Opinions and suggestions are welcome.
>
> --
> )Hiroaki Nakamura) hnakamur@v003.vaio.ne.jp
>
>
> Here is the patch for the <velocity> task:
>
> diff -ruN  
> jakarta-ant-1.5.1.orig/docs/manual/OptionalTasks/velocity.html  
> jakarta-ant-1.5.1/docs/manual/OptionalTasks/velocity.html
> --- jakarta-ant-1.5.1.orig/docs/manual/OptionalTasks/velocity.html  
> 1970-01-01 09:00:00.000000000 +0900
> +++ jakarta-ant-1.5.1/docs/manual/OptionalTasks/velocity.html  
> 2003-01-21 07:39:03.000000000 +0900
> @@ -0,0 +1,232 @@
> +<html>
> +
> +<head>
> +<meta http-equiv="Content-Language" content="en-us">
> +<title>Velocity Task</title>
> +</head>
> +
> +<body>
> +
> +<h2><a name="velocity">Velocity</a></h2>
> +<h3>Description</h3>
> +<p>Run <a href="http://jakarta.apache.org/velocity/index.html"  
> target="_top">Jakarta-Velocity</a> on a file or FileSet to a new
> file or directory.
> +By default, files are only copied if the source file is newer than the
> +destination file, or when the destination file does not exist.   
> However,
> +you can explicitly overwrite files with the <code>overwrite</code>  
> attribute.</p>
> +<p><a href="../CoreTypes/fileset.html">FileSet</a>s are used to  
> select a
> +set of files to copy.
> +To use a <code>&lt;fileset&gt;</code>, the <code>todir</code>  
> attribute
> +must be set.</p>
> +<h3>Parameters</h3>
> +<table border="1" cellpadding="2" cellspacing="0">
> +  <tr>
> +    <td valign="top"><b>Attribute</b></td>
> +    <td valign="top"><b>Description</b></td>
> +    <td align="center" valign="top"><b>Required</b></td>
> +  </tr>
> +  <tr>
> +    <td valign="top">propertyfile</td>
> +     <td valign="top">The property file which is used to initialize  
> Velocity.
> +     </td>
> +     <td valign="top" align="center">Yes</td>
> +  </tr>
> +  <tr>
> +    <td valign="top">file</td>
> +    <td valign="top">The file to copy.</td>
> +    <td valign="top" align="center">Yes, unless a nested
> +    <code>&lt;fileset&gt;</code> element is used.</td>
> +  </tr>
> +  <tr>
> +    <td valign="top">tofile</td>
> +    <td valign="top">The file to copy to.</td>
> +    <td valign="top" align="center" rowspan="2">With the  
> <code>file</code>
> +      attribute, either <code>tofile</code> or <code>todir</code> can  
> be used.
> +      With nested <code>&lt;fileset&gt;</code> elements, if the set  
> of files
> +      is greater than 1, or if only the <code>dir</code> attribute is
> +      specified in the <code>&lt;fileset&gt;</code>, or if the
> +      <code>file</code> attribute is also specified, then only
> +      <code>todir</code> is allowed.</td>
> +  </tr>
> +  <tr>
> +    <td valign="top">todir</td>
> +    <td valign="top">The directory to copy to.</td>
> +  </tr>
> +  <tr>
> +    <td valign="top">overwrite</td>
> +    <td valign="top">Overwrite existing files even if the destination
> +      files are newer.</td>
> +    <td valign="top" align="center">No; defaults to false.</td>
> +  </tr>
> +  <tr>
> +    <td valign="top">flatten</td>
> +    <td valign="top">Ignore the directory structure of the source  
> files,
> +      and copy all files into the directory specified by the  
> <code>todir</code>
> +      attribute.  Note that you can achieve the same effect by using a
> +      <a href="../CoreTypes/mapper.html#flatten-mapper">flatten  
> mapper</a>.</td>
> +    <td valign="top" align="center">No; defaults to false.</td>
> +  </tr>
> +  <tr>
> +    <td valign="top">failonerror</td>
> +     <td valign="top">Log a warning message, but do not stop the  
> build,
> +       when the file to copy does not exist.
> +       Only meaningful when copying a single file.
> +     </td>
> +     <td valign="top" align="center">No; defaults to true.</td>
> +  </tr>
> +  <tr>
> +    <td valign="top">templatebasedir</td>
> +     <td valign="top">The template base directory. This is used to
> +       caclutate a relative path of a template file. Velocity  
> receives a
> +       relative path and searches a template file in Velocity's  
> search paths.
> +     </td>
> +     <td valign="top" align="center">No; defaults to project  
> basedir.</td>
> +  </tr>
> +</table>
> +<h3>Parameters specified as nested elements</h3>
> +
> +<h4>velocitycontext</h4>
> + <p>A &lt;velocitycontext&gt; is used to specify the VelocityContext  
> data.
> + It has nested &lt;contextdata&gt; elements.</p>
> +
> +<h4>contextdata</h4>
> + <p>A &lt;contextdata&gt; is a nested element of  
> &lt;velocitycontext&gt;
> + and is used to specify a VelocityContext datum.</p>
> +
> +<table border="1" cellpadding="2" cellspacing="0">
> +  <tr>
> +    <td valign="top"><b>Attribute</b></td>
> +    <td valign="top"><b>Description</b></td>
> +    <td align="center" valign="top"><b>Required</b></td>
> +  </tr>
> +  <tr>
> +    <td valign="top">key</td>
> +     <td valign="top">The key of a VelocityContext datum.
> +     </td>
> +     <td valign="top" align="center">Yes</td>
> +  </tr>
> +  <tr>
> +    <td valign="top">value</td>
> +    <td valign="top">The value of a VelocityContext datum.</td>
> +    <td valign="top" align="center" rowspan="2">One of either  
> <var>value</var>
> +    or <var>classname</var>.</td>
> +  </tr>
> +  <tr>
> +    <td valign="top">classname</td>
> +    <td valign="top">An instance of this classname is used as a  
> VelocityContext
> +    datum. The specified class must have the public non-argument  
> constructor.
> +    And if the class has a public method
> +    <code>setContext(org.apache.velocity.context.Context)</code>,
> +    it is invoked by reflection.
> +    </td>
> +  </tr>
> +  <tr>
> +    <td valign="top">if</td>
> +    <td valign="top">Only use this data if the named property is  
> set.</td>
> +    <td align="center" valign="top">No</td>
> +  </tr>
> +  <tr>
> +    <td valign="top">unless</td>
> +    <td valign="top">Only use this data if the named property is
> +       <b>not</b> set.</td>
> +    <td align="center" valign="top">No</td>
> +  </tr>
> +</table>
> +
> +<h4>fileset</h4>
> + <p><a href="../CoreTypes/fileset.html">FileSet</a>s are used to  
> select
> +sets of files to run velocity on.
> + To use a fileset, the <code>todir</code> attribute must be set.</p>
> +
> +<h4>mapper</h4>
> + <p>You can define filename transformations by using a nested <a
> + href="../CoreTypes/mapper.html">mapper</a> element. The default  
> mapper used by
> + <code>&lt;velocity&gt;</code> is the <a
> + href="../CoreTypes/mapper.html#identity-mapper">identity  
> mapper</a>.</p>
> +
> +<h3>Examples</h3>
> +<p><b>Run velocity on a single file</b></p>
> +<pre>
> +  &lt;velocity file=&quot;myfile.txt&quot;  
> tofile=&quot;mycopy.txt&quot;
> +      propertyfile=&quot;velocity.properties&quot;&gt;
> +    &lt;velocitycontext&gt;
> +      &lt;contextdata key=&quot;key1&quot;  
> value=&quot;value1&quot;/&gt;
> +      &lt;contextdata key=&quot;key2&quot;  
> classname=&quot;some.Class1&quot;/&gt;
> +      &lt;contextdata key=&quot;key3&quot; value=&quot;value3&quot;  
> if=&quot;SOME_PROPERTY&quot;/&gt;
> +      &lt;contextdata key=&quot;key4&quot; value=&quot;value4&quot;  
> unless=&quot;SOME_PROPERTY&quot;/&gt;
> +    &lt;/velocitycontext&gt;
> +  &lt;/velocity&gt;
> +</pre>
> +<p><b>Run velocity on a single file to a directory</b></p>
> +<pre>
> +  &lt;velocity file=&quot;myfile.txt&quot;  
> todir=&quot;../some/other/dir&quot;
> +      propertyfile=&quot;velocity.properties&quot;&gt;
> +    &lt;velocitycontext&gt;
> +      &lt;contextdata key=&quot;key1&quot;  
> value=&quot;value1&quot;/&gt;
> +      &lt;contextdata key=&quot;key2&quot;  
> classname=&quot;some.Class1&quot;/&gt;
> +      &lt;contextdata key=&quot;key3&quot; value=&quot;value3&quot;  
> if=&quot;SOME_PROPERTY&quot;/&gt;
> +      &lt;contextdata key=&quot;key4&quot; value=&quot;value4&quot;  
> unless=&quot;SOME_PROPERTY&quot;/&gt;
> +    &lt;/velocitycontext&gt;
> +  &lt;/velocity&gt;
> +</pre>
> +<p><b>Run velocity on a set of files to a directory</b></p>
> +<pre>
> +  &lt;velocity todir=&quot;../dest/dir&quot;
> +      propertyfile=&quot;velocity.properties&quot;&gt;
> +    &lt;velocitycontext&gt;
> +      &lt;contextdata key=&quot;key1&quot;  
> value=&quot;value1&quot;/&gt;
> +      &lt;contextdata key=&quot;key2&quot;  
> classname=&quot;some.Class1&quot;/&gt;
> +      &lt;contextdata key=&quot;key3&quot; value=&quot;value3&quot;  
> if=&quot;SOME_PROPERTY&quot;/&gt;
> +      &lt;contextdata key=&quot;key4&quot; value=&quot;value4&quot;  
> unless=&quot;SOME_PROPERTY&quot;/&gt;
> +    &lt;/velocitycontext&gt;
> +    &lt;fileset dir=&quot;src_dir&quot;&gt;
> +      &lt;exclude name=&quot;**/*.java&quot;/&gt;
> +    &lt;/fileset&gt;
> +  &lt;/velocity&gt;
> +
> +  &lt;velocity todir=&quot;../dest/dir&quot;
> +      propertyfile=&quot;velocity.properties&quot;&gt;
> +    &lt;velocitycontext&gt;
> +      &lt;contextdata key=&quot;key1&quot;  
> value=&quot;value1&quot;/&gt;
> +      &lt;contextdata key=&quot;key2&quot;  
> classname=&quot;some.Class1&quot;/&gt;
> +      &lt;contextdata key=&quot;key3&quot; value=&quot;value3&quot;  
> if=&quot;SOME_PROPERTY&quot;/&gt;
> +      &lt;contextdata key=&quot;key4&quot; value=&quot;value4&quot;  
> unless=&quot;SOME_PROPERTY&quot;/&gt;
> +    &lt;/velocitycontext&gt;
> +    &lt;fileset dir=&quot;src_dir&quot;  
> excludes=&quot;**/*.java&quot;/&gt;
> +  &lt;/velocity&gt;
> +</pre>
> +<p><b>Run velocity on a set of files to a directory, appending
> +<code>.bak</code> to the file name on the fly</b></p>
> +<pre>
> +  &lt;velocity todir=&quot;../backup/dir&quot;
> +      propertyfile=&quot;velocity.properties&quot;&gt;
> +    &lt;velocitycontext&gt;
> +      &lt;contextdata key=&quot;key1&quot;  
> value=&quot;value1&quot;/&gt;
> +      &lt;contextdata key=&quot;key2&quot;  
> classname=&quot;some.Class1&quot;/&gt;
> +      &lt;contextdata key=&quot;key3&quot; value=&quot;value3&quot;  
> if=&quot;SOME_PROPERTY&quot;/&gt;
> +      &lt;contextdata key=&quot;key4&quot; value=&quot;value4&quot;  
> unless=&quot;SOME_PROPERTY&quot;/&gt;
> +    &lt;/velocitycontext&gt;
> +    &lt;fileset dir=&quot;src_dir&quot;/&gt;
> +    &lt;mapper type=&quot;glob&quot; from=&quot;*&quot;  
> to=&quot;*.bak&quot;/&gt;
> +  &lt;/velocity&gt;
> +</pre>
> +
> +<p><strong>Unix Note:</strong> Destination file permissions are not  
> the same as
> +the template files; they end up with the default <code>UMASK</code>  
> permissions
> +instead. This
> +is caused by the lack of any means to query or set file permissions  
> in the
> +current Java runtimes.
> +</p>
> +
> +<p><strong>Windows Note:</strong> If you a destination file already  
> exists,
> +but with different casing, the destination file takes on the case of  
> the
> +original. The workaround is to
> +<a href="delete.html">delete</a>
> +the file in the destination directory before you run velocity.
> +</p>
> +
> +<hr><p align="center">Copyright &copy; 2003 Apache Software  
> Foundation.
> +All rights Reserved.</p>
> +
> +</body>
> +</html>
> +
> diff -ruN jakarta-ant-1.5.1.orig/docs/manual/install.html  
> jakarta-ant-1.5.1/docs/manual/install.html
> --- jakarta-ant-1.5.1.orig/docs/manual/install.html 2002-10-02  
> 11:10:18.000000000 +0900
> +++ jakarta-ant-1.5.1/docs/manual/install.html 2003-01-21  
> 07:37:06.000000000 +0900
> @@ -381,6 +381,12 @@
>      <td><a href="http://www.clarkware.com/software/JDepend.html"
>           
> target="_top">http://www.clarkware.com/software/JDepend.html</a></td>
>    </tr>
> +  <tr>
> +    <td>Velocity JAR(s)</td>
> +    <td>velocity task</td>
> +    <td><a href="http://jakarta.apache.org/velocity/index.html"
> +         
> target="_top">http://jakarta.apache.org/velocity/index.html</a></td>
> +  </tr>
>  </table>
>  <br>
>  <hr>
> diff -ruN jakarta-ant-1.5.1.orig/docs/manual/optionaltasklist.html  
> jakarta-ant-1.5.1/docs/manual/optionaltasklist.html
> --- jakarta-ant-1.5.1.orig/docs/manual/optionaltasklist.html  
> 2002-10-02 11:10:06.000000000 +0900
> +++ jakarta-ant-1.5.1/docs/manual/optionaltasklist.html 2003-01-20  
> 09:40:43.000000000 +0900
> @@ -62,6 +62,7 @@
>  <a href="OptionalTasks/test.html">Test</a><br>
>  <a href="OptionalTasks/translate.html">Translate</a><br>
>  <a href="Integration/VAJAntTool.html#tasks">Visual Age for Java  
> Tasks</a><br>
> +<a href="OptionalTasks/velocity.html">Velocity</a><br>
>  <a href="OptionalTasks/vss.html#tasks">Microsoft Visual SourceSafe  
> Tasks</a><br>
>  <a href="OptionalTasks/wljspc.html">Weblogic JSP Compiler</a><br>
>  <a href="OptionalTasks/xmlvalidate.html">XmlValidate</a><br>
> diff -ruN  
> jakarta-ant-1.5.1.orig/src/main/org/apache/tools/ant/taskdefs/ 
> defaults.properties
> jakarta-ant-1.5.1/src/main/org/apache/tools/ant/taskdefs/ 
> defaults.properties
> ---  
> jakarta-ant-1.5.1.orig/src/main/org/apache/tools/ant/taskdefs/ 
> defaults.properties 2002-10-02 11:08:34.000000000 +0900
> +++  
> jakarta-ant-1.5.1/src/main/org/apache/tools/ant/taskdefs/ 
> defaults.properties 2003-01-21 07:29:56.000000000 +0900
> @@ -169,6 +169,7 @@
>   
> jarlib- 
> available=org.apache.tools.ant.taskdefs.optional.extension.JarLibAvaila 
> bleTask
>   
> jarlib- 
> resolve=org.apache.tools.ant.taskdefs.optional.extension.JarLibResolveT 
> ask
>  setproxy=org.apache.tools.ant.taskdefs.optional.net.SetProxy
> +velocity=org.apache.tools.ant.taskdefs.optional.VelocityTask
>
>  # deprecated ant tasks (kept for back compatibility)
>   
> starteam=org.apache.tools.ant.taskdefs.optional.scm.AntStarTeamCheckOut
> diff -ruN  
> jakarta-ant-1.5.1.orig/src/main/org/apache/tools/ant/taskdefs/ 
> optional/VelocityTask.java
> jakarta-ant-1.5.1/src/main/org/apache/tools/ant/taskdefs/optional/ 
> VelocityTask.java
> ---  
> jakarta-ant-1.5.1.orig/src/main/org/apache/tools/ant/taskdefs/ 
> optional/VelocityTask.java 1970-01-01 09:00:00.000000000 +0900
> +++  
> jakarta-ant-1.5.1/src/main/org/apache/tools/ant/taskdefs/optional/ 
> VelocityTask.java 2003-01-20 10:48:52.000000000 +0900
> @@ -0,0 +1,478 @@
> +/*
> + * The Apache Software License, Version 1.1
> + *
> + * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
> + * reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + *
> + * 2. Redistributions in binary form must reproduce the above  
> copyright
> + *    notice, this list of conditions and the following disclaimer in
> + *    the documentation and/or other materials provided with the
> + *    distribution.
> + *
> + * 3. The end-user documentation included with the redistribution, if
> + *    any, must include the following acknowlegement:
> + *       "This product includes software developed by the
> + *        Apache Software Foundation (http://www.apache.org/)."
> + *    Alternately, this acknowlegement may appear in the software  
> itself,
> + *    if and wherever such third-party acknowlegements normally  
> appear.
> + *
> + * 4. The names "The Jakarta Project", "Ant", and "Apache Software
> + *    Foundation" must not be used to endorse or promote products  
> derived
> + *    from this software without prior written permission. For written
> + *    permission, please contact apache@apache.org.
> + *
> + * 5. Products derived from this software may not be called "Apache"
> + *    nor may "Apache" appear in their names without prior written
> + *    permission of the Apache Group.
> + *
> + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
> + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> + * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
> + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
> + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
> + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + *  
> ====================================================================
> + *
> + * This software consists of voluntary contributions made by many
> + * individuals on behalf of the Apache Software Foundation.  For more
> + * information on the Apache Software Foundation, please see
> + * <http://www.apache.org/>.
> + */
> +
> +package org.apache.tools.ant.taskdefs.optional;
> +
> +import java.io.File;
> +import java.io.FileOutputStream;
> +import java.io.OutputStreamWriter;
> +import java.util.Enumeration;
> +import java.util.Vector;
> +
> +import org.apache.tools.ant.BuildException;
> +import org.apache.tools.ant.DirectoryScanner;
> +import org.apache.tools.ant.Project;
> +import org.apache.tools.ant.Task;
> +import org.apache.tools.ant.types.FileSet;
> +import org.apache.tools.ant.types.Mapper;
> +import org.apache.tools.ant.types.optional.velocity.VelocityContext;
> +import org.apache.tools.ant.util.FileNameMapper;
> +import org.apache.tools.ant.util.FileUtils;
> +import org.apache.tools.ant.util.FlatFileNameMapper;
> +import org.apache.tools.ant.util.IdentityMapper;
> +import org.apache.velocity.app.Velocity;
> +import org.apache.velocity.context.Context;
> +
> +
> +/**
> + * Run velocity on a file or a fileset to a new file
> + * or directory.  Velocity is only run for a file which is newer
> + * than the destination file, or when the destination file does not
> + * exist.  It is possible to explicitly overwrite existing files.</p>
> + *
> + * <p>This task is supposed to be a richer version of filter function
> + * of copy task, and has similar attributes and nested elements.</p>
> + *
> + * @author <a href="mailto:hnakamur@v003.vaio.ne.jp">Hiroaki  
> Nakamura</a>
> + *
> + * @version $Revision$
> + */
> +public class VelocityTask extends Task {
> +    protected File templateBaseDir = null;
> +    protected File file = null; // the template file
> +    protected File destFile = null; // the destination file
> +    protected File destDir = null;  // the destination directory
> +    protected String encoding = System.getProperty("file.encoding");  
> // template and output file encoding
> +    protected File propertyFile = null; // the destination file
> +    protected VelocityContext velocityContext; // the  
> <velocitycontext> nested element
> +    protected Vector filesets = new Vector();
> +
> +    protected boolean forceOverwrite = false;
> +    private boolean failonerror = true;
> +
> +    protected boolean flatten = false;
> +    protected Mapper mapperElement = null;
> +
> +    private FileUtils fileUtils;
> +
> +    /**
> +     * Velocity task constructor.
> +     */
> +    public VelocityTask() {
> +        fileUtils = FileUtils.newFileUtils();
> +    }
> +
> +    protected FileUtils getFileUtils() {
> +        return fileUtils;
> +    }
> +
> +    /**
> +     * Sets template files base directory.
> +     */
> +    public void setTemplateBaseDir(File dir) {
> +        this.templateBaseDir = dir;
> +    }
> +
> +    /**
> +     * @return templatebasedir attribute value or project basedir if  
> templatebasedir is not set.
> +     */
> +    protected File getTemplateBaseDir() {
> +        return templateBaseDir == null
> +                ? project.getBaseDir() : templateBaseDir;
> +    }
> +
> +    /**
> +     * Sets a single source file to copy.
> +     */
> +    public void setFile(File file) {
> +        this.file = file;
> +    }
> +
> +    /**
> +     * Sets the destination file.
> +     */
> +    public void setTofile(File destFile) {
> +        this.destFile = destFile;
> +    }
> +
> +    /**
> +     * Sets the destination directory.
> +     */
> +    public void setTodir(File destDir) {
> +        this.destDir = destDir;
> +    }
> +
> +    /**
> +     * Sets the Velocity propertyfile.
> +     */
> +    public void setPropertyFile(File propertyFile) {
> +        this.propertyFile = propertyFile;
> +    }
> +
> +    /**
> +     * Sets the encoding.
> +     */
> +    public void setEncoding(String encoding) {
> +        this.encoding = encoding;
> +    }
> +
> +    /**
> +     * Create a nested velocitycontext element.
> +    */
> +    public VelocityContext createVelocityContext() throws  
> BuildException {
> +        if (velocityContext != null) {
> +            throw new BuildException("Cannot define more than one  
> velocitycontext",
> +                                     location);
> +        }
> +        velocityContext = new VelocityContext();
> +        return velocityContext;
> +    }
> +
> +    /**
> +     * Adds a set of files to copy.
> +     */
> +    public void addFileset(FileSet set) {
> +        filesets.addElement(set);
> +    }
> +
> +    /**
> +     * Overwrite any existing destination file(s).
> +     */
> +    public void setOverwrite(boolean overwrite) {
> +        this.forceOverwrite = overwrite;
> +    }
> +
> +    /**
> +     * If false, note errors to the output but keep going.
> +     * @param failonerror true or false
> +     */
> +     public void setFailOnError(boolean failonerror) {
> +         this.failonerror = failonerror;
> +     }
> +
> +    /**
> +     * When copying directory trees, the files can be "flattened"
> +     * into a single directory.  If there are multiple files with
> +     * the same name in the source directory tree, only the first
> +     * file will be copied into the "flattened" directory, unless
> +     * the forceoverwrite attribute is true.
> +     */
> +    public void setFlatten(boolean flatten) {
> +        this.flatten = flatten;
> +    }
> +
> +    /**
> +     * Defines the mapper to map source to destination files.
> +     */
> +    public Mapper createMapper() throws BuildException {
> +        if (mapperElement != null) {
> +            throw new BuildException("Cannot define more than one  
> mapper",
> +                                     location);
> +        }
> +        mapperElement = new Mapper(project);
> +        return mapperElement;
> +    }
> +
> +    /**
> +     * Performs the velocity template merge operation.
> +     */
> +    public void execute() throws BuildException {
> +        File savedFile = file; // may be altered in validateAttributes
> +        File savedDestFile = destFile;
> +        File savedDestDir = destDir;
> +        FileSet savedFileSet = null;
> +        if (file == null && destFile != null && filesets.size() == 1)  
> {
> +            // will be removed in validateAttributes
> +            savedFileSet = (FileSet) filesets.elementAt(0);
> +        }
> +
> +        validateAttributes();
> +
> +        try {
> +            initVelocity();
> +            Context ctx = createContext();
> +            File tmplBaseDir = getTemplateBaseDir();
> +
> +            if (file != null) {
> +                if (!file.exists()) {
> +                    String message = "Warning: Could not find  
> template file "
> +                        + file.getAbsolutePath() + ".";
> +                    if (!failonerror) {
> +                        log(message);
> +                    } else {
> +                        throw new BuildException(message);
> +                    }
> +                }
> +
> +                if (destFile == null) {
> +                    destFile = new File(destDir, file.getName());
> +                }
> +
> +                mergeTemplateUnlessUpToDate(
> +                    tmplBaseDir,
> +                    file,
> +                    ctx,
> +                    destFile);
> +            }
> +
> +            if (filesets != null) {
> +                FileNameMapper mapper = getFileNameMapper();
> +                for (Enumeration en = filesets.elements();  
> en.hasMoreElements();) {
> +                    FileSet fs = (FileSet) en.nextElement();
> +                    DirectoryScanner ds =  
> fs.getDirectoryScanner(project);
> +                    File dsBaseDir = ds.getBasedir();
> +                    String[] files = ds.getIncludedFiles();
> +                    for (int i = 0; i < files.length; i++) {
> +                        String srcRelativePath = files[i];
> +                        File srcFile = new File(dsBaseDir,  
> srcRelativePath);
> +                        String[] destRelativePaths =  
> mapper.mapFileName(srcRelativePath);
> +                        for (int j = 0; j < destRelativePaths.length;  
> j++) {
> +                            String destRelativePath =  
> destRelativePaths[j];
> +                            File curDestFile = new File(destDir,  
> destRelativePath);
> +                            mergeTemplateUnlessUpToDate(
> +                                tmplBaseDir,
> +                                srcFile,
> +                                ctx,
> +                                curDestFile);
> +                        }
> +                    }
> +                }
> +            }
> +        } finally {
> +            // clean up again, so this instance can be used a second
> +            // time
> +            file = savedFile;
> +            destFile = savedDestFile;
> +            destDir = savedDestDir;
> +            if (savedFileSet != null && filesets.size() == 0) {
> +                filesets.insertElementAt(savedFileSet, 0);
> +            }
> +        }
> +    }
> +
> +// 
> *********************************************************************** 
> *
> +//  protected and private methods
> +// 
> *********************************************************************** 
> *
> +
> +    /**
> +     * Ensure we have a consistent and legal set of attributes, and  
> set
> +     * any internal flags necessary based on different combinations
> +     * of attributes.
> +     */
> +    protected void validateAttributes() throws BuildException {
> +        if (file == null && filesets.size() == 0) {
> +            throw new BuildException("Specify at least one source "
> +                                     + "- a file or a fileset.");
> +        }
> +
> +        if (destFile != null && destDir != null) {
> +            throw new BuildException("Only one of tofile and todir "
> +                                     + "may be set.");
> +        }
> +
> +        if (destFile == null && destDir == null) {
> +            throw new BuildException("One of tofile or todir must be  
> set.");
> +        }
> +
> +        if (file != null && file.exists() && file.isDirectory()) {
> +            throw new BuildException("Use a fileset to copy  
> directories.");
> +        }
> +
> +        if (destFile != null && filesets.size() > 0) {
> +            if (filesets.size() > 1) {
> +                throw new BuildException(
> +                    "Cannot concatenate multiple files into a single  
> file.");
> +            } else {
> +                FileSet fs = (FileSet) filesets.elementAt(0);
> +                DirectoryScanner ds = fs.getDirectoryScanner(project);
> +                String[] srcFiles = ds.getIncludedFiles();
> +
> +                if (srcFiles.length == 0) {
> +                    throw new BuildException(
> +                        "Cannot perform operation from directory to  
> file.");
> +                } else if (srcFiles.length == 1) {
> +                    if (file == null) {
> +                        file = new File(ds.getBasedir(), srcFiles[0]);
> +                        filesets.removeElementAt(0);
> +                    } else {
> +                        throw new BuildException("Cannot concatenate  
> multiple "
> +                                                 + "files into a  
> single file.");
> +                    }
> +                } else {
> +                    throw new BuildException("Cannot concatenate  
> multiple "
> +                                             + "files into a single  
> file.");
> +                }
> +            }
> +        }
> +
> +        if (destFile != null) {
> +            destDir = fileUtils.getParentFile(destFile);
> +        }
> +
> +    }
> +
> +    /**
> +     * @return FileNameMapper instance
> +     */
> +    protected FileNameMapper getFileNameMapper() {
> +        FileNameMapper mapper = null;
> +        if (mapperElement != null) {
> +            mapper = mapperElement.getImplementation();
> +        } else if (flatten) {
> +            mapper = new FlatFileNameMapper();
> +        } else {
> +            mapper = new IdentityMapper();
> +        }
> +        return mapper;
> +    }
> +
> +    /**
> +     * Initializes Velocity.
> +     */
> +    protected void initVelocity() throws BuildException {
> +        if (propertyFile == null) {
> +            throw new BuildException("propertyfile must be set");
> +        }
> +        try {
> +            Velocity.init(propertyFile.getPath());
> +        } catch (Exception ex) {
> +            throw new BuildException(ex);
> +        }
> +    }
> +
> +    /**
> +     * Merge Velocity template file to the corresponding destination  
> file
> +     * if the destination file is older than the template file or  
> does not exist.
> +     */
> +    protected void mergeTemplateUnlessUpToDate(
> +        File templateBaseDir,
> +        File templateFile,
> +        Context ctx,
> +        File destFile)
> +        throws BuildException {
> +
> +        if (forceOverwrite ||
> +            (templateFile.lastModified() > destFile.lastModified())) {
> +            String templatePath = getRelativePath(templateFile,  
> templateBaseDir);
> +            mergeTemplate(templatePath, ctx, destFile);
> +        } else {
> +            log(templateFile + " omitted as " + destFile
> +                + " is up to date.", Project.MSG_VERBOSE);
> +        }
> +    }
> +
> +    /**
> +     * Merge Velocity template file to the corresponding destination  
> file.
> +     */
> +    protected void mergeTemplate(
> +        String templateRelativePath,
> +        Context ctx,
> +        File destFile)
> +        throws BuildException {
> +        try {
> +            File destDir = fileUtils.getParentFile(destFile);
> +            if (!destDir.exists()) {
> +                destDir.mkdirs();
> +            }
> +
> +            OutputStreamWriter osw = null;
> +            FileOutputStream fos = new FileOutputStream(destFile);
> +            try {
> +                osw = new OutputStreamWriter(fos, encoding);
> +                try {
> +                    Velocity.mergeTemplate(
> +                        templateRelativePath,
> +                        encoding,
> +                        ctx,
> +                        osw);
> +                } finally {
> +                    osw.close();
> +                    fos = null;
> +                }
> +            } finally {
> +                if (fos != null) {
> +                    fos.close();
> +                }
> +            }
> +        } catch (Exception ex) {
> +            throw new BuildException(ex);
> +        }
> +    }
> +
> +    /**
> +     * @return relative path of file from baseDir
> +     */
> +    protected String getRelativePath(File file, File baseDir) {
> +        int trimLen = baseDir.getAbsolutePath().length();
> +        if (!isRootDirectory(baseDir)) {
> +            trimLen++;
> +        }
> +        return file.getAbsolutePath().substring(trimLen);
> +    }
> +
> +    /**
> +     * @return whether dir is root directory or not.
> +     */
> +    protected boolean isRootDirectory(File dir) {
> +        return dir.getParent() == null;
> +    }
> +
> +    /**
> +     * @return Velocity context created.
> +     */
> +    protected Context createContext()
> +        throws BuildException {
> +        return velocityContext.createRealContext();
> +    }
> +}
> diff -ruN  
> jakarta-ant-1.5.1.orig/src/main/org/apache/tools/ant/types/optional/ 
> velocity/VelocityContext.java
> jakarta-ant-1.5.1/src/main/org/apache/tools/ant/types/optional/ 
> velocity/VelocityContext.java
> ---  
> jakarta-ant-1.5.1.orig/src/main/org/apache/tools/ant/types/optional/ 
> velocity/VelocityContext.java 1970-01-01 09:00:00.000000000
> +0900
> +++  
> jakarta-ant-1.5.1/src/main/org/apache/tools/ant/types/optional/ 
> velocity/VelocityContext.java 2003-01-20 11:00:10.000000000 +0900
> @@ -0,0 +1,258 @@
> +/*
> + * The Apache Software License, Version 1.1
> + *
> + * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
> + * reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + *
> + * 2. Redistributions in binary form must reproduce the above  
> copyright
> + *    notice, this list of conditions and the following disclaimer in
> + *    the documentation and/or other materials provided with the
> + *    distribution.
> + *
> + * 3. The end-user documentation included with the redistribution, if
> + *    any, must include the following acknowlegement:
> + *       "This product includes software developed by the
> + *        Apache Software Foundation (http://www.apache.org/)."
> + *    Alternately, this acknowlegement may appear in the software  
> itself,
> + *    if and wherever such third-party acknowlegements normally  
> appear.
> + *
> + * 4. The names "The Jakarta Project", "Ant", and "Apache Software
> + *    Foundation" must not be used to endorse or promote products  
> derived
> + *    from this software without prior written permission. For written
> + *    permission, please contact apache@apache.org.
> + *
> + * 5. Products derived from this software may not be called "Apache"
> + *    nor may "Apache" appear in their names without prior written
> + *    permission of the Apache Group.
> + *
> + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
> + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> + * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
> + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
> + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
> + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
> + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + *  
> ====================================================================
> + *
> + * This software consists of voluntary contributions made by many
> + * individuals on behalf of the Apache Software Foundation.  For more
> + * information on the Apache Software Foundation, please see
> + * <http://www.apache.org/>.
> + */
> +
> +package org.apache.tools.ant.types.optional.velocity;
> +
> +import java.lang.reflect.InvocationTargetException;
> +import java.lang.reflect.Method;
> +import java.util.Enumeration;
> +import java.util.Vector;
> +
> +import org.apache.tools.ant.BuildException;
> +import org.apache.tools.ant.Project;
> +import org.apache.tools.ant.types.DataType;
> +import org.apache.velocity.context.Context;
> +
> +/**
> + * A VelocityContext is a nested element of Velocity task.
> + * It has nested <code>&ltcontextdata&gt;</code> elements.
> + *
> + * @author <a href="mailto:hnakamur@v003.vaio.ne.jp">Hiroaki  
> Nakamura</a>
> + *
> + * @version $Revision$
> + */
> +public class VelocityContext extends DataType {
> +    private Vector contextData = new Vector();
> +
> +    /**
> +     * Creates the nested <code>&ltcontextdata&gt;</code> element.
> +     */
> +    public ContextData createContextData() throws BuildException {
> +        ContextData cd = new ContextData();
> +        contextData.addElement(cd);
> +        return cd;
> +    }
> +
> +    /**
> +     * @return real org.apache.velocity.VelocityContext specified by
> +     * <code>&ltvelocitycontext&gt;</code> element.
> +     */
> +    public Context createRealContext()
> +        throws BuildException {
> +        Context context = new org.apache.velocity.VelocityContext();
> +        populateContext(context);
> +        return context;
> +    }
> +
> +    /**
> +     * Populates org.apache.velocity.VelocityContext with data  
> specified by
> +     * nested <code>&ltcontextdata&gt;</code> elements.
> +     */
> +    protected void populateContext(Context context)
> +        throws BuildException {
> +        for (Enumeration en = contextData.elements();  
> en.hasMoreElements();) {
> +            Object o = en.nextElement();
> +            ContextData cd = (ContextData) o;
> +            cd.addIfValid(context);
> +        }
> +    }
> +
> +    /**
> +     * ContextData represents a nested  
> <code>&ltcontextdata&gt;</code> element.
> +     * The attribute <code>key</code> is necessary. One of attribute  
> <code>value</code>
> +     * or <code>className</code> is necessary. The attribute  
> <code>value</code>
> +     * is used to create immediate Context data. The attribute  
> <code>className</code>
> +     * is used to create a "tool" object which is later used from  
> template files.
> +     * The attribute <code>if</code> and <code>unless</code> are  
> optional, which
> +     * are used to control of enabling or disabling of a  
> <code>&ltcontextdata&gt;</code>
> +     * element.
> +     */
> +    public class ContextData {
> +        protected String key;
> +        protected String value;
> +        protected String ifCond;
> +        protected String className;
> +        protected String unlessCond;
> +
> +        /**
> +         * Sets the key.
> +         * @param name The key to set
> +         */
> +        public void setKey(String key) {
> +            this.key = key;
> +        }
> +
> +        /**
> +         * Sets the value.
> +         * @param value The value to set
> +         */
> +        public void setValue(String value) {
> +            this.value = value;
> +        }
> +
> +        /**
> +         * Sets the className.
> +         * @param className The className to set
> +         */
> +        public void setClassName(String className) {
> +            this.className = className;
> +        }
> +
> +        /**
> +         * Sets the ifCond.
> +         * @param ifCond The ifCond to set
> +         */
> +        public void setIf(String ifCond) {
> +            this.ifCond = ifCond;
> +        }
> +
> +        /**
> +         * Sets the unlessCond.
> +         * @param unlessCond The unlessCond to set
> +         */
> +        public void setUnless(String unlessCond) {
> +            this.unlessCond = unlessCond;
> +        }
> +
> +        /**
> +         * @return whether this element is valid or not
> +         */
> +        public boolean isValid() {
> +            Project p = getProject();
> +            if (ifCond != null && p.getProperty(ifCond) == null) {
> +                return false;
> +            } else if (unlessCond != null &&  
> p.getProperty(unlessCond) != null) {
> +                return false;
> +            }
> +            return true;
> +        }
> +
> +        /**
> +         * Add to a context if this element is valid.
> +         */
> +        public void addIfValid(Context context)
> +            throws BuildException {
> +            if (!isValid()) {
> +                return;
> +            }
> +
> +            if (key == null) {
> +                throw new BuildException("name must be set");
> +            }
> +
> +            if (value != null && className != null) {
> +                throw new BuildException("value and className cannot  
> both be set");
> +            } else if (value == null && className == null) {
> +                throw new BuildException("value or className must be  
> set");
> +            }
> +
> +            if (value != null) {
> +                context.put(key, value);
> +            } else if (className != null) {
> +                Object instance = createInstance(className);
> +                invokeSetContext(instance, context);
> +                context.put(key, instance);
> +            }
> +        }
> +
> +        /**
> +         * @return an instance of the specified class.
> +         */
> +        protected Object createInstance(String className)
> +            throws BuildException {
> +            try {
> +                return Class.forName(className).newInstance();
> +            } catch (ClassNotFoundException ex) {
> +                throw new BuildException(ex);
> +            } catch (IllegalAccessException ex) {
> +                throw new BuildException(ex);
> +            } catch (InstantiationException ex) {
> +                throw new BuildException(ex);
> +            }
> +        }
> +
> +        protected void invokeSetContext(Object instance, Context  
> context)
> +            throws BuildException {
> +            try {
> +                Class[] paramTypes = { Context.class };
> +                Method method =  
> instance.getClass().getMethod("setContext", paramTypes);
> +                Object[] args = { context };
> +                method.invoke(instance, args);
> +            } catch (NoSuchMethodException ex) {
> +                // ignore
> +            } catch (IllegalAccessException ex) {
> +                throw new BuildException(ex);
> +            } catch (InvocationTargetException ex) {
> +                throw new BuildException(ex);
> +            }
> +        }
> +
> +        /**
> +         * @return a string representation of an instance.
> +         */
> +        public String toString() {
> +            return "ContextVar[name="
> +                + key
> +                + ", value="
> +                + value
> +                + ", className="
> +                + className
> +                + ", if="
> +                + ifCond
> +                + ", unless="
> +                + unlessCond
> +                + "]";
> +        }
> +    }
> +}
>
>
>
> --
> To unsubscribe, e-mail:    
> <ma...@jakarta.apache.org>
> For additional commands, e-mail:  
> <ma...@jakarta.apache.org>
>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>