You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by si...@apache.org on 2002/04/03 11:10:03 UTC

cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

sidler      02/04/03 01:10:03

  Added:       tools    README.txt build.xml
               tools/lib jdbc2_0-stdext.jar servlet.jar struts.jar
                        velocity-tools-view-0.4.jar
               tools/src/conf MANIFEST.MF
               tools/src/java/org/apache/velocity/tools/tools DateTool.java
                        MathTool.java ParameterParser.java ToolLoader.java
                        package.html
               tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml
                        ToolLoader.xml
  Log:
  Added package tools. This is intended to host various reusable context
  tools. Currently hosted tools are DateTool, MathTool, RequestParser and
  ToolLoader. All tools are optimized to be used with an auto-loading toolbox
  manager and come with documentation for the template designers. A
  documentation snapshot is online at:
  http://www.teamup.com/jakarta-velocity-tools/docs/vellibrary.html
  
  Revision  Changes    Path
  1.1                  jakarta-velocity-tools/tools/README.txt
  
  Index: README.txt
  ===================================================================
  R E A D M E
  ===========
  
  This package contains a collection of general purpose context tools.
  Most tools are optimized for use with an automatic toolbox manager.
  
  
  Build and JAR
  -------------
  An ant script is provided to build and jar the package.
  
  > ant compile
  > ant jar
  
  
  Documentation
  -------------
  To generate the documentation for this package, call:
  
  > ant docs
  
  Then look for the generated documentation in the 'docs' subdirectory.
  
    
    
  Please send your feedback to velocity-user@jakarta.apache.org. 
  
  
  1.1                  jakarta-velocity-tools/tools/build.xml
  
  Index: build.xml
  ===================================================================
  
  <project name="velocity-tools-library" default="all" basedir=".">
  
  <!-- ========== Initialize Properties ===================================== -->
  
    <property file="build/build.properties"/>          <!-- Component local   -->
    <property file="../build.properties"/>             <!-- Commons local     -->
    <property file="${user.home}/.build.properties"/>  <!-- User local        -->
  
  <!-- ========== External Dependencies ===================================== -->
  
   <!-- the local repository -->
   <property name="local.repository"            value="./lib" />
   <property name="project.repository"          value="../lib" />
  
  <!-- ========== Component Declarations ==================================== -->
  
  
    <!-- The name of this component -->
    <property name="project.name"          value="velocity-tools-library" />
  
    <!-- The title of this component -->
    <property name="project.title"         value=""/>
  
    <!-- The current version number of this component -->
    <property name="project.version"       value="0.1"/>
  
    <!-- The current version number of this component -->
    <property name="project.date"          value="24-Mar-2002"/>
  
    <!-- The base directory for compilation targets -->
    <property name="build.home"            value="target"/>
  
    <!-- The base directory for distribution targets -->
    <property name="dist.home"             value="dist"/>
  
    <!-- The base directory for component sources -->
    <property name="source.home"           value="src"/>
  
    <!-- The base directory for component sources -->
    <property name="conf.home"             value="src/conf"/>
  
    <!-- The docs source directory -->
    <property name="docs.src"              value="xdocs"/>
  
    <!-- The docs destination directory  -->
    <property name="docs.dest"             value="docs"/>
  
    <!-- The docs destination directory  -->
    <property name="examples.home"         value="examples"/>
  
  <!-- ========== Compiler Defaults ========================================= -->
  
  
    <!-- Should Java compilations set the 'debug' compiler option? -->
    <property name="compile.debug"           value="true"/>
  
    <!-- Should Java compilations set the 'deprecation' compiler option? -->
    <property name="compile.deprecation"     value="true"/>
  
    <!-- Should Java compilations set the 'optimize' compiler option? -->
    <property name="compile.optimize"        value="true"/>
  
    <!-- Construct compile classpath -->
    <path id="classpath">
      <fileset dir="${local.repository}">
        <include name="**/*.jar"/>
      </fileset>
      <fileset dir="${project.repository}">
        <include name="**/*.jar"/>
      </fileset>
    </path>
  
  <!-- ========== Executable Targets ======================================== -->
  
  
    <!-- ================================================================== -->
    <!-- I N I T                                                            -->
    <!-- ================================================================== -->
    <target name="init"
     description="Initialize and evaluate conditionals">
      <echo message="-------- ${project.name} ${project.version} --------"/>
      <filter  token="name"                  value="${project.name}"/>
      <filter  token="version"               value="${project.version}"/>
    </target>
  
    <!-- ================================================================== -->
    <!-- P R E P A R E                                                      -->
    <!-- ================================================================== -->
    <target name="prepare" depends="init"
     description="Prepare build directory">
      <mkdir dir="${build.home}"/>
      <mkdir dir="${build.home}/classes"/>
      <mkdir dir="${build.home}/conf"/>
      <mkdir dir="${build.home}/javadoc"/>
    </target>
  
    <!-- ================================================================== -->
    <!-- S T A T I C                                                        -->
    <!-- ================================================================== -->
    <target name="static" depends="prepare"
     description="Copy static files to build directory">
      <tstamp/>
      <copy  todir="${build.home}/conf" filtering="on">
        <fileset dir="${conf.home}" includes="*.MF"/>
      </copy>
    </target>
  
    <!-- ================================================================== -->
    <!-- C O M P I L E                                                      -->
    <!-- ================================================================== -->
    <target name="compile" depends="static" description="Compile">
  
      <javac  srcdir="${source.home}/java"
              destdir="${build.home}/classes"
              debug="${compile.debug}"
              deprecation="${compile.deprecation}"
              optimize="${compile.optimize}">
          <classpath refid="classpath"/>
      </javac>
  
      <copy    todir="${build.home}/classes" filtering="on">
        <fileset dir="${source.home}/java" excludes="**/*.java"/>
      </copy>
  
    </target>
  
    <!-- ================================================================== -->
    <!-- C L E A N                                                          -->
    <!-- ================================================================== -->
    <target name="clean"
     description="Clean build and distribution directories">
      <delete    dir="${build.home}"/>
      <delete    dir="${dist.home}"/>
      <delete>
        <fileset dir="${basedir}" includes="*.jar"/>
      </delete>
      <delete>
        <fileset dir="${docs.dest}" includes="**/*.html"/>
      </delete>
      <delete    dir="${examples.home}/velstruts"/>
      <delete>
        <fileset dir="${examples.home}" includes="*.war"/>
      </delete>
      <delete>
        <fileset dir="${basedir}" includes="**/*.bak"/>
      </delete>
  
    </target>
  
  
    <!-- ================================================================== -->
    <!-- A L L                                                              -->
    <!-- ================================================================== -->
    <target name="all" depends="clean,jar,docs,javadocs"
     description="Clean and compile all components"/>
  
  
    <!-- ================================================================== -->
    <!-- J A V A D O C S                                                    -->
    <!-- ================================================================== -->
    <target name="javadocs" depends="compile"
     description="Create Javadoc documentation">
      <javadoc sourcepath="${source.home}/java"
                  destdir="${build.home}/javadoc"
             packagenames="org.apache.velocity.tools.struts.*"
                   author="true"
                  private="true"
                  version="true"
                 doctitle="&lt;h1&gt;${project.title}&lt;/h1&gt;"
              windowtitle="${project.title} (Version ${project.version})"
                   bottom="Copyright (c) 2002 Apache Software Foundation" >
  
        <classpath refid="classpath"/>
  
       </javadoc>
    </target>
  
  
    <!-- ================================================================== -->
    <!-- J A R                                                              -->
    <!-- ================================================================== -->
    <target name="jar" depends="compile">
      <jar    jarfile="${project.name}-${project.version}.jar"
              basedir="${build.home}/classes"
              manifest="${conf.home}/MANIFEST.MF"/>
    </target>
  
  
    <!-- ================================================================== -->
    <!-- D O C S                                                            -->
    <!-- ================================================================== -->
    <target name="docs">
  
        <taskdef name="dvsl" classname="org.apache.tools.dvsl.DVSLTask">
  
            <classpath>
               <path refid="classpath"/>
            </classpath>
  
        </taskdef>
  
        <dvsl
             basedir="${docs.src}"
             destdir="${docs.dest}/"
      	   toolboxfile="../xdocs/toolbox.props"
             extension=".html"
             style="../xdocs/site.dvsl"
             excludes="*menue.xml"
             includes="**/*.xml"
        />
  
        <replace dir="${docs.dest}">
            <replacefilter token="@@@version@@@" value="${project.version}"/>
            <replacefilter token="@@@date@@@" value="${project.date}"/>
        </replace>
  
  
    </target>
  
  
    <!-- ================================================================== -->
    <!-- I N S T A L L  J A R                                               -->
    <!-- ================================================================== -->
    <target name="install-jar" depends="jar"
            description="--> Installs .jar file in ${lib.repo}">
      <copy todir="${lib.repo}" filtering="no">
        <fileset dir="${basedir}">
          <include name="${project.name}-${project.version}.jar"/>
        </fileset>
      </copy>
    </target>
  
  
    <!-- ================================================================== -->
    <!--  D E P L O Y   J A R                                               -->
    <!-- ================================================================== -->
    <target name="deploy-jar" depends="compile, jar"
            description="Deploy jar to example applications">
      
      <delete>
          <fileset dir="${examples.home}/struts/WEB-INF/lib" includes="${project.name}-*.jar"/>
      </delete>
  
      <copy todir="${examples.home}/struts/WEB-INF/lib" filtering="no">
        <fileset dir="${basedir}">
          <include name="${project.name}-*.jar"/>
        </fileset>
      </copy>
    </target>
  
  
  </project>
  
  
  
  
  1.1                  jakarta-velocity-tools/tools/lib/jdbc2_0-stdext.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-velocity-tools/tools/lib/servlet.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-velocity-tools/tools/lib/struts.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-velocity-tools/tools/lib/velocity-tools-view-0.4.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-velocity-tools/tools/src/conf/MANIFEST.MF
  
  Index: MANIFEST.MF
  ===================================================================
  Extension-Name: @package@
  Specification-Vendor: Apache Software Foundation
  Specification-Version: 1.0
  Implementation-Vendor: Apache Software Foundation
  Implementation-Version: @version@
  
  
  
  1.1                  jakarta-velocity-tools/tools/src/java/org/apache/velocity/tools/tools/DateTool.java
  
  Index: DateTool.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 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", "Velocity", 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.velocity.tools.tools;
  
  
  import java.text.DateFormat;
  import java.text.SimpleDateFormat;
  import java.util.Date;
  import java.util.Calendar;
  import java.util.Locale;
  
  import org.apache.velocity.tools.view.tools.ThreadSafeContextTool;
  
  
  /**
   * <p>Tool for manipulating {@link Date} and {@link Calendar}
   * objects in Velocity templates.</p> 
   * 
   * <p>The tool is tread-safe and implements interface 
   * ThreadSafeContextTool. This allows a compatible toolbox 
   * manager like {@link org.apache.velocity.tools.view.servlet.ServletToolboxManager}
   * to automatically load the tool into the context and reuse
   * the same instance for the entire runtime.</p>
   *
   * @author <a href="mailto:sidler@teamup.com">Gabriel Sidler</a>
   * @author <a href="mailto:nathan@esha.com">Nathan Bubna</a>
   * @version $Revision: 1.1 $
   */
  
  public class DateTool implements ThreadSafeContextTool
  {
  
  
      /**
       * Default constructor.
       */
      public DateTool()
      {}
  
  
      /**
       * Returns a Date object. The default Locale is used.
       *
       * @return a <code>java.util.Date</code> object representing the time at 
       *    which this method was invoked
       */
      public static Date getDate()
      {
          return getDate();
      }
  
  
      /**
       * Returns a Date object representing the time at which this method was
       * invoked in the specified locale.
       *
       * @param locale the {@link java.util.Locale} to use to generate the Date
       *
       * @return a {@link java.util.Date} object representing the time at which 
       *     this method was invoked in the specified locale
       */
      public static Date getDate(Locale locale)
      {
          return getCalendar(locale).getTime();
      }
  
  
      /**
       * Returns a Calendar object representing the time at which this method was
       * invoked and in the default Locale.
       *
       * @return a {@link java.util.Calendar} object representing the time at which 
       *     this method was invoked using the default Locale
       */
      public static Calendar getCalendar()
      {
          return Calendar.getInstance();
      }
  
  
      /**
       * Returns a Calendar object representing the time at which this method was
       * invoked and in the specified locale.
       *
       * @param locale the {@link java.util.Locale} to use to create a Calendar
       * @return a {@link java.util.Calendar} object representing the time at which 
       *     this method was invoked and in the specified locale
       */
      public static Calendar getCalendar(Locale locale)
      {
          return Calendar.getInstance(locale);
      }
  
  
      /**
       * Returns a formatted string representing the specified date
       * in the default locale.
       *
       * <p>
       * This method uses the same formatting instructions as 
       * {@link SimpleDateFormat}:
       * <pre>
       *   Symbol   Meaning                 Presentation        Example
       *   ------   -------                 ------------        -------
       *   G        era designator          (Text)              AD
       *   y        year                    (Number)            1996
       *   M        month in year           (Text & Number)     July & 07
       *   d        day in month            (Number)            10
       *   h        hour in am/pm (1~12)    (Number)            12
       *   H        hour in day (0~23)      (Number)            0
       *   m        minute in hour          (Number)            30
       *   s        second in minute        (Number)            55
       *   S        millisecond             (Number)            978
       *   E        day in week             (Text)              Tuesday
       *   D        day in year             (Number)            189
       *   F        day of week in month    (Number)            2 (2nd Wed in July)
       *   w        week in year            (Number)            27
       *   W        week in month           (Number)            2
       *   a        am/pm marker            (Text)              PM
       *   k        hour in day (1~24)      (Number)            24
       *   K        hour in am/pm (0~11)    (Number)            0
       *   z        time zone               (Text)              Pacific Standard Time
       *   '        escape for text         (Delimiter)
       *   ''       single quote            (Literal)           '     
       *
       *   Examples: "E, MMMM d" will result in "Tue, July 24"
       *             "EEE, M-d (H:m)" will result in "Tuesday, 7-24 (14:12)"
       * </pre>
       *
       * @param format the formatting instructions
       * @param obj the date to format
       *
       * @return a formatted string representing the specified date or
       *     <code>null</code> if the parameters are invalid
       */
      public static String format(String format, Object obj)
      {
          Date date = toDate(obj);
          if (date == null || format == null)
          {
              return null;
          }
          SimpleDateFormat formatter = new SimpleDateFormat(format);
          return formatter.format(date);
      }
  
  
      /**
       * Returns a formatted string representing the specified date and locale.
       *
       * This method uses the same formatting instructions as 
       * {@link SimpleDateFormat}:
       *
       * @param format the formatting instructions
       * @param obj the date to format
       * @param locale the {@link java.util.Locale} to format the date for
       *
       * @return a formatted string representing the specified date or
       *         <code>null</code> if the parameters are invalid
       * @see #format
       */
      public static String format(String format, Object obj, Locale locale)
      {
          Date date = toDate(obj);
          if (date == null || format == null || locale == null)
          {
              return null;
          }
          SimpleDateFormat formatter = new SimpleDateFormat(format, locale);
          return formatter.format(date);
      }
  
  
  
      /**
       * Returns a Date object representing the specified date.
       *
       * @param obj the date to convert
       *
       * @return the converted date
       */
      public static Date toDate(Object obj)
      {
          if (obj == null)
          {
              return null;
          }
          if (obj instanceof Date)
          {
              return (Date)obj;
          }
          if (obj instanceof Calendar)
          {
              return ((Calendar)obj).getTime();
          }
          try
          {
              //try treating obj as a string and parsing it
              DateFormat format = DateFormat.getInstance();
              return format.parse(String.valueOf(obj));
          }
          catch (Exception e)
          {
              return null;
          }
      }
  
  
      /**
       * Returns a Calendar object representing the specified date.
       *
       * @param obj the date to convert
       *
       * @return the converted date
       */
      public static Calendar toCalendar(Object obj)
      {
          if (obj == null)
          {
              return null;
          }
          if (obj instanceof Calendar)
          {
              return (Calendar)obj;
          }
          //try to get a date out of it
          Date date = toDate(obj);
          if (date == null)
          {
              return null;
          }
          
          //convert the date to a calendar
          Calendar cal = Calendar.getInstance();
          cal.setTime(date);
          //Force fields to update.
          cal.getTime();
          return cal;
      }
  
  
  }
  
  
  
  
  1.1                  jakarta-velocity-tools/tools/src/java/org/apache/velocity/tools/tools/MathTool.java
  
  Index: MathTool.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 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", "Velocity", 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.velocity.tools.tools;
  
  import org.apache.velocity.tools.view.tools.ThreadSafeContextTool;
  import java.lang.Math;
  
  
  /**
   * <p>Tool for performing floating point math in Velocity.</p>
   *
   * <p>Several things should be noted here:</p>
   *
   * <ol>
   * <li>This class does not have methods that take
   * primitives.  This is simply because Velocity
   * wraps all primitives for us automagically.</li>
   *
   * <li>Most methods return {@link Double} wrappers
   * which automatically render the decimal places even
   * for whole numbers (e.g. new Double(1).toString() -> '1.0')
   * This is intentional.  This tool is for floating 
   * point arithmetic.  Integer arithmetic is already supported
   * in Velocity syntax.  if you really need '1' instead of '1.0',
   * just call intValue() on the result.</li>
   *
   * <li>No null pointer, number format, or divide by zero
   * exceptions are thrown here.  This is because such exceptions
   * thrown in template halt rendering.  It should be sufficient
   * debugging feedback that Velocity will render the reference
   * literally. (e.g. $math.div(1, 0) renders as '$math.div(1, 0)')</li>
   * </ul>
   * 
   * @author <a href="mailto:nathan@esha.com">Nathan Bubna</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/03 09:10:03 $
   */
  
  public class MathTool implements ThreadSafeContextTool
  {
      /**
       * @param num1 the first number
       * @param num2 the second number
       * @return the sum of the numbers or 
       *         <code>null</code> if they're invalid
       * @see #toDouble
       */
      public static Double add(Object num1, Object num2)
      {
          Double d1 = toDouble(num1);
          Double d2 = toDouble(num2);
          if (d1 == null || d2 == null)
          {
              return null;
          }
          return new Double(d1.doubleValue() + d2.doubleValue());
      }
  
  
      /**
       * @param num1 the first number
       * @param num2 the second number
       * @return the difference of the numbers or 
       *         <code>null</code> if they're invalid
       * @see #toDouble
       */
      public static Double sub(Object num1, Object num2)
      {
          Double d1 = toDouble(num1);
          Double d2 = toDouble(num2);
          if (d1 == null || d2 == null)
          {
              return null;
          }
          return new Double(d1.doubleValue() - d2.doubleValue());
      }
  
  
      /**
       * @param num1 the first number
       * @param num2 the second number
       * @return the product of the numbers or 
       *         <code>null</code> if they're invalid
       * @see #toDouble
       */
      public static Double mul(Object num1, Object num2)
      {
          Double d1 = toDouble(num1);
          Double d2 = toDouble(num2);
          if (d1 == null || d2 == null)
          {
              return null;
          }
          return new Double(d1.doubleValue() * d2.doubleValue());
      }
  
  
      /**
       * @param num1 the first number
       * @param num2 the second number
       * @return the quotient of the numbers or 
       *         <code>null</code> if they're invalid
       * @see #toDouble
       */
      public static Double div(Object num1, Object num2)
      {
          Double d1 = toDouble(num1);
          Double d2 = toDouble(num2);
          if (d1 == null || d2 == null || d2.doubleValue() == 0.0)
          {
              return null;
          }
          return new Double(d1.doubleValue() / d2.doubleValue());
      }
  
  
      /**
       * @param num1 the first number
       * @param num2 the second number
       * @return the first number raised to the power of the
       *         second or <code>null</code> if they're invalid
       * @see #toDouble
       */
      public static Double pow(Object num1, Object num2)
      {
          Double d1 = toDouble(num1);
          Double d2 = toDouble(num2);
          if (d1 == null || d2 == null)
          {
              return null;
          }
          return new Double(Math.pow(d1.doubleValue(), d2.doubleValue()));
      }
  
  
      /**
       * @param num1 the first number
       * @param num2 the second number
       * @return the largest of the numbers or 
       *         <code>null</code> if they're invalid
       * @see #toDouble
       */
      public static Double max(Object num1, Object num2)
      {
          Double d1 = toDouble(num1);
          Double d2 = toDouble(num2);
          if (d1 == null || d2 == null)
          {
              return null;
          }
          return new Double(Math.max(d1.doubleValue(), d2.doubleValue()));
      }
  
  
      /**
       * @param num1 the first number
       * @param num2 the second number
       * @return the smallest of the numbers or 
       *         <code>null</code> if they're invalid
       * @see #toDouble
       */
      public static Double min(Object num1, Object num2)
      {
          Double d1 = toDouble(num1);
          Double d2 = toDouble(num2);
          if (d1 == null || d2 == null)
          {
              return null;
          }
          return new Double(Math.min(d1.doubleValue(), d2.doubleValue()));
      }
  
  
      /**
       * @param num1 the number
       * @return the absolute value of the number 
       *         <code>null</code> if it's invalid
       * @see #toDouble
       */
      public static Double abs(Object num)
      {
          Double d = toDouble(num);
          if (d == null)
          {
              return null;
          }
          return new Double(Math.abs(d.doubleValue()));
      }
  
  
      /**
       * Converts an object with a numeric value into a Double
       * Valid formats are {@link Number} or a {@link String}
       * representation of a number
       *
       * @param num the number to be converted
       * @return a {@link Double} representation of the number
       *         or <code>null</code> if it's invalid
       */
      public static Double toDouble(Object num)
      {
          double value;
          try
          {
              if (num instanceof Number)
              {
                  value = ((Number)num).doubleValue();
              }
              else
              {
                  value = Double.parseDouble(String.valueOf(num));
              }
          }
          catch (NumberFormatException nfe)
          {
              return null;
          }
          return new Double(value);
      }
  
  
      /**
       * Converts an object with a numeric value into an Integer
       * Valid formats are {@link Number} or a {@link String}
       * representation of a number
       *
       * @param num the number to be converted
       * @return a {@link Integer} representation of the number
       *         or <code>null</code> if it's invalid
       */
      public static Integer toInteger(Object num)
      {
          Double d = toDouble(num);
          if (d == null)
          {
              return null;
          }
          return new Integer(d.intValue());
      }
  
  
      /**
       * Rounds a number to the specified number of decimal places.
       * This is particulary useful for simple display formatting.
       * If you want to round an number to the nearest integer, it
       * is better to use {@link #roundToInt}, as that will return
       * an {@link Integer} rather than a {@link Double}.
       *
       * @param decimals the number of decimal places
       * @param value the number to round
       * @return the value rounded to the specified number of
       *         decimal places or <code>null</code> if it's invalid
       * @see #toDouble
       * @see #toInteger
       */
      public static Double roundTo(Object decimals, Object num)
      {
          Integer i = toInteger(decimals);
          Double d = toDouble(num);
          if (i == null || d == null)
          {
              return null;
          }
          //ok, go ahead and do the rounding
          int places = i.intValue();
          double value = d.doubleValue();
          if (places == 0)
          {
              value = (int)(value + .5);
          }
          else
          {
              double shift = Math.pow(10, places);
              value = value * shift;
              value = (int)(value + .5);
              value = value / shift;
          }
          return new Double(value);
      }
  
  
      /**
       * Rounds a number to the nearest whole Integer
       *
       * @param num the number to round
       * @return the number rounded to the nearest whole Integer
       *         or <code>null</code> if it's invalid
       * @see #toDouble
       */
      public static Integer roundToInt(Object num)
      {
          Double d = toDouble(num);
          if (d == null)
          {
              return null;
          }
          return new Integer((int)Math.rint(d.doubleValue()));
      }
  
  
      /**
       * @returns a pseudo-random {@link Double} greater 
       *          than or equal to 0.0 and less than 1.0
       * @see Math#random()
       */
      public static Double getRandom()
      {
          return new Double(Math.random());
      }
  
  
      /**
       * This returns a random {@link Integer} within the
       * specified range.  The return Integer will have a
       * value greater than or equal to the first number
       * and less than the second number.
       *
       * @param num1 the first number
       * @param num2 the second number
       * @return a pseudo-random {@link Integer} greater than
       *         or equal to the first number and less than
       *         the second
       * @see #toInteger
       * @see Math#random()
       */
      public static Integer random(Object num1, Object num2)
      {
          Integer i1 = toInteger(num1);
          Integer i2 = toInteger(num2);
          if (i1 == null || i2 == null)
          {
              return null;
          }
          //get the difference
          double diff = i2.intValue() - i1.intValue();
          //multiply the difference by a pseudo-random 
          //double from 0.0 to 1.0 and round to the nearest int
          int random = (int)Math.rint(diff * Math.random());
          //add the first value to the random int and return as an Integer
          return new Integer(random + i1.intValue());
      }
  
  
  }
  
  
  
  1.1                  jakarta-velocity-tools/tools/src/java/org/apache/velocity/tools/tools/ParameterParser.java
  
  Index: ParameterParser.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 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", "Velocity", 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.velocity.tools.tools;
  
  import org.apache.velocity.tools.view.tools.ThreadSafeContextTool;
  import javax.servlet.ServletRequest;
  
  
  /**
   * Utility class for easy parsing of {@link ServletRequest} parameters
   *
   * @author <a href="mailto:sidler@teamup.com">Gabriel Sidler</a>
   * @author <a href="mailto:nathan@esha.com">Nathan Bubna</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/03 09:10:03 $
   */
  
  public class ParameterParser implements ThreadSafeContextTool
  {
  
      /**
       * Constructs a new instance
       */
      public ParameterParser()
      {}
  
  
      /**
       * @param request the servlet request
       * @param key the parameter's key
       * @return parameter matching the specified key or
       *         <code>null</code> if there is no matching
       *         parameter
       */
      public static String getString(ServletRequest request, String key)
      {
          return request.getParameter(key);
      }
  
  
      /**
       * @param request the servlet request
       * @param the desired parameter's key
       * @param the alternate value
       * @return parameter matching the specified key or the 
       *         specified alternate String if there is no matching
       *         parameter
       */
      public static String getString(ServletRequest request, String key, String alternate)
      {
          String s = getString(request, key);
          return (s != null) ? s : alternate;
      }
  
  
      /**
       * @param request the servlet request
       * @param the desired parameter's key
       * @return a {@link Boolean} object for the specified key or 
       *         <code>null</code> if no matching parameter is found
       */
      public static Boolean getBoolean(ServletRequest request, String key)
      {
          String s = getString(request, key);
          return (s != null) ? Boolean.valueOf(s) : null;
      }
  
  
      /**
       * @param request the servlet request
       * @param the desired parameter's key
       * @param the alternate boolean value
       * @return boolean value for the specified key or the 
       *         alternate boolean is no value is found
       */
      public static boolean getBoolean(ServletRequest request, String key, boolean alternate)
      {
          Boolean bool = getBoolean(request, key);
          return (bool != null) ? bool.booleanValue() : alternate;
      }
  
  
      /**
       * @param request the servlet request
       * @param the desired parameter's key
       * @param the alternate {@link Boolean}
       * @return a {@link Boolean} for the specified key or the specified
       *         alternate if no matching parameter is found
       */
      public static Boolean getBoolean(ServletRequest request, String key, Boolean alternate)
      {
          Boolean bool = getBoolean(request, key);
          return (bool != null) ? bool : alternate;
      }
  
  
      /**
       * @param request the servlet request
       * @param the desired parameter's key
       * @return a {@link Number} for the specified key or 
       *         <code>null</code> if no matching parameter is found
       */
      public static Number getNumber(ServletRequest request, String key)
      {
          String s = getString(request, key);
          if (s == null || s.length() == 0)
          {
              return null;
          }
          if (s.indexOf('.') >= 0)
          {
              return new Double(s);
          }
          return new Long(s);
      }
  
  
      /**
       * @param request the servlet request
       * @param the desired parameter's key
       * @param the alternate Number
       * @return a Number for the specified key or the specified
       *         alternate if no matching parameter is found
       */
      public static Number getNumber(ServletRequest request, String key, Number alternate)
      {
          Number n = getNumber(request, key);
          return (n != null) ? n : alternate;
      }
  
  
      /**
       * @param request the servlet request
       * @param the desired parameter's key
       * @param the alternate int value
       * @return the int value for the specified key or the specified
       *         alternate value if no matching parameter is found
       */
      public static int getInt(ServletRequest request, String key, int alternate)
      {
          Number n = getNumber(request, key);
          return (n != null) ? n.intValue() : alternate;
      }
  
  
      /**
       * @param request the servlet request
       * @param the desired parameter's key
       * @param the alternate double value
       * @return the double value for the specified key or the specified
       *         alternate value if no matching parameter is found
       */
      public static double getDouble(ServletRequest request, String key, double alternate)
      {
          Number n = getNumber(request, key);
          return (n != null) ? n.doubleValue() : alternate;
      }
  
  
      /**
       * @param request the servlet request
       * @param the key for the desired parameter
       * @return an array of String objects containing all of the values
       *         the given request parameter has, or <code>null</code>
       *         if the parameter does not exist
       */
      public static String[] getStrings(ServletRequest request, String key)
      {
          return request.getParameterValues(key);
      }
  
  
      /**
       * @param request the servlet request
       * @param the key for the desired parameter
       * @return an array of Number objects for the specified key or 
       *         <code>null</code> if the parameter does not exist or the
       *         parameter does not contain Numbers.
       */
      public static Number[] getNumbers(ServletRequest request, String key)
      {
          String[] strings = getStrings(request, key);
          if (strings == null)
          {
              return null;
          }
          
          Number[] nums = new Number[strings.length];
          try
          {
              for(int i=0; i<nums.length; i++)
              {
                  if (strings[i] != null && strings[i].length() > 0)
                  {
                      if (strings[i].indexOf('.') >= 0)
                      {
                          nums[i] = new Double(strings[i]);
                      }
                      else
                      {
                          nums[i] = new Long(strings[i]);
                      }
                  }
              }
          }
          catch (NumberFormatException nfe)
          {
              return null;
          }
          return nums;
      }
  
  
      /**
       * @param request the servlet request
       * @param the key for the desired parameter
       * @return an array of int values for the specified key or 
       *         <code>null</code> if the parameter does not exist or the
       *         parameter does not contain ints.
       */
      public static int[] getInts(ServletRequest request, String key)
      {
          String[] strings = getStrings(request, key);
          if (strings == null)
          {
              return null;
          }
          
          int[] ints = new int[strings.length];
          try
          {
              for(int i=0; i<ints.length; i++)
              {
                  if (strings[i] != null && strings[i].length() > 0)
                  {
                      ints[i] = Integer.parseInt(strings[i]);
                  }
              }
          }
          catch (NumberFormatException nfe)
          {
              return null;
          }
          return ints;
      }
  
  
      /**
       * @param request the servlet request
       * @param the key for the desired parameter
       * @return an array of double values for the specified key or 
       *         <code>null</code> if the parameter does not exist or the
       *         parameter does not contain doubles.
       */
      public static double[] getDoubles(ServletRequest request, String key)
      {
          String[] strings = getStrings(request, key);
          if (strings == null)
          {
              return null;
          }
          
          double[] doubles = new double[strings.length];
          try
          {
              for(int i=0; i<doubles.length; i++)
              {
                  if (strings[i] != null && strings[i].length() > 0)
                  {
                      doubles[i] = Double.parseDouble(strings[i]);
                  }
              }
          }
          catch (NumberFormatException nfe)
          {
              return null;
          }
          return doubles;
      }
  
  
  }
  
  
  1.1                  jakarta-velocity-tools/tools/src/java/org/apache/velocity/tools/tools/ToolLoader.java
  
  Index: ToolLoader.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 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", "Velocity", 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.velocity.tools.tools;
  
  import org.apache.velocity.tools.view.context.ViewContext;
  import org.apache.velocity.tools.view.tools.ContextContextTool;
  import org.apache.velocity.tools.view.tools.LogEnabledContextToolImpl;
  import org.apache.velocity.context.Context;
  
  
  /**
   * <p>A context tool that allows template designers to load
   * other context tools from within the template. Any object
   * with a public constructor without parameters can be used
   * as a context tool.</p>
   *
   * <p>Example: Assuming that an instance of this class has
   * been loaded into the Velocity context under key "toolloader",
   * then from within a template a designer would call:<br>
   * <br>
   * <code>$toolloader.load("math", "xxx.yyy.zzz.MathTool")</code><br>
   * <br>
   * to load a math tool into the context under key "math". This tool
   * is then available for use within the template, for example:<br>
   * <br>
   * <code>$math.random(1, 100)</code><br>
   * </p>
   *
   * <p>THIS CLASS IS HERE AS A PROOF OF CONCEPT ONLY. IT NEEDS TO BE
   * REFACTORED.</p>
   * 
   * @author <a href="mailto:sidler@teamup.com">Gabe Sidler</a>
   * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
   *
   * @version $Id: ToolLoader.java,v 1.1 2002/04/03 09:10:03 sidler Exp $
   * 
   */
  
  public class ToolLoader extends LogEnabledContextToolImpl 
      implements ContextContextTool
  {
  
      // -------------------------------------------- Properties ----------------
  
      /**
       * <p>A reference to the Velocity context.</p>
       */
      private Context ctx;
      
  
      
      // -------------------------------------------- Constructors --------------
      
      /**
       * Returns a factory for instances of this class. Use method 
       * {@link #getInstance(Context context)} to obtain instances 
       * of this class. Do not use instance obtained from this method
       * in templates. They are not properly initialized.
       */
      public ToolLoader()
      {
      }
  
      
      /**
       * Contructor for internal use only. 
       */
      private ToolLoader(Context context)
      {
          this.ctx = context;
      }
  
      
  
      // --------------------------------------- Interface ContextContextTool ---
      
      /**
       * Returns an initialized instance of this context tool.
       */
      public Object getInstance(Context context)
      {
          return new ToolLoader(context);
      }
  
  
  
      // -------------------------------------------- Public Utility Methods ----
  
      /**
       * <p>Loads a context tool of class <i>clazz</i> and inserts it
       * into the Velocity context with key <i>key</i>. On order to be
       * loadable, context tools must provide a constructor with no 
       * parameters. The life cycle of a context tool loaded using
       * this method is the current request.</p>
       *
       * @param key the key used to add the tool to the context
       * @param clazz the fully qualified class name of the tool that
       *     is to be instantiated and added to the context
       */
      public void load(String key, String clazz)
      {
          try
          {
              Object tool = Class.forName(clazz).newInstance();
              ctx.put(key, tool);
              log(INFO, "Loaded tool: Key: " + key + " Class: " + clazz);
          }
          catch (Exception e)
          {
              log(ERROR, "Error loading context tool: " + clazz + " with key: " + key + ". " + e);            
          }
      }
  
  }
  
  
  
  1.1                  jakarta-velocity-tools/tools/src/java/org/apache/velocity/tools/tools/package.html
  
  Index: package.html
  ===================================================================
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
  <html>
  <head>
  <!--
  
    These are Javadoc package comments.
    
  -->
  </head>
  <body bgcolor="white">
  
  Contains a collection of reusable, general-purpose Velocity context tools. Where applicable
  tools are optimized to be used in conjunction with a toolbox manager.
  
  <!--
  ##### THIS IS THE TEMPLATE FOR THE PACKAGE DOC COMMENTS. #####
  ##### TYPE YOUR PACKAGE COMMENTS HERE.  BEGIN WITH A     #####
  ##### ONE-SENTENCE SUMMARY STARTING WITH A VERB LIKE:    #####
  Provides for.... 
  -->
  
  <h2>Package Specification</h2>
  
  <!--
  ##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT #####
  <ul>
    <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a>
  </ul>
  -->
  
  <h2>Related Documentation</h2>
  
  <!--
  For overviews, tutorials, examples, guides, and tool documentation, please see:
  <ul>
    <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a>
  </ul>
  -->
  
  <!-- Put @see and @since tags down here. -->
  
  </body>
  </html>
  
  
  
  1.1                  jakarta-velocity-tools/tools/xdocs/DateTool.xml
  
  Index: DateTool.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
  
      <properties>
          <title>DateTool</title>
          <author email="sidler@apache.org">Gabriel Sidler</author>
          <projectfile>../xdocs/vellibrary-menue.xml</projectfile>
      </properties>
  
      <body>
  
      <section name="DateTool Reference Documentation">
  
          <p>
          Tool for manipulating <code>java.util.Date</code> and <code>java.util.Calendar</code> 
          objects in Velocity templates. It supports locales to format dates language
          and country specific.
          </p>
          
          <toolinfo>
              <version>@@@version@@@, @@@date@@@</version>
  
              <jar>velocity-tools-library-@@@version@@@.jar</jar>
  
              <clazz>org.apache.velocity.tools.tools.DateTool</clazz>
  
              <name>$dateTool</name>
  
              <author email="sidler@apache.org">Gabriel Sidler</author>
              <author email="nathan@esha.com">Nathan Bubna</author>
  
              <config-example>&lt;tool&gt;
    &lt;key&gt;dateTool&lt;/key&gt;
    &lt;class&gt;org.apache.velocity.tools.tools.DateTool&lt;/class&gt;
  &lt;/tool&gt;</config-example>
  
          </toolinfo>
  
          <methods/>
  
      </section>
  
      <section name="getDate()">
          <method name="getDate()">
      
              <abstract>
                  Returns a Date object representing the time at which this 
                  method was invoked.
              </abstract>
      
              <signature>
                  String getDate()
              </signature>
              
              <signature>
                  String getDate(Locale locale)
              </signature>
              
              <parameters>
                  <parameter name="locale">
                      An object of class <code>java.util.Locale</code> that represents the locale
                      to be used to create the date.
                  </parameter>
              </parameters>
                      
              <returns>
                  An object of class <code>java.util.Date</code> representing the time at which this 
                  method was invoked in the specified locale. If no locale is specified,
                  the system's default locale is used.
              </returns>
                  
          </method>
      </section>
  
  
      <section name="getCalendar()">
          <method name="getCalendar()">
      
              <abstract>
                  Returns a Calendar object representing the time at which this 
                  method was invoked.
              </abstract>
      
              <signature>
                  String getCalendar()
              </signature>
              
              <signature>
                  String getCalendar(Locale locale)
              </signature>
              
              <parameters>
                  <parameter name="locale">
                      An object of class <code>java.util.Locale</code> that represents the locale
                      to be used to create the calendar.
                  </parameter>
              </parameters>
                      
              <returns>
                  An object of class <code>java.util.Calendar</code> representing the time at which this 
                  method was invoked in the specified locale. If no locale is specified,
                  the system's default locale is used.
              </returns>
                  
          </method>
      </section>
  
  
      <section name="format()">
          <method name="format()">
      
              <abstract>
                  Returns a formatted string representing the specified date.
              </abstract>
      
              <signature>
                  String format(String format, Object obj)
              </signature>
              
              <signature>
                  String format(String format, Object obj, Locale locale)
              </signature>
              
              <parameters>
                  <parameter name="format">
                      A string that represents the formatting instructions according to
                      <code>java.text.SimpleDateFormat</code>. See also below.
                  </parameter>
                  
                  <parameter name="obj">
                      An object of class <code>java.util.Date</code> or <code>java.util.Calendar</code>. It is
                      also possible to pass a string that represents a parsable date
                      according to <code>java.text.DateFormat</code>.
                  </parameter>
                  
                  <parameter name="locale">
                      An object of class <code>java.util.Locale</code> that represents the locale
                      to format the date for.
                  </parameter>
              </parameters>
      
              <returns>
                  The formatted date string in the specified locale or <code>null</code> 
                  if one or several input parameters are invalid. If no locale is specified,
                  the system's default locale is used instead.
              </returns>
      
              <description>
                  <p>This methods use the same formatting instructions as class 
                  <code>java.text.SimpleDateFormat</code>.</p>
                  
  <sourcecode>
  Symbol   Meaning                 Presentation        Example
  ------   -------                 ------------        -------
  G        era designator          (Text)              AD
  y        year                    (Number)            1996
  M        month in year           (Text &amp; Number)     July &amp; 07
  d        day in month            (Number)            10
  h        hour in am/pm (1~12)    (Number)            12
  H        hour in day (0~23)      (Number)            0
  m        minute in hour          (Number)            30
  s        second in minute        (Number)            55
  S        millisecond             (Number)            978
  E        day in week             (Text)              Tuesday
  D        day in year             (Number)            189
  F        day of week in month    (Number)            2 (2nd Wed in July)
  w        week in year            (Number)            27
  W        week in month           (Number)            2
  a        am/pm marker            (Text)              PM
  k        hour in day (1~24)      (Number)            24
  K        hour in am/pm (0~11)    (Number)            0
  z        time zone               (Text)              Pacific Standard Time
  '        escape for text         (Delimiter)
  ''       single quote            (Literal)           '     
  
  Examples: "E, MMMM d" will result in "Tue, July 24"
            "EEE, M-d (H:m)" will result in "Tuesday, 7-24 (14:12)"
  </sourcecode>
              
              </description>
      
          </method>
      </section>
  
  
  
      <section name="toDate()">
          <method name="toDate()">
      
              <abstract>
                  Returns a Date object representing the specified date.
              </abstract>
      
              <signature>
                  Date toDate(Object obj)
              </signature>
              
              <parameters>
                  <parameter name="obj">
                      The date to convert. The parameter can be an object of class 
                      <code>java.util.Date</code> or <code>java.util.Calendar</code>. It is also possible to 
                      pass a string that represents a parsable date according to 
                      <code>java.text.DateFormat</code>.
                  </parameter>
              </parameters>
                      
              <returns>
                  An object of class <code>java.util.Date</code> representing the converted date 
                  or <null></null> of the input parameter is invalid.
              </returns>
         
          </method>
      </section>
  
  
      <section name="toCalendar()">
          <method name="toCalendar()">
      
              <abstract>
                  Returns a Calendar object representing the specified date.
              </abstract>
      
              <signature>
                  Calendar toCalendar(Object obj)
              </signature>
              
              <parameters>
                  <parameter name="obj">
                      The date to convert. The parameter can be an object of class 
                      <code>java.util.Date</code> or <code>java.util.Calendar</code>. It is also possible to 
                      pass a string that represents a parsable date according to 
                      <code>java.text.DateFormat</code>.
                  </parameter>
               </parameters>
                      
              <returns>
                  An object of class <code>java.util.Calendar</code> representing the converted date 
                  or <null></null> of the input parameter is invalid.
              </returns>
         
          </method>
      </section>
  
  
  
   </body>
  </document>
  
  
  
  
  1.1                  jakarta-velocity-tools/tools/xdocs/MathTool.xml
  
  Index: MathTool.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
  
      <properties>
          <title>MathTool</title>
          <author email="sidler@apache.org">Gabriel Sidler</author>
          <projectfile>../xdocs/vellibrary-menue.xml</projectfile>
      </properties>
  
      <body>
  
      <section name="MathTool Reference Documentation">
  
          <p>Tool for performing floating point math in Velocity.</p>
  
          <p>A few things to note:</p>
          
          <ul>
              <li>Most methods return numbers wrapped as Double
                  which automatically render the decimal places even
                  for whole numbers (e.g. new Double(1).toString() -> '1.0'). 
                  This is intentional. This tool is for floating 
                  point arithmetic. Integer arithmetic is already supported
                  by the Velocity template language. If you really need '1' 
                  instead of '1.0', just call intValue() on the result.</li> 
              <li>No null pointer, number format, or divide by zero
                  exceptions are thrown here. This is because such exceptions
                  halt template rendering. It should be sufficient debugging 
                  feedback that Velocity will render the reference
                  literally. (e.g. $math.div(1, 0) renders as '$math.div(1, 0)')</li>
              <li>Class <code>java.lang.Math</code> is used to perform the
                  mathematical operations.</li>
          </ul>    
          
          <toolinfo>
              <version>@@@version@@@, @@@date@@@</version>
              <jar>velocity-tools-library-@@@version@@@.jar</jar>
              <clazz>org.apache.velocity.tools.tools.MathTool</clazz>
              <name>$math</name>
              <author email="nathan@esha.com">Nathan Bubna</author>
              <config-example>&lt;tool&gt;
    &lt;key&gt;math&lt;/key&gt;
    &lt;class&gt;org.apache.velocity.tools.tools.MathTool&lt;/class&gt;
  &lt;/tool&gt;</config-example>
          </toolinfo>
  
          <methods/>
  
      </section>
  
      <section name="add()">
          <method name="add()">
      
              <abstract>
                  Addition
              </abstract>
                  
              <signature>
                  Double add(Object num1, Object num2)
              </signature>
  
              <parameters>
                  <parameter name="num1, num2">
                      Operands of the addition. Valid input is any number (primitive
                      types or objects, Velocity automatically converts primitives types 
                      to objects) or a string representation of a number.
                  </parameter>
              </parameters>
      
              <returns>
                  A <code>java.lang.Double</code> representing the sum or <code>null</code> if the input
                  paramters are not valid.
              </returns>
      
          </method>
      </section>
  
  
      <section name="sub()">
          <method name="sub()">
      
              <abstract>
                  Subtraction
              </abstract>
                  
              <signature>
                  Double sub(Object num1, Object num2)
              </signature>
  
              <parameters>
                  <parameter name="num1, num2">
                      Operands of the subtraction. Valid input is any number (primitive
                      types or objects, Velocity automatically converts primitives types 
                      to objects) or a string representation of a number.
                  </parameter>
              </parameters>
      
              <returns>
                  A <code>java.lang.Double</code> representing the result of the subtraction
                  or <code>null</code> if the input paramters are not valid.
              </returns>
      
          </method>
      </section>
  
  
      <section name="mul()">
          <method name="mul()">
      
              <abstract>
                  Multiplication
              </abstract>
                  
              <signature>
                  Double mul(Object num1, Object num2)
              </signature>
  
              <parameters>
                  <parameter name="num1, num2">
                      Factors of the multiplication. Valid input is any number (primitive
                      types or objects, Velocity automatically converts primitives types 
                      to objects) or a string representation of a number.
                  </parameter>
              </parameters>
      
              <returns>
                  A <code>java.lang.Double</code> representing the result of the multiplication
                  or <code>null</code> if the input paramters are not valid.
              </returns>
      
          </method>
      </section>
  
  
      <section name="div()">
          <method name="div()">
      
              <abstract>
                  Division
              </abstract>
                  
              <signature>
                  Double div(Object num1, Object num2)
              </signature>
  
              <parameters>
                  <parameter name="num1, num2">
                      Input for the division. Valid input is any number (primitive
                      types or objects, Velocity automatically converts primitives types 
                      to objects) or a string representation of a number.
                  </parameter>
              </parameters>
      
              <returns>
                  A <code>java.lang.Double</code> representing the result of the division
                  or <code>null</code> if the input paramters are not valid.
              </returns>
      
          </method>
      </section>
  
  
      <section name="pow()">
          <method name="pow()">
      
              <abstract>
                  Power of
              </abstract>
      
              <signature>
                  Double pow(Object num1, Object num2)
              </signature>
  
              <parameters>
                  <parameter name="num1, num2">
                      Operands. Valid input is any number (primitive
                      types or objects, Velocity automatically converts primitives types 
                      to objects) or a string representation of a number.
                  </parameter>
              </parameters>
      
              <returns>
                  A <code>java.lang.Double</code> representing the first number raised to 
                  the power of the second or <code>null</code> if the input paramters are not valid.
              </returns>
      
         </method>
      </section>
  
  
  
      <section name="max()">
          <method name="max()">
      
              <abstract>
                  Maximum of two numbers
              </abstract>
      
              <signature>
                  Double max(Object num1, Object num2)
              </signature>
  
              <parameters>
                  <parameter name="num1, num2">
                      Operands. Valid input is any number (primitive
                      types or objects, Velocity automatically converts primitives types 
                      to objects) or a string representation of a number.
                  </parameter>
              </parameters>
      
              <returns>
                  A <code>java.lang.Double</code> representing the maximum of the two
                  numbers or <code>null</code> if the input paramters are not valid.
              </returns>
      
         </method>
      </section>
  
  
  
      <section name="min()">
          <method name="min()">
      
              <abstract>
                  Minimum of two numbers
              </abstract>
      
              <signature>
                  Double min(Object num1, Object num2)
              </signature>
  
              <parameters>
                  <parameter name="num1, num2">
                      Operands. Valid input is any number (primitive
                      types or objects, Velocity automatically converts primitives types 
                      to objects) or a string representation of a number.
                  </parameter>
              </parameters>
      
              <returns>
                  A <code>java.lang.Double</code> representing the minimum of the two
                  numbers or <code>null</code> if the input paramters are not valid.
              </returns>
      
         </method>
      </section>
  
  
  
  
      <section name="abs()">
          <method name="max()">
      
              <abstract>
                  Absolute value of a number
              </abstract>
      
              <signature>
                  Double abs(Object num)
              </signature>
  
              <parameters>
                  <parameter name="num1, num2">
                      Operand. Valid input is any number (primitive
                      types or objects, Velocity automatically converts primitives types 
                      to objects) or a string representation of a number.
                  </parameter>
              </parameters>
      
              <returns>
                  A <code>java.lang.Double</code> representing the absolute value of the
                  input or <code>null</code> if the input paramter is not valid.
              </returns>
      
         </method>
      </section>
  
  
  
  
      <section name="toDouble()">
          <method name="toDouble()">
      
              <abstract>
                  Converts a number into a double.
              </abstract>
      
              <signature>
                  Double toDouble(Object num)
              </signature>
  
              <parameters>
                  <parameter name="num">
                      Operand. Valid input is any number (primitive
                      types or objects, Velocity automatically converts primitives types 
                      to objects) or a string representation of a number.
                  </parameter>
              </parameters>
      
              <returns>
                  A <code>java.lang.Double</code> representing the input number or 
                  <code>null</code> if the input paramter is not valid.
              </returns>
      
         </method>
      </section>
  
  
  
      <section name="toInteger()">
          <method name="toInteger()">
      
              <abstract>
                  Converts a number into an integer
              </abstract>
      
              <signature>
                  Integer toInteger(Object num)
              </signature>
  
              <parameters>
                  <parameter name="num">
                      Operand. Valid input is any number (primitive
                      types or objects, Velocity automatically converts primitives types 
                      to objects) or a string representation of a number.
                  </parameter>
              </parameters>
      
              <returns>
                  A <code>java.lang.Integer</code> representing the input number or 
                  <code>null</code> if the input paramter is not valid.
              </returns>
      
         </method>
      </section>
  
  
  
      <section name="roundTo()">
          <method name="roundTo()">
      
              <abstract>
                  Rounds a number to the specified number of decimal places
              </abstract>
      
              <signature>
                  Double roundTo(Object decimals, Object num)
              </signature>
  
              <parameters>
                  <parameter name="decimals">
                      The number of decimal places. Valid input is any number (primitive
                      types or objects, Velocity automatically converts primitives types 
                      to objects) or a string representation of a number.
                  </parameter>
                  
                  <parameter name="num">
                      The number to round. Valid input is any number (primitive
                      types or objects, Velocity automatically converts primitives types 
                      to objects) or a string representation of a number.
                  </parameter>
              </parameters>
      
              <returns>
                  A <code>java.lang.Double</code> representing the input number 
                  rounded to the specified number of decimal places or 
                  <code>null</code> if the input paramter is not valid.
              </returns>
                 
              <description>
                  <p>This method is particulary useful for simple display formatting.
                  If you want to round an number to the nearest integer, it
                  is better to use method <code><a href="#roundToInt()">roundToInt()</a></code>, 
                  as that will return an <code>java.lang.Integer</code> rather than 
                  a <code>java.lang.Double</code>.</p>
              </description>
      
          </method>
      </section>
  
  
      <section name="roundToInt()">
          <method name="roundToInt()">
      
              <abstract>
                  Rounds a number to the nearest whole Integer
              </abstract>
      
              <signature>
                  Integer roundToInt(Object num)
              </signature>
  
              <parameters>
                  <parameter name="num">
                      The number to round. Valid input is any number (primitive
                      types or objects, Velocity automatically converts primitives types 
                      to objects) or a string representation of a number.
                  </parameter>
              </parameters>
      
              <returns>
                  A <code>java.lang.Integer</code> representing the input number 
                  rounded to nearest whole Integer or <code>null</code> if the input paramter is not valid.
              </returns>
                 
          </method>
      </section>
  
  
  
      <section name="getRandom()">
          <method name="getRandom()">
      
              <abstract>
                  Returns a pseudo-random number
              </abstract>
      
              <signature>
                  Double getRandom()
              </signature>
      
              <returns>
                  A <code>java.lang.Double</code> 
                  greater than or equal to 0.0 and less than 1.0.
              </returns>
      
         </method>
      </section>
  
  
  
      <section name="random()">
          <method name="random()">
      
              <abstract>
                  Returns a pseudo-random number in a configurable range
              </abstract>
      
              <signature>
                  Integer random(Object num1, Object num2)
              </signature>
  
              <parameters>
                  <parameter name="num1, num2">
                      First and last number of range. Valid input is any number (primitive
                      types or objects, Velocity automatically converts primitives types 
                      to objects) or a string representation of a number.
                  </parameter>
              </parameters>
      
              <returns>
                  A <code>java.lang.Integer</code> greater than or equal to the first
                  number and less than the second number or <code>null</code> if the input paramter 
                  is not valid.
              </returns>
                 
          </method>
      </section>
  
   </body>
  </document>
  
  
  
  
  1.1                  jakarta-velocity-tools/tools/xdocs/ParameterParser.xml
  
  Index: ParameterParser.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
  
      <properties>
          <title>ParameterParser</title>
          <author email="sidler@apache.org">Gabriel Sidler</author>
          <projectfile>../xdocs/vellibrary-menue.xml</projectfile>
      </properties>
  
      <body>
  
      <section name="ParameterParser Reference Documentation">
  
          <p>Context tool for easy parsing of ServletRequest parameters.</p>
          
          <toolinfo>
              <version>@@@version@@@, @@@date@@@</version>
  
              <jar>velocity-tools-library-@@@version@@@.jar</jar>
  
              <clazz>org.apache.velocity.tools.tools.ParameterParser</clazz>
  
              <name>$reqParser</name>
  
              <author email="nathan@esha.com">Nathan Bubna</author>
  
              <config-example>&lt;tool&gt;
    &lt;key&gt;reqParser&lt;/key&gt;
    &lt;class&gt;org.apache.velocity.tools.tools.RequestParser&lt;/class&gt;
  &lt;/tool&gt;</config-example>
  
          </toolinfo>
  
          <methods/>
  
      </section>
  
      <section name="getString()">
          <method name="getString()">
      
              <abstract>
                  Returns the specified servlet request parameter as a String
              </abstract>
      
              <signature>
                  String getString(ServletRequest request, String key)
              </signature>
              
              <signature>
                  String getString(ServletRequest request, String key, String alternate)
              </signature>
              
              <parameters>
                  <parameter name="request">
                      The servlet request of class <code>javax.servlet.ServletRequest</code>
                  </parameter>
                  
                  <parameter name="key">
                      The key of the desired string parameter
                  </parameter>
                  
                  <parameter name="alternate">
                      An alternate value
                  </parameter>
              </parameters>
      
              <returns>
                 The value of the parameter matching the specified key or the 
                 specified alternate String if there is no matching parameter.
                 A value of <code>null</code> is returned if no alternate value
                 is defined and the desired parameter is not found.
              </returns>
         
          </method>
      </section>
  
  
  
      <section name="getBoolean()">
          <method name="getBoolean()">
      
              <abstract>
                  Returns the specified servlet request parameter as a Boolean object or
                  a boolean primitive type
              </abstract>
      
              <signature>
                  Boolean getBoolean(ServletRequest request, String key)
              </signature>
              
              <signature>
                  Boolean getBoolean(ServletRequest request, String key, Boolean alternate)
              </signature>
              
              <signature>
                  boolean getBoolean(ServletRequest request, String key, boolean alternate)
              </signature>
  
              <parameters>
                  <parameter name="request">
                      The servlet request of class <code>javax.servlet.ServletRequest</code>
                  </parameter>
                  
                  <parameter name="key">
                      The key of the desired string parameter
                  </parameter>
                  
                  <parameter name="alternate">
                      An alternate value
                  </parameter>
              </parameters>
      
              <returns>
                 A Boolean object or boolean primitive type that represents the 
                 value of the servlet request parameter matching the specified key 
                 or the specified alternate boolean if there is no matching parameter.
                 A value of <code>null</code> is returned if no alternate value
                 is defined and the desired parameter is not found.
              </returns>
         
          </method>
      </section>
  
  
  
  
      <section name="getNumber()">
          <method name="getNumber()">
      
              <abstract>
                  Returns the specified servlet request parameter as a Number object
              </abstract>
      
              <signature>
                  Number getNumber(ServletRequest request, String key)
              </signature>
              
              <signature>
                  Number getNumber(ServletRequest request, String key, Number alternate)
              </signature>
  
              <parameters>
                  <parameter name="request">
                      The servlet request of class <code>javax.servlet.ServletRequest</code>
                  </parameter>
                  
                  <parameter name="key">
                      The key of the desired string parameter
                  </parameter>
                  
                  <parameter name="alternate">
                      An alternate value
                  </parameter>
              </parameters>
      
              <returns>
                 A <code>java.lang.Number</code> object that represents the 
                 value of the servlet request parameter matching the specified key 
                 or the specified alternate Number if there is no matching parameter.
                 A value of <code>null</code> is returned if no alternate value
                 is defined and the desired parameter is not found.
              </returns>
         
          </method>
      </section>
  
  
  
      <section name="getInt()">
          <method name="getInt()">
      
              <abstract>
                  Returns the specified servlet request parameter as an integer
              </abstract>
      
              <signature>
                  int getInt(ServletRequest request, String key, int alternate)
              </signature>
  
              <parameters>
                  <parameter name="request">
                      The servlet request of class <code>javax.servlet.ServletRequest</code>
                  </parameter>
                  
                  <parameter name="key">
                      The key of the desired string parameter
                  </parameter>
                  
                  <parameter name="alternate">
                      An alternate value
                  </parameter>
              </parameters>
      
              <returns>
                 An integer that represents the 
                 value of the servlet request parameter matching the specified key 
                 or the specified alternate value if there is no matching parameter.
              </returns>
         
          </method>
      </section>
  
  
  
  
      <section name="getDouble()">
          <method name="getDouble()">
      
              <abstract>
                  Returns the specified servlet request parameter as a double
              </abstract>
      
              <signature>
                  double getDouble(ServletRequest request, String key, double alternate)
              </signature>
  
              <parameters>
                  <parameter name="request">
                      The servlet request of class <code>javax.servlet.ServletRequest</code>
                  </parameter>
                  
                  <parameter name="key">
                      The key of the desired string parameter
                  </parameter>
                  
                  <parameter name="alternate">
                      An alternate value
                  </parameter>
              </parameters>
      
              <returns>
                 An double that represents the 
                 value of the servlet request parameter matching the specified key 
                 or the specified alternate value if there is no matching parameter.
              </returns>
         
          </method>
      </section>
  
  
  
      <section name="getStrings()">
          <method name="getStrings()">
      
              <abstract>
                  Returns an array of Strings of all the values of the specified servlet 
                  request parameter
              </abstract>
      
              <signature>
                  String[] getStrings(ServletRequest request, String key)
              </signature>
              
              <parameters>
                  <parameter name="request">
                      The servlet request of class <code>javax.servlet.ServletRequest</code>
                  </parameter>
                  
                  <parameter name="key">
                      The key of the desired string parameter
                  </parameter>
                  
              </parameters>
      
              <returns>
                 A array of Strings that represent all the values of the desired
                 request parameter or <code>null</code> if the parameter does not
                 exist.
              </returns>
         
          </method>
      </section>
  
  
  
  
      <section name="getNumbers()">
          <method name="getNumbers()">
      
              <abstract>
                  Returns an array of Numbers of all the values of the specified servlet 
                  request parameter
              </abstract>
      
              <signature>
                  Number[] getNumbers(ServletRequest request, String key)
              </signature>
              
              <parameters>
                  <parameter name="request">
                      The servlet request of class <code>javax.servlet.ServletRequest</code>
                  </parameter>
                  
                  <parameter name="key">
                      The key of the desired string parameter
                  </parameter>
                  
              </parameters>
      
              <returns>
                 A array of <code>java.lang.Number</code> that represent all the 
                 values of the desired request parameter or <code>null</code> if 
                 the parameter does not exist.
              </returns>
         
          </method>
      </section>
  
  
  
  
      <section name="getInts()">
          <method name="getInts()">
      
              <abstract>
                  Returns an array of integers of all the values of the specified servlet 
                  request parameter
              </abstract>
      
              <signature>
                  int[] getInts(ServletRequest request, String key)
              </signature>
              
              <parameters>
                  <parameter name="request">
                      The servlet request of class <code>javax.servlet.ServletRequest</code>
                  </parameter>
                  
                  <parameter name="key">
                      The key of the desired string parameter
                  </parameter>
                  
              </parameters>
      
              <returns>
                 A array of integer primitive types that represent all the 
                 values of the desired request parameter or <code>null</code> if 
                 the parameter does not exist.
              </returns>
         
          </method>
      </section>
  
  
  
  
      <section name="getDoubles()">
          <method name="getDoubles()">
      
              <abstract>
                  Returns an array of doubles of all the values of the specified servlet 
                  request parameter
              </abstract>
      
              <signature>
                  double[] getDoubles(ServletRequest request, String key)
              </signature>
              
              <parameters>
                  <parameter name="request">
                      The servlet request of class <code>javax.servlet.ServletRequest</code>
                  </parameter>
                  
                  <parameter name="key">
                      The key of the desired string parameter
                  </parameter>
                  
              </parameters>
      
              <returns>
                 A array of double primitive types that represent all the 
                 values of the desired request parameter or <code>null</code> if 
                 the parameter does not exist.
              </returns>
         
          </method>
      </section>
  
  
   </body>
  </document>
  
  
  
  
  1.1                  jakarta-velocity-tools/tools/xdocs/ToolLoader.xml
  
  Index: ToolLoader.xml
  ===================================================================
  <?xml version="1.0"?>
  
  <document>
  
      <properties>
          <title>ToolLoader</title>
          <author email="sidler@apache.org">Gabriel Sidler</author>
          <projectfile>../xdocs/vellibrary-menue.xml</projectfile>
      </properties>
  
      <body>
  
      <section name="ToolLoader Reference Documentation">
  
          <p>
          A context tool that allows template designers to load context tools 
          from within the template. Any object with a public constructor without 
          parameters can be loaded into the context.
          </p>
          
          <toolinfo>
              <version>@@@version@@@, @@@date@@@</version>
  
              <jar>velocity-tools-library-@@@version@@@.jar</jar>
  
              <clazz>org.apache.velocity.tools.tools.ToolLoader</clazz>
  
              <name>$toolLoader</name>
  
              <author email="sidler@apache.org">Gabriel Sidler</author>
  
              <config-example>&lt;tool&gt;
    &lt;key&gt;toolLoader&lt;/key&gt;
    &lt;class&gt;org.apache.velocity.tools.tools.ToolLoader&lt;/class&gt;
  &lt;/tool&gt;</config-example>
  
          </toolinfo>
  
          <methods/>
  
      </section>
  
      <section name="load()">
          <method name="load()">
      
              <abstract>
                  Loads a context tool and inserts it into the Velocity context.
              </abstract>
      
              <signature>
                  void load(String key, String class)
              </signature>
              
              <parameters>
                  <parameter name="key">
                      The key string used to insert to newly instantiated tool 
                      into the Velocity context.
                  </parameter>
                  
                  <parameter name="class">
                      The name of the class to instantiate.
                  </parameter>
              </parameters>
              
              <description>
                  <p>Loads a context tool of class <i>class</i> and inserts it
                  into the Velocity context with key <i>key</i>. On order to be
                  loadable, context tools must provide a public constructor with no 
                  parameters.</p> 
                  <p>The life cycle of a context tool loaded using this method is 
                  the current template request. The instance is processing of the
                  current template has been completet.</p>
                  <p>If the specified class cannot be found or does not have a 
                  public contructor without parameters, then the tool is not loaded
                  and an error message is written to the log.</p>
  
                  <p>Application example:</p>
  <sourcecode>$toolLoader("math", "org.apache.velocity.tools.tools.MathTool")
  $math.random(1,1000)</sourcecode>
  
                  <p>Loads MathTool with name $math into the context. Then, its random() function is
                  used to generate a random number betweenn 1 and 1000.</p>
              </description>
      
          </method>
      </section>
  
  
   </body>
  </document>
  
  
  
  

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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Nathan Bubna <na...@esha.com>.
Nathan said:
> Gabe said:
> > I didn't think about tool initializiation as the primary problematic
> > situation. Much more likely are threading problems if a tools uses
> > read-write instance variables. Synchorniszation wouldn't help in all
> > such cases.
>
> No, not at all.  Mutable instance variables are not a problem for session
> tools.  Each separate browser that connects to a servlet that uses
sessions
> gets its own unique session.  This session can be created upon initial
> request or upon some sort of login action, and it will remain associated
> with _only_ that browser until it either times out or is invalidated by a
> logout action of sorts.  Even if the same user opens the site in a new
> browser (not just a new window of the same browser instance), that browser
> will get a new session of its own.  So even though multiple requests
> (threads) may be executing for the same session, as in the frameset
> situation you propose (and i'd venture to say that that is a highly
uncommon
> situation), all of those requests will be using the same session object
and
> therefore, their own unique set of session tool instances.  Requests made
> for other sessions will have their own instances of those tools.  So i
> repeat again, the only scope-placement in the servlet environment where
> thread-safety is a legitimate concern is the application scope.

eh, i should rephrase... that's not completely true.  i suppose it is
theoretically possible for multiple virtually simultaneous requests by the
same session to happen even after initialization.  but this is an even less
common situation (how many applications really load multiple framesets
during a session?).  and once again, if such a situation causes a problem, i
fault poor design of the tool and site, not lack of enforcement by a toolbox
manager.  in other words, i still don't consider this a legitimate concern
for us here.  if you personally have a tool with this issue and you don't
want to change your API or templates, just synchronize the problematic
method(s).

Nathan Bubna
nathan@esha.com


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Nathan Bubna <na...@esha.com>.
Gabe said:
> I didn't think about tool initializiation as the primary problematic
> situation. Much more likely are threading problems if a tools uses
> read-write instance variables. Synchorniszation wouldn't help in all
> such cases.

No, not at all.  Mutable instance variables are not a problem for session
tools.  Each separate browser that connects to a servlet that uses sessions
gets its own unique session.  This session can be created upon initial
request or upon some sort of login action, and it will remain associated
with _only_ that browser until it either times out or is invalidated by a
logout action of sorts.  Even if the same user opens the site in a new
browser (not just a new window of the same browser instance), that browser
will get a new session of its own.  So even though multiple requests
(threads) may be executing for the same session, as in the frameset
situation you propose (and i'd venture to say that that is a highly uncommon
situation), all of those requests will be using the same session object and
therefore, their own unique set of session tool instances.  Requests made
for other sessions will have their own instances of those tools.  So i
repeat again, the only scope-placement in the servlet environment where
thread-safety is a legitimate concern is the application scope.

Nathan Bubna
nathan@esha.com


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Gabriel Sidler <si...@teamup.ch>.

Nathan Bubna wrote:

> Gabe said:
> 
>>I don't think it is far-fetched at all. Think of the following case:
>>Browser loads frameset file with three subframes. This will result in
>>three virtually concurrent requests to the server. All three requests
>>are within the same session because they come from the same client.
>>Three different server threads will assigned to handle these requests.
>>It is quite likely that the execution of the these three threads is
>>overlapping in time. Now, if multiple threads access the same session-
>>scoped tool, thread-safety is clearly a requirement for this tool.
>>
>>Why do you think this is far fetched?
>>
> 
> it is not the situation that is far fetched, it is the possibility of the
> situation resulting in an error.  you see, there still is only one session
> for this user, and it is in that session that we store the tools.  all
> should we need to do is synchronize the initialization/storing of those
> tools on the session object, and there should be no problem.  further, even
> if we do not synchronize that process, it would have to be a very poor
> design if all three of those "virtually concurrent" initial requests would
> initialize the session tool(s) with different data!  if the site and tools
> are properly designed, the worse that would happen is that the session
> tool(s) would be initialized and stored identically three times, and
> subsequent requests would still find only one set of those session tool(s)
> in the user's session attributes.



I didn't think about tool initializiation as the primary problematic
situation. Much more likely are threading problems if a tools uses
read-write instance variables. Synchorniszation wouldn't help in all
such cases.

Gabe




> 
> Nathan Bubna
> nathan@esha.com
> 



--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Nathan Bubna <na...@esha.com>.
Gabe said:
> I don't think it is far-fetched at all. Think of the following case:
> Browser loads frameset file with three subframes. This will result in
> three virtually concurrent requests to the server. All three requests
> are within the same session because they come from the same client.
> Three different server threads will assigned to handle these requests.
> It is quite likely that the execution of the these three threads is
> overlapping in time. Now, if multiple threads access the same session-
> scoped tool, thread-safety is clearly a requirement for this tool.
>
> Why do you think this is far fetched?

it is not the situation that is far fetched, it is the possibility of the
situation resulting in an error.  you see, there still is only one session
for this user, and it is in that session that we store the tools.  all
should we need to do is synchronize the initialization/storing of those
tools on the session object, and there should be no problem.  further, even
if we do not synchronize that process, it would have to be a very poor
design if all three of those "virtually concurrent" initial requests would
initialize the session tool(s) with different data!  if the site and tools
are properly designed, the worse that would happen is that the session
tool(s) would be initialized and stored identically three times, and
subsequent requests would still find only one set of those session tool(s)
in the user's session attributes.

Nathan Bubna
nathan@esha.com


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Gabriel Sidler <si...@teamup.ch>.
Nathan Bubna wrote:

> Gabe said:
> 
>>Thread-safety is an issue for session scoped tools as well. The
>>
> requirements
> 
>>are somewhat different thought. Think about a web client loading a
>>
> frame-set
> 
>>page. It can easily generate multiple virtually concurrent requests that
>>are all within the same session.
>>
> 
> bit of stretch, don't you think?  i suppose it's remotely possible that this
> could cause a problem.  but if such a situation did cause a problem, i would
> lean heavily toward faulting very poor design of the tool and site, rather
> than going to great lengths to prevent this.  it's hard for me at least
> (even if no one else) to see this as a reasonable concern.  IMO, the only
> scope where thread safety is a reasonable concern (barring any inappropriate
> use of static members, of course) is application scope.



I don't think it is far-fetched at all. Think of the following case:
Browser loads frameset file with three subframes. This will result in
three virtually concurrent requests to the server. All three requests
are within the same session because they come from the same client.
Three different server threads will assigned to handle these requests.
It is quite likely that the execution of the these three threads is
overlapping in time. Now, if multiple threads access the same session-
scoped tool, thread-safety is clearly a requirement for this tool.

Why do you think this is far fetched?


Gabe




--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Nathan Bubna <na...@esha.com>.
Gabe said:
> Thread-safety is an issue for session scoped tools as well. The
requirements
> are somewhat different thought. Think about a web client loading a
frame-set
> page. It can easily generate multiple virtually concurrent requests that
> are all within the same session.

bit of stretch, don't you think?  i suppose it's remotely possible that this
could cause a problem.  but if such a situation did cause a problem, i would
lean heavily toward faulting very poor design of the tool and site, rather
than going to great lengths to prevent this.  it's hard for me at least
(even if no one else) to see this as a reasonable concern.  IMO, the only
scope where thread safety is a reasonable concern (barring any inappropriate
use of static members, of course) is application scope.

> > ...this is a very simple,
> > specific, and real case that i must have repeated to you about ten times
...
>
> We are talking past each other here. I hear what you are saying but you
> are not addressing my input. That's why repeating the same thing doesn't
> resolve the issue.

hmm.  i disagree on your premise here.  i do not simply repeat things for
the sake of repeating them.  if i write something, it is in direct reponse
to what you have just written, that is why i always write my responses
inline.  so in my view, if what i say is being repeated, it is because i am
responding to repeated input.  but, i digress, if we are in such a rut, a
portion of the blame is probably mine.  i try to respond to all significant
points made, but perhaps i have failed to do so.

> Let me come back to this topic in a few days. I noted that there are some
> open points here.

well, then i look forward to your return to the topic.  if you would humor
me to repeat your input once more, i will attempt to address it as directly
and thoroughly as i can.

Nathan Bubna
nathan@esha.com


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Gabriel Sidler <si...@teamup.ch>.
Nathan Bubna wrote:

> Gabe said:
...

>>My expectation was that simple tools like a date formatter should be
>>thread-safe such that we can reuse instances. If the tool is not
>>thread-safe, the only reasonable and safe scope is 'request' in my view.
>>If something like a date formatter can't even be reused, what can?
>>
> first of all, session scope is just as safe as request.  the only scope
> where thread-safety is a reasonable concern at all is application.


Thread-safety is an issue for session scoped tools as well. The requirements
are somewhat different thought. Think about a web client loading a frame-set
page. It can easily generate multiple virtually concurrent requests that
are all within the same session.


...



> arghh!! how can you not see the case for that!!!?!!!??! i have spelled it
> out for you time and again!!!  please read this ****i want a DateTool that
> can be easily used (or at least easily extended) to work reasonably in
> either application, session, or request scope!!!****  what is so hard for
> you to understand about that?  if you'd like other cases, how about pretty
> much any tool that relies heavily on localization?!  sorry if i seem a
> little exasperated about this, but if i'm do then it's probably because i
> am!  this is not a non-issue or unrealistic case! this is a very simple,
> specific, and real case that i must have repeated to you about ten times by
> now!!  and i'm not feeling very patient today!  sorry.


We are talking past each other here. I hear what you are saying but you
are not addressing my input. That's why repeating the same thing doesn't
resolve the issue.

Let me come back to this topic in a few days. I noted that there are some
open points here.

Gabe



--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Nathan Bubna <na...@esha.com>.
Nathan said:
> and find different way to satisfy both my
> desire for a flexible DateTool and Gabe's fears about thread-safety when
> DateTool is used as application scope.  thinking....

ok, here's my suggestion (supporting arguments below it):

public class DateTool implements ViewContextTool
{

    //this is used in all methods where a locale is
    //not specified as a parameter
    private Locale locale;

    public DateTool()
    {
        locale = Locale.getDefault();
    }

    public void init(ViewContext ctx)
    {
        //search for a locale within the velocity context,
        //request, session and servlet context
        //in similar fashion to Daniel's MultiViewsTool
        locale = the first one we find in the search pattern
    }

     ... (all other methods go here of course)
}


Now, yes i know this is not completely threadsafe if used as application
scope.  However,  a template designer would have to go to all the trouble of
getting a ViewContext object in a template and passing it to the init
method.  I'm gonna go out on a proverbial limb here and suggest that that
cannot possibly happen by accident!!!  If  Gabe really cannot trust template
designers not to do this maliciously or otherwise inappropriately on
purpose, then i suggest he use the following class as his date formatter.

public ThreadsafeDateTool extends DateTool
{

    public ThreadsafeDateTool ()
    {
        super();
    }

    public void init(ViewContext ctx)
    {
        throws new UnsupportedOperationException("Bad designer! You can't do
that!");
    }

}

Did i miss anything?  Any reasonable objections?

Nathan Bubna
nathan@esha.com


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Nathan Bubna <na...@esha.com>.
Nathan said:
> second, the *very* least you can do is put the DateTool(Locale)
constructor
> back (and working correctly of course).  there is absolutely nothing
unsafe
> about that when used as an application tool.  that would at least allow me
> to easily extend it to make a DateTool of my own that can be easily used
as
> a session or request tool.  you went too far in your eagerness to make it
> thread-safe as an application tool.

heh.  i just realized i'm arguing against myself a bit here... %-)

adding the ctor with a locale parameter does make it easy to extend and use
as a request/session tool *if* we keep the combined factory/initialization
approach (which i don't want to keep anymore) otherwise it doesn't help
much.  d'oh!  guess i asked for that one by arguing..er..debating about too
many things at once.  if i have to choose between the two, i'd rather ditch
the factory/initialization combo and find different way to satisfy both my
desire for a flexible DateTool and Gabe's fears about thread-safety when
DateTool is used as application scope.  thinking....

Nathan Bubna
nathan@esha.com


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Nathan Bubna <na...@esha.com>.
Gabe said:
> Well, our disagreement is really over how much we value flexibility
> vs. usability vs. safety vs. performance of a tool. I am wondering
> what requirements we should apply for the tools that go into the library.
> We certainly can't have such a discussion back and forth for each tool
> that we add.

yeah, i really don't want to do this every time either.

> My expectation was that simple tools like a date formatter should be
> thread-safe such that we can reuse instances. If the tool is not
> thread-safe, the only reasonable and safe scope is 'request' in my view.
> If something like a date formatter can't even be reused, what can?

first of all, session scope is just as safe as request.  the only scope
where thread-safety is a reasonable concern at all is application.

second, the *very* least you can do is put the DateTool(Locale) constructor
back (and working correctly of course).  there is absolutely nothing unsafe
about that when used as an application tool.  that would at least allow me
to easily extend it to make a DateTool of my own that can be easily used as
a session or request tool.  you went too far in your eagerness to make it
thread-safe as an application tool.

third, i don't appreciate you changing the target scope of tool i submitted
without discussing it with me.  i use the tools i submit in my classes
and/or templates.  you make it difficult to switch from my local versions
when you make so many changes to the API.  yes, i know and expect that
things i submit will change, but when you change them that much i think it's
at least common courtesy to discuss it with me first.   and just for the
record, it would have been just as easy for you to extend my version to be
thread-safe in application scope, as it will be for me to extend your
version (with the change i'm asking of course) to work well as request or
session scope.

> The point of my changes was to make it thread-safe such that you would
> never need to use it in session or request scope. The trade-off is one
> additional parameter for some of the methods. Based on your feedback,
> this seems a quite unreasonable trade-off.

not quite true, your trade-off entails one additional parameter for *all* of
the methods in ParameterParser.  as well as one more parameter for all
DateTool methods that i want to be locale sensitive (as one would likely
want from a request or session scoped DateTool).

furthermore, i only use ParameterParser in request and session situations.
so why would i want to make it so unfriendly to use in those situations?
you claim to have helped by eliminating a "need", but it was not a "need"
for such behaviour that prompted the original design but instead a desire
for it!  as such, i find the API of your version to quite unelegant and
annoying.  i will never agree that avoiding the instantiation of one measly
object per request (particularly one as lightweight as my ParameterParser)
is worth using (IMO) ugly and unweildy code.  your fears about performance
here are quite unreasonable.  what you have done is added a trivial
improvement in performance at the cost of a great deal of flexibility (in
DateTool) and ease-of-use (in both classes).

> You repeately bring up that case where one tools would be used in
different
> scopes. I just don't see the case for that. All tools that I can imaging
have
> a scope fixed by their design. If there really is an exotic case where you
> need variable scopes, there are easy work-arounds. You can always place a
tool
> into one of the scopes manually. My current feeling is that this scope
thing
> is adressing an non-issue.

arghh!! how can you not see the case for that!!!?!!!??! i have spelled it
out for you time and again!!!  please read this ****i want a DateTool that
can be easily used (or at least easily extended) to work reasonably in
either application, session, or request scope!!!****  what is so hard for
you to understand about that?  if you'd like other cases, how about pretty
much any tool that relies heavily on localization?!  sorry if i seem a
little exasperated about this, but if i'm do then it's probably because i
am!  this is not a non-issue or unrealistic case! this is a very simple,
specific, and real case that i must have repeated to you about ten times by
now!!  and i'm not feeling very patient today!  sorry.

Nathan Bubna
nathan@esha.com


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Gabriel Sidler <si...@teamup.ch>.
Nathan Bubna wrote:

> Gabe said:
> 
>>Nathan,
>>my motivation was to make the tools thread-safe and thereby allowing
>>the reuse of the same instance for the entire runtime. The additional
>>method parameter for some of the methods seemed to be a reasonable
>>trade-off to me.
>>
> 
> no, i think DateTool worked fine as an application scope tool as it was.
> sorry, but i don't see how your changes added anything.  all they seem to do
> is make it much more difficult to use it as a session or request tool.
> if you are that concerned about it being thread-safe as an application tool,
> the only thing you needed to do was to remove the setLocale method.
> DateTool has no other mutators and no static members.
> i would much prefer, however, to leave the method so that those who wish to
> use the tool as a request or session tool may take advantage of it.  if
> you're really afraid template designers will misuse the method, then do no
> more than make it protected to hide it from velocity introspection while
> still giving developers a chance at getting at it.  at the very least, give
> me back the constructor that takes a locale parameter; there is nothing
> un-thread-safe about that.



Well, our disagreement is really over how much we value flexibility
vs. usability vs. safety vs. performance of a tool. I am wondering
what requirements we should apply for the tools that go into the library.
We certainly can't have such a discussion back and forth for each tool
that we add.

My expectation was that simple tools like a date formatter should be
thread-safe such that we can reuse instances. If the tool is not
thread-safe, the only reasonable and safe scope is 'request' in my view.
If something like a date formatter can't even be reused, what can?


> as for my ParameterParser, yes, it would not work correctly as an
> application scope tool, but seeing as the entire point of the class is to
> parse request parameters, i it is very poor style to use it in a
> global/application scope fashion!   i completely disagree that what you have
> done there is a reasonable trade-off.  :-/  sorry, but i never use nor
> intend to use ParameterParser as anything but request scope (either in
> templates or in initialization methods of other tools), and your changes
> make such usage quite annoying. 


The point of my changes was to make it thread-safe such that you would
never need to use it in session or request scope. The trade-off is one
additional parameter for some of the methods. Based on your feedback,
this seems a quite unreasonable trade-off.

You repeately bring up that case where one tools would be used in different
scopes. I just don't see the case for that. All tools that I can imaging have
a scope fixed by their design. If there really is an exotic case where you
need variable scopes, there are easy work-arounds. You can always place a tool
into one of the scopes manually. My current feeling is that this scope thing
is adressing an non-issue.

Gabe


--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Daniel Rall <dl...@finemaltcoding.com>.
"Nathan Bubna" <na...@esha.com> writes:

> Daniel said:
> > "Nathan Bubna" <na...@esha.com> writes:
>>
>> > Daniel said:
>> > > Again, caching the request-scoped context tools obviates the need for
>> >> such changes and keeps the API simple.
>> >
>> > yeah, i think this would be good to add...  but one thing at a time.
> afaics
> > > we haven't even nailed down a tool interface/manager API or
> implementation
> > > yet.  (at least not one that everyone is ok with)
>>
>> Looking forward to things like pooling (before you need it) helps
>> define the right API today.
>
> :-)  yeah, you're right.  it's good to look into it and keep it in mind,
> let's just not go implementing any of it just yet.

Certainly not until there's an API which will support it.  ;)
It's already implemented in Turbine's PullService in any case.

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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Nathan Bubna <na...@esha.com>.
Daniel said:
> "Nathan Bubna" <na...@esha.com> writes:
>
> > Daniel said:
> > > Again, caching the request-scoped context tools obviates the need for
> >> such changes and keeps the API simple.
> >
> > yeah, i think this would be good to add...  but one thing at a time.
afaics
> > we haven't even nailed down a tool interface/manager API or
implementation
> > yet.  (at least not one that everyone is ok with)
>
> Looking forward to things like pooling (before you need it) helps
> define the right API today.

:-)  yeah, you're right.  it's good to look into it and keep it in mind,
let's just not go implementing any of it just yet.

Nathan Bubna
nathan@esha.com


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Daniel Rall <dl...@finemaltcoding.com>.
"Nathan Bubna" <na...@esha.com> writes:

> Daniel said:
> > Again, caching the request-scoped context tools obviates the need for
>> such changes and keeps the API simple.
>
> yeah, i think this would be good to add...  but one thing at a time.  afaics
> we haven't even nailed down a tool interface/manager API or implementation
> yet.  (at least not one that everyone is ok with)

Looking forward to things like pooling (before you need it) helps
define the right API today.

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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Nathan Bubna <na...@esha.com>.
Daniel said:
> Again, caching the request-scoped context tools obviates the need for
> such changes and keeps the API simple.

yeah, i think this would be good to add...  but one thing at a time.  afaics
we haven't even nailed down a tool interface/manager API or implementation
yet.  (at least not one that everyone is ok with)

Nathan Bubna
nathan@esha.com


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Daniel Rall <dl...@finemaltcoding.com>.
"Nathan Bubna" <na...@esha.com> writes:

> what?! i highly doubt the instantiation of even a thousand instances a
> second of an object with so lightweight of a constructor would make an
> appreciable difference in any sane application/server setup.  i think your
> fears of poor performance are unfounded.

The problems associated with too much object instantiation is
generally caused by garbage collection, not by the actual act of
memory allocation.

Again, caching the request-scoped context tools obviates the need for
such changes and keeps the API simple.

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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Nathan Bubna <na...@esha.com>.
Gabe said:
> Nathan,
> my motivation was to make the tools thread-safe and thereby allowing
> the reuse of the same instance for the entire runtime. The additional
> method parameter for some of the methods seemed to be a reasonable
> trade-off to me.

no, i think DateTool worked fine as an application scope tool as it was.
sorry, but i don't see how your changes added anything.  all they seem to do
is make it much more difficult to use it as a session or request tool.
if you are that concerned about it being thread-safe as an application tool,
the only thing you needed to do was to remove the setLocale method.
DateTool has no other mutators and no static members.
i would much prefer, however, to leave the method so that those who wish to
use the tool as a request or session tool may take advantage of it.  if
you're really afraid template designers will misuse the method, then do no
more than make it protected to hide it from velocity introspection while
still giving developers a chance at getting at it.  at the very least, give
me back the constructor that takes a locale parameter; there is nothing
un-thread-safe about that.

as for my ParameterParser, yes, it would not work correctly as an
application scope tool, but seeing as the entire point of the class is to
parse request parameters, i it is very poor style to use it in a
global/application scope fashion!   i completely disagree that what you have
done there is a reasonable trade-off.  :-/  sorry, but i never use nor
intend to use ParameterParser as anything but request scope (either in
templates or in initialization methods of other tools), and your changes
make such usage quite annoying.  i think you'll find most people will be
unhappy with it.  if you really need a static version so badly, make it a
separate class.

> Since we are discussing this in the context of auto-loading context
> tools, performance is a real concern of mine. Every context tool class
> that is not thread-safe must be instantantiated on every template
> request. We are talking about hundreds of instances a second.

what?! i highly doubt the instantiation of even a thousand instances a
second of an object with so lightweight of a constructor would make an
appreciable difference in any sane application/server setup.  i think your
fears of poor performance are unfounded.

> I agree that your versions of the tools are a little more user-
> friendly. I would use them in a non-auto-loading environment. Maybe
> we should keep them in the library with a note that they are more
> user-friendly but not thread-safe.

-1

Nathan Bubna
nathan@esha.com


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Daniel Rall <dl...@finemaltcoding.com>.
Gabriel Sidler <si...@teamup.ch> writes:

> Every context tool class that is not thread-safe must be
> instantantiated on every template request. We are talking about
> hundreds of instances a second.

Hello caching, hello destroy()/shutdown()/clear() method for resource
reclamation.  Have you looked at Turbine's PullService?

<http://cvs.apache.org/viewcvs/jakarta-turbine-3/src/java/org/apache/turbine/services/pull/TurbinePullService.java?rev=1&content-type=text/vnd.viewcvs-markup>

Note that the pull service refers to context tools as pull tools, and
uses an ApplicationTool interface for them.  It's been working very
well for me since it was added to Turbine CVS.

> I agree that your versions of the tools are a little more user-
> friendly. I would use them in a non-auto-loading environment. Maybe
> we should keep them in the library with a note that they are more
> user-friendly but not thread-safe.

Good interface is an extremely important consideration when dealing
with context tools.  Consider your target auidence often includes UI
developers and designers which are not comfortable with complex APIs.

If you can't use context tool caching for some reason, why not provide
a wrapper around the thread-safe version of the context tool which
presents a simplified API for single-threaded use (like the old API)?

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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Gabriel Sidler <si...@teamup.ch>.
Nathan Bubna wrote:

> Gabe,
> 
> why the all the changes to DateTool and ParameterParser?  i'm not opposed to
> improving them, but your changes break my current usage of them and makes
> them more difficult to use (IMO).   In DateTool, I don't like having to get
> the locale and pass it to methods every time i want locale sensitive
> behaviour.  it is much easier to set the locale once per instance and have
> it from there.  what was your reason for changing that?
> as for the ParameterParser, a similar problem now exists.  instead of having
> one instance per request, i must now pass the request for every method!
> why??  i can't imagine a case where you can correctly be using the same
> instance for multiple requests!  IMO that is really wrong behaviour and
> seems to be encouraged by your changes.  i really don't get it and am not at
> all eager to change my usage to fit these changes.  am i just completely
> missing something?  please explain.
> 
> Nathan Bubna
> nathan@esha.com


Nathan,
my motivation was to make the tools thread-safe and thereby allowing
the reuse of the same instance for the entire runtime. The additional
method parameter for some of the methods seemed to be a reasonable
trade-off to me.

Since we are discussing this in the context of auto-loading context
tools, performance is a real concern of mine. Every context tool class
that is not thread-safe must be instantantiated on every template
request. We are talking about hundreds of instances a second.
I agree that your versions of the tools are a little more user-
friendly. I would use them in a non-auto-loading environment. Maybe
we should keep them in the library with a note that they are more
user-friendly but not thread-safe.


Gabe


--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Daniel Rall <dl...@finemaltcoding.com>.
"Nathan Bubna" <na...@esha.com> writes:

> Gabe,
>
> why the all the changes to DateTool and ParameterParser?  i'm not
> opposed to improving them, but your changes break my current usage
> of them and makes them more difficult to use (IMO).  In DateTool, I
> don't like having to get the locale and pass it to methods every
> time i want locale sensitive behaviour.  it is much easier to set
> the locale once per instance and have it from there.  what was your
> reason for changing that?

Nathan has a good point.  If the tool is request-scoped, that should
be set at initialization time.

> as for the ParameterParser, a similar problem now exists.  instead
> of having one instance per request, i must now pass the request for
> every method!  why??  i can't imagine a case where you can correctly
> be using the same instance for multiple requests!  IMO that is
> really wrong behaviour and seems to be encouraged by your changes.
> i really don't get it and am not at all eager to change my usage to
> fit these changes.  am i just completely missing something?  please
> explain.

Ditto.

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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Nathan Bubna <na...@esha.com>.
Gabe,

why the all the changes to DateTool and ParameterParser?  i'm not opposed to
improving them, but your changes break my current usage of them and makes
them more difficult to use (IMO).   In DateTool, I don't like having to get
the locale and pass it to methods every time i want locale sensitive
behaviour.  it is much easier to set the locale once per instance and have
it from there.  what was your reason for changing that?
as for the ParameterParser, a similar problem now exists.  instead of having
one instance per request, i must now pass the request for every method!
why??  i can't imagine a case where you can correctly be using the same
instance for multiple requests!  IMO that is really wrong behaviour and
seems to be encouraged by your changes.  i really don't get it and am not at
all eager to change my usage to fit these changes.  am i just completely
missing something?  please explain.

Nathan Bubna
nathan@esha.com


----- Original Message -----
From: <si...@apache.org>
To: <ja...@apache.org>
Sent: Wednesday, April 03, 2002 1:10 AM
Subject: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml
MathTool.xml ParameterParser.xml ToolLoader.xml


> sidler      02/04/03 01:10:03
>
>   Added:       tools    README.txt build.xml
>                tools/lib jdbc2_0-stdext.jar servlet.jar struts.jar
>                         velocity-tools-view-0.4.jar
>                tools/src/conf MANIFEST.MF
>                tools/src/java/org/apache/velocity/tools/tools
DateTool.java
>                         MathTool.java ParameterParser.java ToolLoader.java
>                         package.html
>                tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml
>                         ToolLoader.xml
>   Log:
>   Added package tools. This is intended to host various reusable context
>   tools. Currently hosted tools are DateTool, MathTool, RequestParser and
>   ToolLoader. All tools are optimized to be used with an auto-loading
toolbox
>   manager and come with documentation for the template designers. A
>   documentation snapshot is online at:
>   http://www.teamup.com/jakarta-velocity-tools/docs/vellibrary.html
>
>   Revision  Changes    Path
>   1.1                  jakarta-velocity-tools/tools/README.txt
>
>   Index: README.txt
>   ===================================================================
>   R E A D M E
>   ===========
>
>   This package contains a collection of general purpose context tools.
>   Most tools are optimized for use with an automatic toolbox manager.
>
>
>   Build and JAR
>   -------------
>   An ant script is provided to build and jar the package.
>
>   > ant compile
>   > ant jar
>
>
>   Documentation
>   -------------
>   To generate the documentation for this package, call:
>
>   > ant docs
>
>   Then look for the generated documentation in the 'docs' subdirectory.
>
>
>
>   Please send your feedback to velocity-user@jakarta.apache.org.
>
>
>   1.1                  jakarta-velocity-tools/tools/build.xml
>
>   Index: build.xml
>   ===================================================================
>
>   <project name="velocity-tools-library" default="all" basedir=".">
>
>   <!-- ========== Initialize Properties
===================================== -->
>
>     <property file="build/build.properties"/>          <!-- Component
local   -->
>     <property file="../build.properties"/>             <!-- Commons
l     -->
>     <property file="${user.home}/.build.properties"/>  <!-- User
      -->
>
>   <!-- ========== External Dependencies
===================================== -->
>
>    <!-- the local repository -->
>    <property name="local.repository"            value="./lib" />
>    <property name="project.repository"          value="../lib" />
>
>   <!-- ========== Component Declarations
==================================== -->
>
>
>     <!-- The name of this component -->
>     <property name="project.name"          value="velocity-tools-library"
/>
>
>     <!-- The title of this component -->
>     <property name="project.title"         value=""/>
>
>     <!-- The current version number of this component -->
>     <property name="project.version"       value="0.1"/>
>
>     <!-- The current version number of this component -->
>     <property name="project.date"          value="24-Mar-2002"/>
>
>     <!-- The base directory for compilation targets -->
>     <property name="build.home"            value="target"/>
>
>     <!-- The base directory for distribution targets -->
>     <property name="dist.home"             value="dist"/>
>
>     <!-- The base directory for component sources -->
>     <property name="source.home"           value="src"/>
>
>     <!-- The base directory for component sources -->
>     <property name="conf.home"             value="src/conf"/>
>
>     <!-- The docs source directory -->
>     <property name="docs.src"              value="xdocs"/>
>
>     <!-- The docs destination directory  -->
>     <property name="docs.dest"             value="docs"/>
>
>     <!-- The docs destination directory  -->
>     <property name="examples.home"         value="examples"/>
>
>   <!-- ========== Compiler Defaults
========================================= -->
>
>
>     <!-- Should Java compilations set the 'debug' compiler option? -->
>     <property name="compile.debug"           value="true"/>
>
>     <!-- Should Java compilations set the 'deprecation' compiler
option? -->
>     <property name="compile.deprecation"     value="true"/>
>
>     <!-- Should Java compilations set the 'optimize' compiler option? -->
>     <property name="compile.optimize"        value="true"/>
>
>     <!-- Construct compile classpath -->
>     <path id="classpath">
>       <fileset dir="${local.repository}">
>         <include name="**/*.jar"/>
>       </fileset>
>       <fileset dir="${project.repository}">
>         <include name="**/*.jar"/>
>       </fileset>
>     </path>
>
>   <!-- ========== Executable Targets
======================================== -->
>
>
>     <!--
================================================================== -->
>     <!-- I N I
  -->
>     <!--
================================================================== -->
>     <target name="init"
>      description="Initialize and evaluate conditionals">
>       <echo message="-------- ${project.name}
${project.version} --------"/>
>       <filter  token="name"                  value="${project.name}"/>
>       <filter  token="version"               value="${project.version}"/>
>     </target>
>
>     <!--
================================================================== -->
>     <!-- P R E P A R
  -->
>     <!--
================================================================== -->
>     <target name="prepare" depends="init"
>      description="Prepare build directory">
>       <mkdir dir="${build.home}"/>
>       <mkdir dir="${build.home}/classes"/>
>       <mkdir dir="${build.home}/conf"/>
>       <mkdir dir="${build.home}/javadoc"/>
>     </target>
>
>     <!--
================================================================== -->
>     <!-- S T A T I
  -->
>     <!--
================================================================== -->
>     <target name="static" depends="prepare"
>      description="Copy static files to build directory">
>       <tstamp/>
>       <copy  todir="${build.home}/conf" filtering="on">
>         <fileset dir="${conf.home}" includes="*.MF"/>
>       </copy>
>     </target>
>
>     <!--
================================================================== -->
>     <!-- C O M P I L
  -->
>     <!--
================================================================== -->
>     <target name="compile" depends="static" description="Compile">
>
>       <javac  srcdir="${source.home}/java"
>               destdir="${build.home}/classes"
>               debug="${compile.debug}"
>               deprecation="${compile.deprecation}"
>               optimize="${compile.optimize}">
>           <classpath refid="classpath"/>
>       </javac>
>
>       <copy    todir="${build.home}/classes" filtering="on">
>         <fileset dir="${source.home}/java" excludes="**/*.java"/>
>       </copy>
>
>     </target>
>
>     <!--
================================================================== -->
>     <!-- C L E A
  -->
>     <!--
================================================================== -->
>     <target name="clean"
>      description="Clean build and distribution directories">
>       <delete    dir="${build.home}"/>
>       <delete    dir="${dist.home}"/>
>       <delete>
>         <fileset dir="${basedir}" includes="*.jar"/>
>       </delete>
>       <delete>
>         <fileset dir="${docs.dest}" includes="**/*.html"/>
>       </delete>
>       <delete    dir="${examples.home}/velstruts"/>
>       <delete>
>         <fileset dir="${examples.home}" includes="*.war"/>
>       </delete>
>       <delete>
>         <fileset dir="${basedir}" includes="**/*.bak"/>
>       </delete>
>
>     </target>
>
>
>     <!--
================================================================== -->
>     <!-- A L
  -->
>     <!--
================================================================== -->
>     <target name="all" depends="clean,jar,docs,javadocs"
>      description="Clean and compile all components"/>
>
>
>     <!--
================================================================== -->
>     <!-- J A V A D O C
  -->
>     <!--
================================================================== -->
>     <target name="javadocs" depends="compile"
>      description="Create Javadoc documentation">
>       <javadoc sourcepath="${source.home}/java"
>                   destdir="${build.home}/javadoc"
>              packagenames="org.apache.velocity.tools.struts.*"
>                    author="true"
>                   private="true"
>                   version="true"
>                  doctitle="&lt;h1&gt;${project.title}&lt;/h1&gt;"
>               windowtitle="${project.title} (Version ${project.version})"
>                    bottom="Copyright (c) 2002 Apache Software Foundation"
>
>
>         <classpath refid="classpath"/>
>
>        </javadoc>
>     </target>
>
>
>     <!--
================================================================== -->
>     <!-- J A
  -->
>     <!--
================================================================== -->
>     <target name="jar" depends="compile">
>       <jar    jarfile="${project.name}-${project.version}.jar"
>               basedir="${build.home}/classes"
>               manifest="${conf.home}/MANIFEST.MF"/>
>     </target>
>
>
>     <!--
================================================================== -->
>     <!-- D O C
  -->
>     <!--
================================================================== -->
>     <target name="docs">
>
>         <taskdef name="dvsl" classname="org.apache.tools.dvsl.DVSLTask">
>
>             <classpath>
>                <path refid="classpath"/>
>             </classpath>
>
>         </taskdef>
>
>         <dvsl
>              basedir="${docs.src}"
>              destdir="${docs.dest}/"
>          toolboxfile="../xdocs/toolbox.props"
>              extension=".html"
>              style="../xdocs/site.dvsl"
>              excludes="*menue.xml"
>              includes="**/*.xml"
>         />
>
>         <replace dir="${docs.dest}">
>             <replacefilter token="@@@version@@@"
value="${project.version}"/>
>             <replacefilter token="@@@date@@@" value="${project.date}"/>
>         </replace>
>
>
>     </target>
>
>
>     <!--
================================================================== -->
>     <!-- I N S T A L L  J A
  -->
>     <!--
================================================================== -->
>     <target name="install-jar" depends="jar"
>             description="--> Installs .jar file in ${lib.repo}">
>       <copy todir="${lib.repo}" filtering="no">
>         <fileset dir="${basedir}">
>           <include name="${project.name}-${project.version}.jar"/>
>         </fileset>
>       </copy>
>     </target>
>
>
>     <!--
================================================================== -->
>     <!--  D E P L O Y   J A
  -->
>     <!--
================================================================== -->
>     <target name="deploy-jar" depends="compile, jar"
>             description="Deploy jar to example applications">
>
>       <delete>
>           <fileset dir="${examples.home}/struts/WEB-INF/lib"
includes="${project.name}-*.jar"/>
>       </delete>
>
>       <copy todir="${examples.home}/struts/WEB-INF/lib" filtering="no">
>         <fileset dir="${basedir}">
>           <include name="${project.name}-*.jar"/>
>         </fileset>
>       </copy>
>     </target>
>
>
>   </project>
>
>
>
>
>   1.1                  jakarta-velocity-tools/tools/lib/jdbc2_0-stdext.jar
>
>   <<Binary file>>
>
>
>   1.1                  jakarta-velocity-tools/tools/lib/servlet.jar
>
>   <<Binary file>>
>
>
>   1.1                  jakarta-velocity-tools/tools/lib/struts.jar
>
>   <<Binary file>>
>
>
>   1.1
jakarta-velocity-tools/tools/lib/velocity-tools-view-0.4.jar
>
>   <<Binary file>>
>
>
>   1.1                  jakarta-velocity-tools/tools/src/conf/MANIFEST.MF
>
>   Index: MANIFEST.MF
>   ===================================================================
>   Extension-Name: @package@
>   Specification-Vendor: Apache Software Foundation
>   Specification-Version: 1.0
>   Implementation-Vendor: Apache Software Foundation
>   Implementation-Version: @version@
>
>
>
>   1.1
jakarta-velocity-tools/tools/src/java/org/apache/velocity/tools/tools/DateTo
ol.java
>
>   Index: DateTool.java
>   ===================================================================
>   /*
>    * The Apache Software License, Version 1.1
>    *
>    * Copyright (c) 2001 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", "Velocity", 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.velocity.tools.tools;
>
>
>   import java.text.DateFormat;
>   import java.text.SimpleDateFormat;
>   import java.util.Date;
>   import java.util.Calendar;
>   import java.util.Locale;
>
>   import org.apache.velocity.tools.view.tools.ThreadSafeContextTool;
>
>
>   /**
>    * <p>Tool for manipulating {@link Date} and {@link Calendar}
>    * objects in Velocity templates.</p>
>    *
>    * <p>The tool is tread-safe and implements interface
>    * ThreadSafeContextTool. This allows a compatible toolbox
>    * manager like {@link
org.apache.velocity.tools.view.servlet.ServletToolboxManager}
>    * to automatically load the tool into the context and reuse
>    * the same instance for the entire runtime.</p>
>    *
>    * @author <a href="mailto:sidler@teamup.com">Gabriel Sidler</a>
>    * @author <a href="mailto:nathan@esha.com">Nathan Bubna</a>
>    * @version $Revision: 1.1 $
>    */
>
>   public class DateTool implements ThreadSafeContextTool
>   {
>
>
>       /**
>        * Default constructor.
>        */
>       public DateTool()
>       {}
>
>
>       /**
>        * Returns a Date object. The default Locale is used.
>        *
>        * @return a <code>java.util.Date</code> object representing the
time at
>        *    which this method was invoked
>        */
>       public static Date getDate()
>       {
>           return getDate();
>       }
>
>
>       /**
>        * Returns a Date object representing the time at which this method
was
>        * invoked in the specified locale.
>        *
>        * @param locale the {@link java.util.Locale} to use to generate the
Date
>        *
>        * @return a {@link java.util.Date} object representing the time at
which
>        *     this method was invoked in the specified locale
>        */
>       public static Date getDate(Locale locale)
>       {
>           return getCalendar(locale).getTime();
>       }
>
>
>       /**
>        * Returns a Calendar object representing the time at which this
method was
>        * invoked and in the default Locale.
>        *
>        * @return a {@link java.util.Calendar} object representing the time
at which
>        *     this method was invoked using the default Locale
>        */
>       public static Calendar getCalendar()
>       {
>           return Calendar.getInstance();
>       }
>
>
>       /**
>        * Returns a Calendar object representing the time at which this
method was
>        * invoked and in the specified locale.
>        *
>        * @param locale the {@link java.util.Locale} to use to create a
Calendar
>        * @return a {@link java.util.Calendar} object representing the time
at which
>        *     this method was invoked and in the specified locale
>        */
>       public static Calendar getCalendar(Locale locale)
>       {
>           return Calendar.getInstance(locale);
>       }
>
>
>       /**
>        * Returns a formatted string representing the specified date
>        * in the default locale.
>        *
>        * <p>
>        * This method uses the same formatting instructions as
>        * {@link SimpleDateFormat}:
>        * <pre>
>        *   Symbol   Meaning                 Presentation        Example
>        *   ------   -------                 ------------        -------
>        *   G        era designator          (Text)              AD
>        *   y        year                    (Number)            1996
>        *   M        month in year           (Text & Number)     July & 07
>        *   d        day in month            (Number)            10
>        *   h        hour in am/pm (1~12)    (Number)            12
>        *   H        hour in day (0~23)      (Number)            0
>        *   m        minute in hour          (Number)            30
>        *   s        second in minute        (Number)            55
>        *   S        millisecond             (Number)            978
>        *   E        day in week             (Text)              Tuesday
>        *   D        day in year             (Number)            189
>        *   F        day of week in month    (Number)            2 (2nd Wed
in July)
>        *   w        week in year            (Number)            27
>        *   W        week in month           (Number)            2
>        *   a        am/pm marker            (Text)              PM
>        *   k        hour in day (1~24)      (Number)            24
>        *   K        hour in am/pm (0~11)    (Number)            0
>        *   z        time zone               (Text)              Pacific
Standard Time
>        *   '        escape for text         (Delimiter)
>        *   ''       single quote            (Literal)           '
>        *
>        *   Examples: "E, MMMM d" will result in "Tue, July 24"
>        *             "EEE, M-d (H:m)" will result in "Tuesday, 7-24
(14:12)"
>        * </pre>
>        *
>        * @param format the formatting instructions
>        * @param obj the date to format
>        *
>        * @return a formatted string representing the specified date or
>        *     <code>null</code> if the parameters are invalid
>        */
>       public static String format(String format, Object obj)
>       {
>           Date date = toDate(obj);
>           if (date == null || format == null)
>           {
>               return null;
>           }
>           SimpleDateFormat formatter = new SimpleDateFormat(format);
>           return formatter.format(date);
>       }
>
>
>       /**
>        * Returns a formatted string representing the specified date and
locale.
>        *
>        * This method uses the same formatting instructions as
>        * {@link SimpleDateFormat}:
>        *
>        * @param format the formatting instructions
>        * @param obj the date to format
>        * @param locale the {@link java.util.Locale} to format the date for
>        *
>        * @return a formatted string representing the specified date or
>        *         <code>null</code> if the parameters are invalid
>        * @see #format
>        */
>       public static String format(String format, Object obj, Locale
locale)
>       {
>           Date date = toDate(obj);
>           if (date == null || format == null || locale == null)
>           {
>               return null;
>           }
>           SimpleDateFormat formatter = new SimpleDateFormat(format,
locale);
>           return formatter.format(date);
>       }
>
>
>
>       /**
>        * Returns a Date object representing the specified date.
>        *
>        * @param obj the date to convert
>        *
>        * @return the converted date
>        */
>       public static Date toDate(Object obj)
>       {
>           if (obj == null)
>           {
>               return null;
>           }
>           if (obj instanceof Date)
>           {
>               return (Date)obj;
>           }
>           if (obj instanceof Calendar)
>           {
>               return ((Calendar)obj).getTime();
>           }
>           try
>           {
>               //try treating obj as a string and parsing it
>               DateFormat format = DateFormat.getInstance();
>               return format.parse(String.valueOf(obj));
>           }
>           catch (Exception e)
>           {
>               return null;
>           }
>       }
>
>
>       /**
>        * Returns a Calendar object representing the specified date.
>        *
>        * @param obj the date to convert
>        *
>        * @return the converted date
>        */
>       public static Calendar toCalendar(Object obj)
>       {
>           if (obj == null)
>           {
>               return null;
>           }
>           if (obj instanceof Calendar)
>           {
>               return (Calendar)obj;
>           }
>           //try to get a date out of it
>           Date date = toDate(obj);
>           if (date == null)
>           {
>               return null;
>           }
>
>           //convert the date to a calendar
>           Calendar cal = Calendar.getInstance();
>           cal.setTime(date);
>           //Force fields to update.
>           cal.getTime();
>           return cal;
>       }
>
>
>   }
>
>
>
>
>   1.1
jakarta-velocity-tools/tools/src/java/org/apache/velocity/tools/tools/MathTo
ol.java
>
>   Index: MathTool.java
>   ===================================================================
>   /*
>    * The Apache Software License, Version 1.1
>    *
>    * Copyright (c) 2001 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", "Velocity", 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.velocity.tools.tools;
>
>   import org.apache.velocity.tools.view.tools.ThreadSafeContextTool;
>   import java.lang.Math;
>
>
>   /**
>    * <p>Tool for performing floating point math in Velocity.</p>
>    *
>    * <p>Several things should be noted here:</p>
>    *
>    * <ol>
>    * <li>This class does not have methods that take
>    * primitives.  This is simply because Velocity
>    * wraps all primitives for us automagically.</li>
>    *
>    * <li>Most methods return {@link Double} wrappers
>    * which automatically render the decimal places even
>    * for whole numbers (e.g. new Double(1).toString() -> '1.0')
>    * This is intentional.  This tool is for floating
>    * point arithmetic.  Integer arithmetic is already supported
>    * in Velocity syntax.  if you really need '1' instead of '1.0',
>    * just call intValue() on the result.</li>
>    *
>    * <li>No null pointer, number format, or divide by zero
>    * exceptions are thrown here.  This is because such exceptions
>    * thrown in template halt rendering.  It should be sufficient
>    * debugging feedback that Velocity will render the reference
>    * literally. (e.g. $math.div(1, 0) renders as '$math.div(1, 0)')</li>
>    * </ul>
>    *
>    * @author <a href="mailto:nathan@esha.com">Nathan Bubna</a>
>    * @version $Revision: 1.1 $ $Date: 2002/04/03 09:10:03 $
>    */
>
>   public class MathTool implements ThreadSafeContextTool
>   {
>       /**
>        * @param num1 the first number
>        * @param num2 the second number
>        * @return the sum of the numbers or
>        *         <code>null</code> if they're invalid
>        * @see #toDouble
>        */
>       public static Double add(Object num1, Object num2)
>       {
>           Double d1 = toDouble(num1);
>           Double d2 = toDouble(num2);
>           if (d1 == null || d2 == null)
>           {
>               return null;
>           }
>           return new Double(d1.doubleValue() + d2.doubleValue());
>       }
>
>
>       /**
>        * @param num1 the first number
>        * @param num2 the second number
>        * @return the difference of the numbers or
>        *         <code>null</code> if they're invalid
>        * @see #toDouble
>        */
>       public static Double sub(Object num1, Object num2)
>       {
>           Double d1 = toDouble(num1);
>           Double d2 = toDouble(num2);
>           if (d1 == null || d2 == null)
>           {
>               return null;
>           }
>           return new Double(d1.doubleValue() - d2.doubleValue());
>       }
>
>
>       /**
>        * @param num1 the first number
>        * @param num2 the second number
>        * @return the product of the numbers or
>        *         <code>null</code> if they're invalid
>        * @see #toDouble
>        */
>       public static Double mul(Object num1, Object num2)
>       {
>           Double d1 = toDouble(num1);
>           Double d2 = toDouble(num2);
>           if (d1 == null || d2 == null)
>           {
>               return null;
>           }
>           return new Double(d1.doubleValue() * d2.doubleValue());
>       }
>
>
>       /**
>        * @param num1 the first number
>        * @param num2 the second number
>        * @return the quotient of the numbers or
>        *         <code>null</code> if they're invalid
>        * @see #toDouble
>        */
>       public static Double div(Object num1, Object num2)
>       {
>           Double d1 = toDouble(num1);
>           Double d2 = toDouble(num2);
>           if (d1 == null || d2 == null || d2.doubleValue() == 0.0)
>           {
>               return null;
>           }
>           return new Double(d1.doubleValue() / d2.doubleValue());
>       }
>
>
>       /**
>        * @param num1 the first number
>        * @param num2 the second number
>        * @return the first number raised to the power of the
>        *         second or <code>null</code> if they're invalid
>        * @see #toDouble
>        */
>       public static Double pow(Object num1, Object num2)
>       {
>           Double d1 = toDouble(num1);
>           Double d2 = toDouble(num2);
>           if (d1 == null || d2 == null)
>           {
>               return null;
>           }
>           return new Double(Math.pow(d1.doubleValue(), d2.doubleValue()));
>       }
>
>
>       /**
>        * @param num1 the first number
>        * @param num2 the second number
>        * @return the largest of the numbers or
>        *         <code>null</code> if they're invalid
>        * @see #toDouble
>        */
>       public static Double max(Object num1, Object num2)
>       {
>           Double d1 = toDouble(num1);
>           Double d2 = toDouble(num2);
>           if (d1 == null || d2 == null)
>           {
>               return null;
>           }
>           return new Double(Math.max(d1.doubleValue(), d2.doubleValue()));
>       }
>
>
>       /**
>        * @param num1 the first number
>        * @param num2 the second number
>        * @return the smallest of the numbers or
>        *         <code>null</code> if they're invalid
>        * @see #toDouble
>        */
>       public static Double min(Object num1, Object num2)
>       {
>           Double d1 = toDouble(num1);
>           Double d2 = toDouble(num2);
>           if (d1 == null || d2 == null)
>           {
>               return null;
>           }
>           return new Double(Math.min(d1.doubleValue(), d2.doubleValue()));
>       }
>
>
>       /**
>        * @param num1 the number
>        * @return the absolute value of the number
>        *         <code>null</code> if it's invalid
>        * @see #toDouble
>        */
>       public static Double abs(Object num)
>       {
>           Double d = toDouble(num);
>           if (d == null)
>           {
>               return null;
>           }
>           return new Double(Math.abs(d.doubleValue()));
>       }
>
>
>       /**
>        * Converts an object with a numeric value into a Double
>        * Valid formats are {@link Number} or a {@link String}
>        * representation of a number
>        *
>        * @param num the number to be converted
>        * @return a {@link Double} representation of the number
>        *         or <code>null</code> if it's invalid
>        */
>       public static Double toDouble(Object num)
>       {
>           double value;
>           try
>           {
>               if (num instanceof Number)
>               {
>                   value = ((Number)num).doubleValue();
>               }
>               else
>               {
>                   value = Double.parseDouble(String.valueOf(num));
>               }
>           }
>           catch (NumberFormatException nfe)
>           {
>               return null;
>           }
>           return new Double(value);
>       }
>
>
>       /**
>        * Converts an object with a numeric value into an Integer
>        * Valid formats are {@link Number} or a {@link String}
>        * representation of a number
>        *
>        * @param num the number to be converted
>        * @return a {@link Integer} representation of the number
>        *         or <code>null</code> if it's invalid
>        */
>       public static Integer toInteger(Object num)
>       {
>           Double d = toDouble(num);
>           if (d == null)
>           {
>               return null;
>           }
>           return new Integer(d.intValue());
>       }
>
>
>       /**
>        * Rounds a number to the specified number of decimal places.
>        * This is particulary useful for simple display formatting.
>        * If you want to round an number to the nearest integer, it
>        * is better to use {@link #roundToInt}, as that will return
>        * an {@link Integer} rather than a {@link Double}.
>        *
>        * @param decimals the number of decimal places
>        * @param value the number to round
>        * @return the value rounded to the specified number of
>        *         decimal places or <code>null</code> if it's invalid
>        * @see #toDouble
>        * @see #toInteger
>        */
>       public static Double roundTo(Object decimals, Object num)
>       {
>           Integer i = toInteger(decimals);
>           Double d = toDouble(num);
>           if (i == null || d == null)
>           {
>               return null;
>           }
>           //ok, go ahead and do the rounding
>           int places = i.intValue();
>           double value = d.doubleValue();
>           if (places == 0)
>           {
>               value = (int)(value + .5);
>           }
>           else
>           {
>               double shift = Math.pow(10, places);
>               value = value * shift;
>               value = (int)(value + .5);
>               value = value / shift;
>           }
>           return new Double(value);
>       }
>
>
>       /**
>        * Rounds a number to the nearest whole Integer
>        *
>        * @param num the number to round
>        * @return the number rounded to the nearest whole Integer
>        *         or <code>null</code> if it's invalid
>        * @see #toDouble
>        */
>       public static Integer roundToInt(Object num)
>       {
>           Double d = toDouble(num);
>           if (d == null)
>           {
>               return null;
>           }
>           return new Integer((int)Math.rint(d.doubleValue()));
>       }
>
>
>       /**
>        * @returns a pseudo-random {@link Double} greater
>        *          than or equal to 0.0 and less than 1.0
>        * @see Math#random()
>        */
>       public static Double getRandom()
>       {
>           return new Double(Math.random());
>       }
>
>
>       /**
>        * This returns a random {@link Integer} within the
>        * specified range.  The return Integer will have a
>        * value greater than or equal to the first number
>        * and less than the second number.
>        *
>        * @param num1 the first number
>        * @param num2 the second number
>        * @return a pseudo-random {@link Integer} greater than
>        *         or equal to the first number and less than
>        *         the second
>        * @see #toInteger
>        * @see Math#random()
>        */
>       public static Integer random(Object num1, Object num2)
>       {
>           Integer i1 = toInteger(num1);
>           Integer i2 = toInteger(num2);
>           if (i1 == null || i2 == null)
>           {
>               return null;
>           }
>           //get the difference
>           double diff = i2.intValue() - i1.intValue();
>           //multiply the difference by a pseudo-random
>           //double from 0.0 to 1.0 and round to the nearest int
>           int random = (int)Math.rint(diff * Math.random());
>           //add the first value to the random int and return as an Integer
>           return new Integer(random + i1.intValue());
>       }
>
>
>   }
>
>
>
>   1.1
jakarta-velocity-tools/tools/src/java/org/apache/velocity/tools/tools/Parame
terParser.java
>
>   Index: ParameterParser.java
>   ===================================================================
>   /*
>    * The Apache Software License, Version 1.1
>    *
>    * Copyright (c) 2001 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", "Velocity", 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.velocity.tools.tools;
>
>   import org.apache.velocity.tools.view.tools.ThreadSafeContextTool;
>   import javax.servlet.ServletRequest;
>
>
>   /**
>    * Utility class for easy parsing of {@link ServletRequest} parameters
>    *
>    * @author <a href="mailto:sidler@teamup.com">Gabriel Sidler</a>
>    * @author <a href="mailto:nathan@esha.com">Nathan Bubna</a>
>    * @version $Revision: 1.1 $ $Date: 2002/04/03 09:10:03 $
>    */
>
>   public class ParameterParser implements ThreadSafeContextTool
>   {
>
>       /**
>        * Constructs a new instance
>        */
>       public ParameterParser()
>       {}
>
>
>       /**
>        * @param request the servlet request
>        * @param key the parameter's key
>        * @return parameter matching the specified key or
>        *         <code>null</code> if there is no matching
>        *         parameter
>        */
>       public static String getString(ServletRequest request, String key)
>       {
>           return request.getParameter(key);
>       }
>
>
>       /**
>        * @param request the servlet request
>        * @param the desired parameter's key
>        * @param the alternate value
>        * @return parameter matching the specified key or the
>        *         specified alternate String if there is no matching
>        *         parameter
>        */
>       public static String getString(ServletRequest request, String key,
String alternate)
>       {
>           String s = getString(request, key);
>           return (s != null) ? s : alternate;
>       }
>
>
>       /**
>        * @param request the servlet request
>        * @param the desired parameter's key
>        * @return a {@link Boolean} object for the specified key or
>        *         <code>null</code> if no matching parameter is found
>        */
>       public static Boolean getBoolean(ServletRequest request, String key)
>       {
>           String s = getString(request, key);
>           return (s != null) ? Boolean.valueOf(s) : null;
>       }
>
>
>       /**
>        * @param request the servlet request
>        * @param the desired parameter's key
>        * @param the alternate boolean value
>        * @return boolean value for the specified key or the
>        *         alternate boolean is no value is found
>        */
>       public static boolean getBoolean(ServletRequest request, String key,
boolean alternate)
>       {
>           Boolean bool = getBoolean(request, key);
>           return (bool != null) ? bool.booleanValue() : alternate;
>       }
>
>
>       /**
>        * @param request the servlet request
>        * @param the desired parameter's key
>        * @param the alternate {@link Boolean}
>        * @return a {@link Boolean} for the specified key or the specified
>        *         alternate if no matching parameter is found
>        */
>       public static Boolean getBoolean(ServletRequest request, String key,
Boolean alternate)
>       {
>           Boolean bool = getBoolean(request, key);
>           return (bool != null) ? bool : alternate;
>       }
>
>
>       /**
>        * @param request the servlet request
>        * @param the desired parameter's key
>        * @return a {@link Number} for the specified key or
>        *         <code>null</code> if no matching parameter is found
>        */
>       public static Number getNumber(ServletRequest request, String key)
>       {
>           String s = getString(request, key);
>           if (s == null || s.length() == 0)
>           {
>               return null;
>           }
>           if (s.indexOf('.') >= 0)
>           {
>               return new Double(s);
>           }
>           return new Long(s);
>       }
>
>
>       /**
>        * @param request the servlet request
>        * @param the desired parameter's key
>        * @param the alternate Number
>        * @return a Number for the specified key or the specified
>        *         alternate if no matching parameter is found
>        */
>       public static Number getNumber(ServletRequest request, String key,
Number alternate)
>       {
>           Number n = getNumber(request, key);
>           return (n != null) ? n : alternate;
>       }
>
>
>       /**
>        * @param request the servlet request
>        * @param the desired parameter's key
>        * @param the alternate int value
>        * @return the int value for the specified key or the specified
>        *         alternate value if no matching parameter is found
>        */
>       public static int getInt(ServletRequest request, String key, int
alternate)
>       {
>           Number n = getNumber(request, key);
>           return (n != null) ? n.intValue() : alternate;
>       }
>
>
>       /**
>        * @param request the servlet request
>        * @param the desired parameter's key
>        * @param the alternate double value
>        * @return the double value for the specified key or the specified
>        *         alternate value if no matching parameter is found
>        */
>       public static double getDouble(ServletRequest request, String key,
double alternate)
>       {
>           Number n = getNumber(request, key);
>           return (n != null) ? n.doubleValue() : alternate;
>       }
>
>
>       /**
>        * @param request the servlet request
>        * @param the key for the desired parameter
>        * @return an array of String objects containing all of the values
>        *         the given request parameter has, or <code>null</code>
>        *         if the parameter does not exist
>        */
>       public static String[] getStrings(ServletRequest request, String
key)
>       {
>           return request.getParameterValues(key);
>       }
>
>
>       /**
>        * @param request the servlet request
>        * @param the key for the desired parameter
>        * @return an array of Number objects for the specified key or
>        *         <code>null</code> if the parameter does not exist or the
>        *         parameter does not contain Numbers.
>        */
>       public static Number[] getNumbers(ServletRequest request, String
key)
>       {
>           String[] strings = getStrings(request, key);
>           if (strings == null)
>           {
>               return null;
>           }
>
>           Number[] nums = new Number[strings.length];
>           try
>           {
>               for(int i=0; i<nums.length; i++)
>               {
>                   if (strings[i] != null && strings[i].length() > 0)
>                   {
>                       if (strings[i].indexOf('.') >= 0)
>                       {
>                           nums[i] = new Double(strings[i]);
>                       }
>                       else
>                       {
>                           nums[i] = new Long(strings[i]);
>                       }
>                   }
>               }
>           }
>           catch (NumberFormatException nfe)
>           {
>               return null;
>           }
>           return nums;
>       }
>
>
>       /**
>        * @param request the servlet request
>        * @param the key for the desired parameter
>        * @return an array of int values for the specified key or
>        *         <code>null</code> if the parameter does not exist or the
>        *         parameter does not contain ints.
>        */
>       public static int[] getInts(ServletRequest request, String key)
>       {
>           String[] strings = getStrings(request, key);
>           if (strings == null)
>           {
>               return null;
>           }
>
>           int[] ints = new int[strings.length];
>           try
>           {
>               for(int i=0; i<ints.length; i++)
>               {
>                   if (strings[i] != null && strings[i].length() > 0)
>                   {
>                       ints[i] = Integer.parseInt(strings[i]);
>                   }
>               }
>           }
>           catch (NumberFormatException nfe)
>           {
>               return null;
>           }
>           return ints;
>       }
>
>
>       /**
>        * @param request the servlet request
>        * @param the key for the desired parameter
>        * @return an array of double values for the specified key or
>        *         <code>null</code> if the parameter does not exist or the
>        *         parameter does not contain doubles.
>        */
>       public static double[] getDoubles(ServletRequest request, String
key)
>       {
>           String[] strings = getStrings(request, key);
>           if (strings == null)
>           {
>               return null;
>           }
>
>           double[] doubles = new double[strings.length];
>           try
>           {
>               for(int i=0; i<doubles.length; i++)
>               {
>                   if (strings[i] != null && strings[i].length() > 0)
>                   {
>                       doubles[i] = Double.parseDouble(strings[i]);
>                   }
>               }
>           }
>           catch (NumberFormatException nfe)
>           {
>               return null;
>           }
>           return doubles;
>       }
>
>
>   }
>
>
>   1.1
jakarta-velocity-tools/tools/src/java/org/apache/velocity/tools/tools/ToolLo
ader.java
>
>   Index: ToolLoader.java
>   ===================================================================
>   /*
>    * The Apache Software License, Version 1.1
>    *
>    * Copyright (c) 2001 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", "Velocity", 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.velocity.tools.tools;
>
>   import org.apache.velocity.tools.view.context.ViewContext;
>   import org.apache.velocity.tools.view.tools.ContextContextTool;
>   import org.apache.velocity.tools.view.tools.LogEnabledContextToolImpl;
>   import org.apache.velocity.context.Context;
>
>
>   /**
>    * <p>A context tool that allows template designers to load
>    * other context tools from within the template. Any object
>    * with a public constructor without parameters can be used
>    * as a context tool.</p>
>    *
>    * <p>Example: Assuming that an instance of this class has
>    * been loaded into the Velocity context under key "toolloader",
>    * then from within a template a designer would call:<br>
>    * <br>
>    * <code>$toolloader.load("math", "xxx.yyy.zzz.MathTool")</code><br>
>    * <br>
>    * to load a math tool into the context under key "math". This tool
>    * is then available for use within the template, for example:<br>
>    * <br>
>    * <code>$math.random(1, 100)</code><br>
>    * </p>
>    *
>    * <p>THIS CLASS IS HERE AS A PROOF OF CONCEPT ONLY. IT NEEDS TO BE
>    * REFACTORED.</p>
>    *
>    * @author <a href="mailto:sidler@teamup.com">Gabe Sidler</a>
>    * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
>    *
>    * @version $Id: ToolLoader.java,v 1.1 2002/04/03 09:10:03 sidler Exp $
>    *
>    */
>
>   public class ToolLoader extends LogEnabledContextToolImpl
>       implements ContextContextTool
>   {
>
>       // --------------------------------------------
Properties ----------------
>
>       /**
>        * <p>A reference to the Velocity context.</p>
>        */
>       private Context ctx;
>
>
>
>       // --------------------------------------------
Constructors --------------
>
>       /**
>        * Returns a factory for instances of this class. Use method
>        * {@link #getInstance(Context context)} to obtain instances
>        * of this class. Do not use instance obtained from this method
>        * in templates. They are not properly initialized.
>        */
>       public ToolLoader()
>       {
>       }
>
>
>       /**
>        * Contructor for internal use only.
>        */
>       private ToolLoader(Context context)
>       {
>           this.ctx = context;
>       }
>
>
>
>       // --------------------------------------- Interface
ContextContextTool ---
>
>       /**
>        * Returns an initialized instance of this context tool.
>        */
>       public Object getInstance(Context context)
>       {
>           return new ToolLoader(context);
>       }
>
>
>
>       // -------------------------------------------- Public Utility
Methods ----
>
>       /**
>        * <p>Loads a context tool of class <i>clazz</i> and inserts it
>        * into the Velocity context with key <i>key</i>. On order to be
>        * loadable, context tools must provide a constructor with no
>        * parameters. The life cycle of a context tool loaded using
>        * this method is the current request.</p>
>        *
>        * @param key the key used to add the tool to the context
>        * @param clazz the fully qualified class name of the tool that
>        *     is to be instantiated and added to the context
>        */
>       public void load(String key, String clazz)
>       {
>           try
>           {
>               Object tool = Class.forName(clazz).newInstance();
>               ctx.put(key, tool);
>               log(INFO, "Loaded tool: Key: " + key + " Class: " + clazz);
>           }
>           catch (Exception e)
>           {
>               log(ERROR, "Error loading context tool: " + clazz + " with
key: " + key + ". " + e);
>           }
>       }
>
>   }
>
>
>
>   1.1
jakarta-velocity-tools/tools/src/java/org/apache/velocity/tools/tools/packag
e.html
>
>   Index: package.html
>   ===================================================================
>   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
>   <html>
>   <head>
>   <!--
>
>     These are Javadoc package comments.
>
>   -->
>   </head>
>   <body bgcolor="white">
>
>   Contains a collection of reusable, general-purpose Velocity context
tools. Where applicable
>   tools are optimized to be used in conjunction with a toolbox manager.
>
>   <!--
>   ##### THIS IS THE TEMPLATE FOR THE PACKAGE DOC COMMENTS. #####
>   ##### TYPE YOUR PACKAGE COMMENTS HERE.  BEGIN WITH A     #####
>   ##### ONE-SENTENCE SUMMARY STARTING WITH A VERB LIKE:    #####
>   Provides for....
>   -->
>
>   <h2>Package Specification</h2>
>
>   <!--
>   ##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT #####
>   <ul>
>     <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE
#####</a>
>   </ul>
>   -->
>
>   <h2>Related Documentation</h2>
>
>   <!--
>   For overviews, tutorials, examples, guides, and tool documentation,
please see:
>   <ul>
>     <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a>
>   </ul>
>   -->
>
>   <!-- Put @see and @since tags down here. -->
>
>   </body>
>   </html>
>
>
>
>   1.1                  jakarta-velocity-tools/tools/xdocs/DateTool.xml
>
>   Index: DateTool.xml
>   ===================================================================
>   <?xml version="1.0"?>
>
>   <document>
>
>       <properties>
>           <title>DateTool</title>
>           <author email="sidler@apache.org">Gabriel Sidler</author>
>           <projectfile>../xdocs/vellibrary-menue.xml</projectfile>
>       </properties>
>
>       <body>
>
>       <section name="DateTool Reference Documentation">
>
>           <p>
>           Tool for manipulating <code>java.util.Date</code> and
<code>java.util.Calendar</code>
>           objects in Velocity templates. It supports locales to format
dates language
>           and country specific.
>           </p>
>
>           <toolinfo>
>               <version>@@@version@@@, @@@date@@@</version>
>
>               <jar>velocity-tools-library-@@@version@@@.jar</jar>
>
>               <clazz>org.apache.velocity.tools.tools.DateTool</clazz>
>
>               <name>$dateTool</name>
>
>               <author email="sidler@apache.org">Gabriel Sidler</author>
>               <author email="nathan@esha.com">Nathan Bubna</author>
>
>               <config-example>&lt;tool&gt;
>     &lt;key&gt;dateTool&lt;/key&gt;
>     &lt;class&gt;org.apache.velocity.tools.tools.DateTool&lt;/class&gt;
>   &lt;/tool&gt;</config-example>
>
>           </toolinfo>
>
>           <methods/>
>
>       </section>
>
>       <section name="getDate()">
>           <method name="getDate()">
>
>               <abstract>
>                   Returns a Date object representing the time at which
this
>                   method was invoked.
>               </abstract>
>
>               <signature>
>                   String getDate()
>               </signature>
>
>               <signature>
>                   String getDate(Locale locale)
>               </signature>
>
>               <parameters>
>                   <parameter name="locale">
>                       An object of class <code>java.util.Locale</code>
that represents the locale
>                       to be used to create the date.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   An object of class <code>java.util.Date</code>
representing the time at which this
>                   method was invoked in the specified locale. If no locale
is specified,
>                   the system's default locale is used.
>               </returns>
>
>           </method>
>       </section>
>
>
>       <section name="getCalendar()">
>           <method name="getCalendar()">
>
>               <abstract>
>                   Returns a Calendar object representing the time at which
this
>                   method was invoked.
>               </abstract>
>
>               <signature>
>                   String getCalendar()
>               </signature>
>
>               <signature>
>                   String getCalendar(Locale locale)
>               </signature>
>
>               <parameters>
>                   <parameter name="locale">
>                       An object of class <code>java.util.Locale</code>
that represents the locale
>                       to be used to create the calendar.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   An object of class <code>java.util.Calendar</code>
representing the time at which this
>                   method was invoked in the specified locale. If no locale
is specified,
>                   the system's default locale is used.
>               </returns>
>
>           </method>
>       </section>
>
>
>       <section name="format()">
>           <method name="format()">
>
>               <abstract>
>                   Returns a formatted string representing the specified
date.
>               </abstract>
>
>               <signature>
>                   String format(String format, Object obj)
>               </signature>
>
>               <signature>
>                   String format(String format, Object obj, Locale locale)
>               </signature>
>
>               <parameters>
>                   <parameter name="format">
>                       A string that represents the formatting instructions
according to
>                       <code>java.text.SimpleDateFormat</code>. See also
below.
>                   </parameter>
>
>                   <parameter name="obj">
>                       An object of class <code>java.util.Date</code> or
<code>java.util.Calendar</code>. It is
>                       also possible to pass a string that represents a
parsable date
>                       according to <code>java.text.DateFormat</code>.
>                   </parameter>
>
>                   <parameter name="locale">
>                       An object of class <code>java.util.Locale</code>
that represents the locale
>                       to format the date for.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   The formatted date string in the specified locale or
<code>null</code>
>                   if one or several input parameters are invalid. If no
locale is specified,
>                   the system's default locale is used instead.
>               </returns>
>
>               <description>
>                   <p>This methods use the same formatting instructions as
class
>                   <code>java.text.SimpleDateFormat</code>.</p>
>
>   <sourcecode>
>   Symbol   Meaning                 Presentation        Example
>   ------   -------                 ------------        -------
>   G        era designator          (Text)              AD
>   y        year                    (Number)            1996
>   M        month in year           (Text &amp; Number)     July &amp; 07
>   d        day in month            (Number)            10
>   h        hour in am/pm (1~12)    (Number)            12
>   H        hour in day (0~23)      (Number)            0
>   m        minute in hour          (Number)            30
>   s        second in minute        (Number)            55
>   S        millisecond             (Number)            978
>   E        day in week             (Text)              Tuesday
>   D        day in year             (Number)            189
>   F        day of week in month    (Number)            2 (2nd Wed in July)
>   w        week in year            (Number)            27
>   W        week in month           (Number)            2
>   a        am/pm marker            (Text)              PM
>   k        hour in day (1~24)      (Number)            24
>   K        hour in am/pm (0~11)    (Number)            0
>   z        time zone               (Text)              Pacific Standard
Time
>   '        escape for text         (Delimiter)
>   ''       single quote            (Literal)           '
>
>   Examples: "E, MMMM d" will result in "Tue, July 24"
>             "EEE, M-d (H:m)" will result in "Tuesday, 7-24 (14:12)"
>   </sourcecode>
>
>               </description>
>
>           </method>
>       </section>
>
>
>
>       <section name="toDate()">
>           <method name="toDate()">
>
>               <abstract>
>                   Returns a Date object representing the specified date.
>               </abstract>
>
>               <signature>
>                   Date toDate(Object obj)
>               </signature>
>
>               <parameters>
>                   <parameter name="obj">
>                       The date to convert. The parameter can be an object
of class
>                       <code>java.util.Date</code> or
<code>java.util.Calendar</code>. It is also possible to
>                       pass a string that represents a parsable date
according to
>                       <code>java.text.DateFormat</code>.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   An object of class <code>java.util.Date</code>
representing the converted date
>                   or <null></null> of the input parameter is invalid.
>               </returns>
>
>           </method>
>       </section>
>
>
>       <section name="toCalendar()">
>           <method name="toCalendar()">
>
>               <abstract>
>                   Returns a Calendar object representing the specified
date.
>               </abstract>
>
>               <signature>
>                   Calendar toCalendar(Object obj)
>               </signature>
>
>               <parameters>
>                   <parameter name="obj">
>                       The date to convert. The parameter can be an object
of class
>                       <code>java.util.Date</code> or
<code>java.util.Calendar</code>. It is also possible to
>                       pass a string that represents a parsable date
according to
>                       <code>java.text.DateFormat</code>.
>                   </parameter>
>                </parameters>
>
>               <returns>
>                   An object of class <code>java.util.Calendar</code>
representing the converted date
>                   or <null></null> of the input parameter is invalid.
>               </returns>
>
>           </method>
>       </section>
>
>
>
>    </body>
>   </document>
>
>
>
>
>   1.1                  jakarta-velocity-tools/tools/xdocs/MathTool.xml
>
>   Index: MathTool.xml
>   ===================================================================
>   <?xml version="1.0"?>
>
>   <document>
>
>       <properties>
>           <title>MathTool</title>
>           <author email="sidler@apache.org">Gabriel Sidler</author>
>           <projectfile>../xdocs/vellibrary-menue.xml</projectfile>
>       </properties>
>
>       <body>
>
>       <section name="MathTool Reference Documentation">
>
>           <p>Tool for performing floating point math in Velocity.</p>
>
>           <p>A few things to note:</p>
>
>           <ul>
>               <li>Most methods return numbers wrapped as Double
>                   which automatically render the decimal places even
>                   for whole numbers (e.g. new Double(1).toString() ->
'1.0').
>                   This is intentional. This tool is for floating
>                   point arithmetic. Integer arithmetic is already
supported
>                   by the Velocity template language. If you really need
'1'
>                   instead of '1.0', just call intValue() on the
result.</li>
>               <li>No null pointer, number format, or divide by zero
>                   exceptions are thrown here. This is because such
exceptions
>                   halt template rendering. It should be sufficient
debugging
>                   feedback that Velocity will render the reference
>                   literally. (e.g. $math.div(1, 0) renders as
'$math.div(1, 0)')</li>
>               <li>Class <code>java.lang.Math</code> is used to perform the
>                   mathematical operations.</li>
>           </ul>
>
>           <toolinfo>
>               <version>@@@version@@@, @@@date@@@</version>
>               <jar>velocity-tools-library-@@@version@@@.jar</jar>
>               <clazz>org.apache.velocity.tools.tools.MathTool</clazz>
>               <name>$math</name>
>               <author email="nathan@esha.com">Nathan Bubna</author>
>               <config-example>&lt;tool&gt;
>     &lt;key&gt;math&lt;/key&gt;
>     &lt;class&gt;org.apache.velocity.tools.tools.MathTool&lt;/class&gt;
>   &lt;/tool&gt;</config-example>
>           </toolinfo>
>
>           <methods/>
>
>       </section>
>
>       <section name="add()">
>           <method name="add()">
>
>               <abstract>
>                   Addition
>               </abstract>
>
>               <signature>
>                   Double add(Object num1, Object num2)
>               </signature>
>
>               <parameters>
>                   <parameter name="num1, num2">
>                       Operands of the addition. Valid input is any number
(primitive
>                       types or objects, Velocity automatically converts
primitives types
>                       to objects) or a string representation of a number.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   A <code>java.lang.Double</code> representing the sum or
<code>null</code> if the input
>                   paramters are not valid.
>               </returns>
>
>           </method>
>       </section>
>
>
>       <section name="sub()">
>           <method name="sub()">
>
>               <abstract>
>                   Subtraction
>               </abstract>
>
>               <signature>
>                   Double sub(Object num1, Object num2)
>               </signature>
>
>               <parameters>
>                   <parameter name="num1, num2">
>                       Operands of the subtraction. Valid input is any
number (primitive
>                       types or objects, Velocity automatically converts
primitives types
>                       to objects) or a string representation of a number.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   A <code>java.lang.Double</code> representing the result
of the subtraction
>                   or <code>null</code> if the input paramters are not
valid.
>               </returns>
>
>           </method>
>       </section>
>
>
>       <section name="mul()">
>           <method name="mul()">
>
>               <abstract>
>                   Multiplication
>               </abstract>
>
>               <signature>
>                   Double mul(Object num1, Object num2)
>               </signature>
>
>               <parameters>
>                   <parameter name="num1, num2">
>                       Factors of the multiplication. Valid input is any
number (primitive
>                       types or objects, Velocity automatically converts
primitives types
>                       to objects) or a string representation of a number.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   A <code>java.lang.Double</code> representing the result
of the multiplication
>                   or <code>null</code> if the input paramters are not
valid.
>               </returns>
>
>           </method>
>       </section>
>
>
>       <section name="div()">
>           <method name="div()">
>
>               <abstract>
>                   Division
>               </abstract>
>
>               <signature>
>                   Double div(Object num1, Object num2)
>               </signature>
>
>               <parameters>
>                   <parameter name="num1, num2">
>                       Input for the division. Valid input is any number
(primitive
>                       types or objects, Velocity automatically converts
primitives types
>                       to objects) or a string representation of a number.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   A <code>java.lang.Double</code> representing the result
of the division
>                   or <code>null</code> if the input paramters are not
valid.
>               </returns>
>
>           </method>
>       </section>
>
>
>       <section name="pow()">
>           <method name="pow()">
>
>               <abstract>
>                   Power of
>               </abstract>
>
>               <signature>
>                   Double pow(Object num1, Object num2)
>               </signature>
>
>               <parameters>
>                   <parameter name="num1, num2">
>                       Operands. Valid input is any number (primitive
>                       types or objects, Velocity automatically converts
primitives types
>                       to objects) or a string representation of a number.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   A <code>java.lang.Double</code> representing the first
number raised to
>                   the power of the second or <code>null</code> if the
input paramters are not valid.
>               </returns>
>
>          </method>
>       </section>
>
>
>
>       <section name="max()">
>           <method name="max()">
>
>               <abstract>
>                   Maximum of two numbers
>               </abstract>
>
>               <signature>
>                   Double max(Object num1, Object num2)
>               </signature>
>
>               <parameters>
>                   <parameter name="num1, num2">
>                       Operands. Valid input is any number (primitive
>                       types or objects, Velocity automatically converts
primitives types
>                       to objects) or a string representation of a number.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   A <code>java.lang.Double</code> representing the maximum
of the two
>                   numbers or <code>null</code> if the input paramters are
not valid.
>               </returns>
>
>          </method>
>       </section>
>
>
>
>       <section name="min()">
>           <method name="min()">
>
>               <abstract>
>                   Minimum of two numbers
>               </abstract>
>
>               <signature>
>                   Double min(Object num1, Object num2)
>               </signature>
>
>               <parameters>
>                   <parameter name="num1, num2">
>                       Operands. Valid input is any number (primitive
>                       types or objects, Velocity automatically converts
primitives types
>                       to objects) or a string representation of a number.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   A <code>java.lang.Double</code> representing the minimum
of the two
>                   numbers or <code>null</code> if the input paramters are
not valid.
>               </returns>
>
>          </method>
>       </section>
>
>
>
>
>       <section name="abs()">
>           <method name="max()">
>
>               <abstract>
>                   Absolute value of a number
>               </abstract>
>
>               <signature>
>                   Double abs(Object num)
>               </signature>
>
>               <parameters>
>                   <parameter name="num1, num2">
>                       Operand. Valid input is any number (primitive
>                       types or objects, Velocity automatically converts
primitives types
>                       to objects) or a string representation of a number.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   A <code>java.lang.Double</code> representing the
absolute value of the
>                   input or <code>null</code> if the input paramter is not
valid.
>               </returns>
>
>          </method>
>       </section>
>
>
>
>
>       <section name="toDouble()">
>           <method name="toDouble()">
>
>               <abstract>
>                   Converts a number into a double.
>               </abstract>
>
>               <signature>
>                   Double toDouble(Object num)
>               </signature>
>
>               <parameters>
>                   <parameter name="num">
>                       Operand. Valid input is any number (primitive
>                       types or objects, Velocity automatically converts
primitives types
>                       to objects) or a string representation of a number.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   A <code>java.lang.Double</code> representing the input
number or
>                   <code>null</code> if the input paramter is not valid.
>               </returns>
>
>          </method>
>       </section>
>
>
>
>       <section name="toInteger()">
>           <method name="toInteger()">
>
>               <abstract>
>                   Converts a number into an integer
>               </abstract>
>
>               <signature>
>                   Integer toInteger(Object num)
>               </signature>
>
>               <parameters>
>                   <parameter name="num">
>                       Operand. Valid input is any number (primitive
>                       types or objects, Velocity automatically converts
primitives types
>                       to objects) or a string representation of a number.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   A <code>java.lang.Integer</code> representing the input
number or
>                   <code>null</code> if the input paramter is not valid.
>               </returns>
>
>          </method>
>       </section>
>
>
>
>       <section name="roundTo()">
>           <method name="roundTo()">
>
>               <abstract>
>                   Rounds a number to the specified number of decimal
places
>               </abstract>
>
>               <signature>
>                   Double roundTo(Object decimals, Object num)
>               </signature>
>
>               <parameters>
>                   <parameter name="decimals">
>                       The number of decimal places. Valid input is any
number (primitive
>                       types or objects, Velocity automatically converts
primitives types
>                       to objects) or a string representation of a number.
>                   </parameter>
>
>                   <parameter name="num">
>                       The number to round. Valid input is any number
(primitive
>                       types or objects, Velocity automatically converts
primitives types
>                       to objects) or a string representation of a number.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   A <code>java.lang.Double</code> representing the input
number
>                   rounded to the specified number of decimal places or
>                   <code>null</code> if the input paramter is not valid.
>               </returns>
>
>               <description>
>                   <p>This method is particulary useful for simple display
formatting.
>                   If you want to round an number to the nearest integer,
it
>                   is better to use method <code><a
href="#roundToInt()">roundToInt()</a></code>,
>                   as that will return an <code>java.lang.Integer</code>
rather than
>                   a <code>java.lang.Double</code>.</p>
>               </description>
>
>           </method>
>       </section>
>
>
>       <section name="roundToInt()">
>           <method name="roundToInt()">
>
>               <abstract>
>                   Rounds a number to the nearest whole Integer
>               </abstract>
>
>               <signature>
>                   Integer roundToInt(Object num)
>               </signature>
>
>               <parameters>
>                   <parameter name="num">
>                       The number to round. Valid input is any number
(primitive
>                       types or objects, Velocity automatically converts
primitives types
>                       to objects) or a string representation of a number.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   A <code>java.lang.Integer</code> representing the input
number
>                   rounded to nearest whole Integer or <code>null</code> if
the input paramter is not valid.
>               </returns>
>
>           </method>
>       </section>
>
>
>
>       <section name="getRandom()">
>           <method name="getRandom()">
>
>               <abstract>
>                   Returns a pseudo-random number
>               </abstract>
>
>               <signature>
>                   Double getRandom()
>               </signature>
>
>               <returns>
>                   A <code>java.lang.Double</code>
>                   greater than or equal to 0.0 and less than 1.0.
>               </returns>
>
>          </method>
>       </section>
>
>
>
>       <section name="random()">
>           <method name="random()">
>
>               <abstract>
>                   Returns a pseudo-random number in a configurable range
>               </abstract>
>
>               <signature>
>                   Integer random(Object num1, Object num2)
>               </signature>
>
>               <parameters>
>                   <parameter name="num1, num2">
>                       First and last number of range. Valid input is any
number (primitive
>                       types or objects, Velocity automatically converts
primitives types
>                       to objects) or a string representation of a number.
>                   </parameter>
>               </parameters>
>
>               <returns>
>                   A <code>java.lang.Integer</code> greater than or equal
to the first
>                   number and less than the second number or
<code>null</code> if the input paramter
>                   is not valid.
>               </returns>
>
>           </method>
>       </section>
>
>    </body>
>   </document>
>
>
>
>
>   1.1
jakarta-velocity-tools/tools/xdocs/ParameterParser.xml
>
>   Index: ParameterParser.xml
>   ===================================================================
>   <?xml version="1.0"?>
>
>   <document>
>
>       <properties>
>           <title>ParameterParser</title>
>           <author email="sidler@apache.org">Gabriel Sidler</author>
>           <projectfile>../xdocs/vellibrary-menue.xml</projectfile>
>       </properties>
>
>       <body>
>
>       <section name="ParameterParser Reference Documentation">
>
>           <p>Context tool for easy parsing of ServletRequest
parameters.</p>
>
>           <toolinfo>
>               <version>@@@version@@@, @@@date@@@</version>
>
>               <jar>velocity-tools-library-@@@version@@@.jar</jar>
>
>
<clazz>org.apache.velocity.tools.tools.ParameterParser</clazz>
>
>               <name>$reqParser</name>
>
>               <author email="nathan@esha.com">Nathan Bubna</author>
>
>               <config-example>&lt;tool&gt;
>     &lt;key&gt;reqParser&lt;/key&gt;
>
&lt;class&gt;org.apache.velocity.tools.tools.RequestParser&lt;/class&gt;
>   &lt;/tool&gt;</config-example>
>
>           </toolinfo>
>
>           <methods/>
>
>       </section>
>
>       <section name="getString()">
>           <method name="getString()">
>
>               <abstract>
>                   Returns the specified servlet request parameter as a
String
>               </abstract>
>
>               <signature>
>                   String getString(ServletRequest request, String key)
>               </signature>
>
>               <signature>
>                   String getString(ServletRequest request, String key,
String alternate)
>               </signature>
>
>               <parameters>
>                   <parameter name="request">
>                       The servlet request of class
<code>javax.servlet.ServletRequest</code>
>                   </parameter>
>
>                   <parameter name="key">
>                       The key of the desired string parameter
>                   </parameter>
>
>                   <parameter name="alternate">
>                       An alternate value
>                   </parameter>
>               </parameters>
>
>               <returns>
>                  The value of the parameter matching the specified key or
the
>                  specified alternate String if there is no matching
parameter.
>                  A value of <code>null</code> is returned if no alternate
value
>                  is defined and the desired parameter is not found.
>               </returns>
>
>           </method>
>       </section>
>
>
>
>       <section name="getBoolean()">
>           <method name="getBoolean()">
>
>               <abstract>
>                   Returns the specified servlet request parameter as a
Boolean object or
>                   a boolean primitive type
>               </abstract>
>
>               <signature>
>                   Boolean getBoolean(ServletRequest request, String key)
>               </signature>
>
>               <signature>
>                   Boolean getBoolean(ServletRequest request, String key,
Boolean alternate)
>               </signature>
>
>               <signature>
>                   boolean getBoolean(ServletRequest request, String key,
boolean alternate)
>               </signature>
>
>               <parameters>
>                   <parameter name="request">
>                       The servlet request of class
<code>javax.servlet.ServletRequest</code>
>                   </parameter>
>
>                   <parameter name="key">
>                       The key of the desired string parameter
>                   </parameter>
>
>                   <parameter name="alternate">
>                       An alternate value
>                   </parameter>
>               </parameters>
>
>               <returns>
>                  A Boolean object or boolean primitive type that
represents the
>                  value of the servlet request parameter matching the
specified key
>                  or the specified alternate boolean if there is no
matching parameter.
>                  A value of <code>null</code> is returned if no alternate
value
>                  is defined and the desired parameter is not found.
>               </returns>
>
>           </method>
>       </section>
>
>
>
>
>       <section name="getNumber()">
>           <method name="getNumber()">
>
>               <abstract>
>                   Returns the specified servlet request parameter as a
Number object
>               </abstract>
>
>               <signature>
>                   Number getNumber(ServletRequest request, String key)
>               </signature>
>
>               <signature>
>                   Number getNumber(ServletRequest request, String key,
Number alternate)
>               </signature>
>
>               <parameters>
>                   <parameter name="request">
>                       The servlet request of class
<code>javax.servlet.ServletRequest</code>
>                   </parameter>
>
>                   <parameter name="key">
>                       The key of the desired string parameter
>                   </parameter>
>
>                   <parameter name="alternate">
>                       An alternate value
>                   </parameter>
>               </parameters>
>
>               <returns>
>                  A <code>java.lang.Number</code> object that represents
the
>                  value of the servlet request parameter matching the
specified key
>                  or the specified alternate Number if there is no matching
parameter.
>                  A value of <code>null</code> is returned if no alternate
value
>                  is defined and the desired parameter is not found.
>               </returns>
>
>           </method>
>       </section>
>
>
>
>       <section name="getInt()">
>           <method name="getInt()">
>
>               <abstract>
>                   Returns the specified servlet request parameter as an
integer
>               </abstract>
>
>               <signature>
>                   int getInt(ServletRequest request, String key, int
alternate)
>               </signature>
>
>               <parameters>
>                   <parameter name="request">
>                       The servlet request of class
<code>javax.servlet.ServletRequest</code>
>                   </parameter>
>
>                   <parameter name="key">
>                       The key of the desired string parameter
>                   </parameter>
>
>                   <parameter name="alternate">
>                       An alternate value
>                   </parameter>
>               </parameters>
>
>               <returns>
>                  An integer that represents the
>                  value of the servlet request parameter matching the
specified key
>                  or the specified alternate value if there is no matching
parameter.
>               </returns>
>
>           </method>
>       </section>
>
>
>
>
>       <section name="getDouble()">
>           <method name="getDouble()">
>
>               <abstract>
>                   Returns the specified servlet request parameter as a
double
>               </abstract>
>
>               <signature>
>                   double getDouble(ServletRequest request, String key,
double alternate)
>               </signature>
>
>               <parameters>
>                   <parameter name="request">
>                       The servlet request of class
<code>javax.servlet.ServletRequest</code>
>                   </parameter>
>
>                   <parameter name="key">
>                       The key of the desired string parameter
>                   </parameter>
>
>                   <parameter name="alternate">
>                       An alternate value
>                   </parameter>
>               </parameters>
>
>               <returns>
>                  An double that represents the
>                  value of the servlet request parameter matching the
specified key
>                  or the specified alternate value if there is no matching
parameter.
>               </returns>
>
>           </method>
>       </section>
>
>
>
>       <section name="getStrings()">
>           <method name="getStrings()">
>
>               <abstract>
>                   Returns an array of Strings of all the values of the
specified servlet
>                   request parameter
>               </abstract>
>
>               <signature>
>                   String[] getStrings(ServletRequest request, String key)
>               </signature>
>
>               <parameters>
>                   <parameter name="request">
>                       The servlet request of class
<code>javax.servlet.ServletRequest</code>
>                   </parameter>
>
>                   <parameter name="key">
>                       The key of the desired string parameter
>                   </parameter>
>
>               </parameters>
>
>               <returns>
>                  A array of Strings that represent all the values of the
desired
>                  request parameter or <code>null</code> if the parameter
does not
>                  exist.
>               </returns>
>
>           </method>
>       </section>
>
>
>
>
>       <section name="getNumbers()">
>           <method name="getNumbers()">
>
>               <abstract>
>                   Returns an array of Numbers of all the values of the
specified servlet
>                   request parameter
>               </abstract>
>
>               <signature>
>                   Number[] getNumbers(ServletRequest request, String key)
>               </signature>
>
>               <parameters>
>                   <parameter name="request">
>                       The servlet request of class
<code>javax.servlet.ServletRequest</code>
>                   </parameter>
>
>                   <parameter name="key">
>                       The key of the desired string parameter
>                   </parameter>
>
>               </parameters>
>
>               <returns>
>                  A array of <code>java.lang.Number</code> that represent
all the
>                  values of the desired request parameter or
<code>null</code> if
>                  the parameter does not exist.
>               </returns>
>
>           </method>
>       </section>
>
>
>
>
>       <section name="getInts()">
>           <method name="getInts()">
>
>               <abstract>
>                   Returns an array of integers of all the values of the
specified servlet
>                   request parameter
>               </abstract>
>
>               <signature>
>                   int[] getInts(ServletRequest request, String key)
>               </signature>
>
>               <parameters>
>                   <parameter name="request">
>                       The servlet request of class
<code>javax.servlet.ServletRequest</code>
>                   </parameter>
>
>                   <parameter name="key">
>                       The key of the desired string parameter
>                   </parameter>
>
>               </parameters>
>
>               <returns>
>                  A array of integer primitive types that represent all the
>                  values of the desired request parameter or
<code>null</code> if
>                  the parameter does not exist.
>               </returns>
>
>           </method>
>       </section>
>
>
>
>
>       <section name="getDoubles()">
>           <method name="getDoubles()">
>
>               <abstract>
>                   Returns an array of doubles of all the values of the
specified servlet
>                   request parameter
>               </abstract>
>
>               <signature>
>                   double[] getDoubles(ServletRequest request, String key)
>               </signature>
>
>               <parameters>
>                   <parameter name="request">
>                       The servlet request of class
<code>javax.servlet.ServletRequest</code>
>                   </parameter>
>
>                   <parameter name="key">
>                       The key of the desired string parameter
>                   </parameter>
>
>               </parameters>
>
>               <returns>
>                  A array of double primitive types that represent all the
>                  values of the desired request parameter or
<code>null</code> if
>                  the parameter does not exist.
>               </returns>
>
>           </method>
>       </section>
>
>
>    </body>
>   </document>
>
>
>
>
>   1.1                  jakarta-velocity-tools/tools/xdocs/ToolLoader.xml
>
>   Index: ToolLoader.xml
>   ===================================================================
>   <?xml version="1.0"?>
>
>   <document>
>
>       <properties>
>           <title>ToolLoader</title>
>           <author email="sidler@apache.org">Gabriel Sidler</author>
>           <projectfile>../xdocs/vellibrary-menue.xml</projectfile>
>       </properties>
>
>       <body>
>
>       <section name="ToolLoader Reference Documentation">
>
>           <p>
>           A context tool that allows template designers to load context
tools
>           from within the template. Any object with a public constructor
without
>           parameters can be loaded into the context.
>           </p>
>
>           <toolinfo>
>               <version>@@@version@@@, @@@date@@@</version>
>
>               <jar>velocity-tools-library-@@@version@@@.jar</jar>
>
>               <clazz>org.apache.velocity.tools.tools.ToolLoader</clazz>
>
>               <name>$toolLoader</name>
>
>               <author email="sidler@apache.org">Gabriel Sidler</author>
>
>               <config-example>&lt;tool&gt;
>     &lt;key&gt;toolLoader&lt;/key&gt;
>     &lt;class&gt;org.apache.velocity.tools.tools.ToolLoader&lt;/class&gt;
>   &lt;/tool&gt;</config-example>
>
>           </toolinfo>
>
>           <methods/>
>
>       </section>
>
>       <section name="load()">
>           <method name="load()">
>
>               <abstract>
>                   Loads a context tool and inserts it into the Velocity
context.
>               </abstract>
>
>               <signature>
>                   void load(String key, String class)
>               </signature>
>
>               <parameters>
>                   <parameter name="key">
>                       The key string used to insert to newly instantiated
tool
>                       into the Velocity context.
>                   </parameter>
>
>                   <parameter name="class">
>                       The name of the class to instantiate.
>                   </parameter>
>               </parameters>
>
>               <description>
>                   <p>Loads a context tool of class <i>class</i> and
inserts it
>                   into the Velocity context with key <i>key</i>. On order
to be
>                   loadable, context tools must provide a public
constructor with no
>                   parameters.</p>
>                   <p>The life cycle of a context tool loaded using this
method is
>                   the current template request. The instance is processing
of the
>                   current template has been completet.</p>
>                   <p>If the specified class cannot be found or does not
have a
>                   public contructor without parameters, then the tool is
not loaded
>                   and an error message is written to the log.</p>
>
>                   <p>Application example:</p>
>   <sourcecode>$toolLoader("math",
"org.apache.velocity.tools.tools.MathTool")
>   $math.random(1,1000)</sourcecode>
>
>                   <p>Loads MathTool with name $math into the context.
Then, its random() function is
>                   used to generate a random number betweenn 1 and
1000.</p>
>               </description>
>
>           </method>
>       </section>
>
>
>    </body>
>   </document>
>
>
>
>
>
> --
> 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: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Daniel Rall <dl...@finemaltcoding.com>.
Gabriel Sidler <si...@teamup.ch> writes:

> Daniel Rall wrote:
> ...
>
>> It's kinda of too bad your MessageTool is so tied to Struts (just as
>> mine in Turbine is tied to Fulcrum -- both our tools delegate the
>> request Accept-Language header parsing off to other code), as this new
>> package would be a great place for it.  It would be worth-while to
>> have some sort of I18N/L10N interface in this new package which
>> misc. localization tools can implement.
>
>
> I would be interested in exploring more into the direction that your
> MultiViewTools is going.

To be absolutely clear, the localization tool that I'm referring to is
almost exactly like the one you have written, and is in the Turbine
respository:

http://cvs.apache.org/viewcvs/jakarta-turbine-3/src/tool/org/apache/turbine/tool/LocalizationTool.java?rev=1&content-type=text/vnd.viewcvs-markup

The new MultiViewsTool is more focussed on content negotiation, rather
than message formatting for localization.

> My challenge is the follwing type of web app:
>
> - multiple languages
> - multiple skins
> - dynamic content

Within the same instance of an application, I don't often use multiple
skins.  However, each deployment of SourceCast is generally skinned to
the customer's specs.  Right there with you.  :-)

> How do I achieve to have all style, layout and content free of
> redundancy. And keep it easy to maintain. And achieve resonable
> performance. And all with Velocity. I haven't seen a solution to
> that.

I've found that Velocity performance is quite good (with caching on).
At this point, it's the underlying libraries which are the bottleneck.

I haven't looked how this maps into the interals of Velocity yet, but
I got one really good suggestion from JavaOne which we can apply to
localization of high traffic applications.  It was strongly recommend
that one avoid Java's character to byte conversion routines using
caching.  Before I heard that, Ed Korthof, Jon Stevens, and myself had
run some tests for the MM MySQL JDBC driver and discovered that when
Java's encoding conversion routines were not explicitly avoid,
throughput was degraded by a factor of 10 (!!!).  I was wondering if
snapping a byte[] cache onto Velocity would be possible, so that the
expensive encoding routines could be avoided after the first hit.  The
expense of this is added complexity and memory usage (as output must
be cached for each encoding), but on an enterprise site the
performance gains might very well out weigh these issues.

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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Gabriel Sidler <si...@teamup.ch>.
Daniel Rall wrote:
...

> It's kinda of too bad your MessageTool is so tied to Struts (just as
> mine in Turbine is tied to Fulcrum -- both our tools delegate the
> request Accept-Language header parsing off to other code), as this new
> package would be a great place for it.  It would be worth-while to
> have some sort of I18N/L10N interface in this new package which
> misc. localization tools can implement.


I would be interested in exploring more into the direction that your
MultiViewTools is going. My challenge is the follwing type of web app:

- multiple languages
- multiple skins
- dynamic content

How do I achieve to have all style, layout and content free of
redundancy. And keep it easy to maintain. And achieve resonable
performance. And all with Velocity. I haven't seen a solution to
that.


Gabe



--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Daniel Rall <dl...@finemaltcoding.com>.
sidler@apache.org writes:

> sidler      02/04/03 01:10:03
>
>   Added:       tools    README.txt build.xml
>                tools/lib jdbc2_0-stdext.jar servlet.jar struts.jar
>                         velocity-tools-view-0.4.jar
>                tools/src/conf MANIFEST.MF
>                tools/src/java/org/apache/velocity/tools/tools DateTool.java
>                         MathTool.java ParameterParser.java ToolLoader.java
>                         package.html
>                tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml
>                         ToolLoader.xml
>   Log:
>   Added package tools. This is intended to host various reusable context
>   tools. Currently hosted tools are DateTool, MathTool, RequestParser and
>   ToolLoader. All tools are optimized to be used with an auto-loading toolbox
>   manager and come with documentation for the template designers. A
>   documentation snapshot is online at:
>   http://www.teamup.com/jakarta-velocity-tools/docs/vellibrary.html

It's kinda of too bad your MessageTool is so tied to Struts (just as
mine in Turbine is tied to Fulcrum -- both our tools delegate the
request Accept-Language header parsing off to other code), as this new
package would be a great place for it.  It would be worth-while to
have some sort of I18N/L10N interface in this new package which
misc. localization tools can implement.

Also, my MultiViewsTool content negotiation tool is in the view
package.  What distinction can we make to clearly show what types of
tools belong in which package (i.e. if it's view-related, does it
always go into view, or does it go into tools because it's a context
tool)?

- Dan

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


Re: cvs commit: jakarta-velocity-tools/tools/xdocsDateTool.xmlMathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Nathan Bubna <na...@esha.com>.
Geir said:
> But my impression is that this is getting a bit over-designed : I am going
> to read the whole thread tomorrow - but has everyone stood back and asked
> the question (or answered it) :
>
>    Is there anything we can remove?

yup, plenty if you ask me.

> I like very much the idea of placing few if any requirements on the
tools -
> that the toolbox descriptor should suffice -> I would want to be able to
> specify  java.lang.String as a tool and control where and how it was
used...

i agree.  i think my proposal (already implemented and submitted) for
putting scope-placement wholly to the config file and having two completely
optional interfaces--one for application tools and one for request/session
tools--should suffice.
if that's still too much stuff for you, i personally don't ever plan on
using the application tool interface i proposed (ServletContextTool), i only
think it is something that someone may want.  perhaps we should stick with
just the one interface i proposed for request/session tools
(ViewContextTool) and add the other later if someone actually wants it.

the issues of logging and pooling for tools are of secondary importance to
me.

> And I am afraid that outside of the Struts integration part, it's getting
> framework-ish...

heh.  that may be...  perhaps we should leave any special logging or pooling
for tools out.  after all, tools that implement either of my proposed
interfaces have access to the servlet context and can just log directly thru
that if need be.  other than that, logging can easily be left for developers
to implement on their own. also, i suppose we should think carefully before
implementing anything that will add new dependencies (such as pooling).

> However, these are just random thoughts at the end of a long day towards
the
> end of a long week at the beginning of what will be a long month - so I
may
> be totally off base....

no, i don't think you're off base at all.  simple and clean sounds good to
me.

Nathan Bubna
nathan@esha.com


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xmlMathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Daniel Rall <dl...@finemaltcoding.com>.
"Geir Magnusson Jr." <ge...@optonline.net> writes:

> I like very much the idea of placing few if any requirements on the tools -
> that the toolbox descriptor should suffice -> I would want to be able to
> specify  java.lang.String as a tool and control where and how it was used...

Indeed, _any_ Java class or primitive should be able to be added to
the toolbox (just as in DVSL).  This is a very useful and powerful
piece of functionality.  Additionally, when adding objects to the
toolbox I would find it very useful for an alternate Factory to be use
which has the ability to do object pooling and perform
initialization/resource reclamation activites.  This allows a certain
amount of framework functionality without introducing an actual
framework -- just an integration point.

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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xmlMathTool.xml ParameterParser.xml ToolLoader.xml

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
On 4/4/02 9:29 PM, "Daniel Rall" <dl...@finemaltcoding.com> wrote:

> "Geir Magnusson Jr." <ge...@optonline.net> writes:
> 
>> If the problem is tools/tools/...
>> 
>> Why not
>> 
>>  tools/library/...
>> 
>> As suggested by the docs...
> 
> +1, that sounds _much_ nicer.
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
> 


General comment - I was too busy today to jump into the tools fray (too busy
working for client)...

But my impression is that this is getting a bit over-designed : I am going
to read the whole thread tomorrow - but has everyone stood back and asked
the question (or answered it) :


   Is there anything we can remove?

I like very much the idea of placing few if any requirements on the tools -
that the toolbox descriptor should suffice -> I would want to be able to
specify  java.lang.String as a tool and control where and how it was used...

And I am afraid that outside of the Struts integration part, it's getting
framework-ish...

However, these are just random thoughts at the end of a long day towards the
end of a long week at the beginning of what will be a long month - so I may
be totally off base....

geir

-- 
Geir Magnusson Jr.                                     geirm@optonline.net
System and Software Consulting
The question is : What is a Mahnamahna?


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xmlMathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Daniel Rall <dl...@finemaltcoding.com>.
"Geir Magnusson Jr." <ge...@optonline.net> writes:

> If the problem is tools/tools/...
>
> Why not
>
>  tools/library/...
>
> As suggested by the docs...

+1, that sounds _much_ nicer.

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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xmlMathTool.xml ParameterParser.xml ToolLoader.xml

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
On 4/4/02 1:27 PM, "Daniel Rall" <dl...@finemaltcoding.com> wrote:

> Christoph Reck <Ch...@dlr.de> writes:
> 
>> "Geir Magnusson Jr." wrote:
>>> 
>>> On 4/3/02 12:46 PM, "Jon Scott Stevens" <jo...@latchkey.com> wrote:
>>> 
>>>> on 4/3/02 1:10 AM, "sidler@apache.org" <si...@apache.org> wrote:
>>>> 
>>>>>              tools/src/java/org/apache/velocity/tools/tools DateTool.java
>>>>>                       MathTool.java ParameterParser.java ToolLoader.java
>>>>>                       package.html
>>>> 
>>>> Why is it that these fiels are in a tools/tools directory?
>>>> 
>>> 
>>> Tools is the subpackage that holds all for the -tools project.
>> 
>> yuk!?
>> .../tools/tools/*Tool.java
>> 
>> In the commons sandbox the *Utils and *Tools was discussed and
>> the java.util.* approach was taken where the radix is just postfixed
>> with a plural - like java.util.Arrays, java.util.Collections,
>> Something like DateUtils became Dates, XmlUtils -> XmlStrings,
>> MathUtils -> Numbers or just Math (which has no plural form).
>> 
>> How about such an approach?
> 
> That worked well for the Commons packages, but I'm not sure how well
> it applies to the class names of the Java source files in the tools
> component.  If I've got it right now, these are context/pull tools.
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
> 


If the problem is tools/tools/...

Why not

 tools/library/...

As suggested by the docs...

-- 
Geir Magnusson Jr.                                     geirm@optonline.net
System and Software Consulting
"The greatest pleasure in life is doing what people say you cannot do."
        - Walter Bagehot



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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xmlMathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Daniel Rall <dl...@finemaltcoding.com>.
Christoph Reck <Ch...@dlr.de> writes:

> "Geir Magnusson Jr." wrote:
> > 
>> On 4/3/02 12:46 PM, "Jon Scott Stevens" <jo...@latchkey.com> wrote:
>> 
>> > on 4/3/02 1:10 AM, "sidler@apache.org" <si...@apache.org> wrote:
>> >
>> >>              tools/src/java/org/apache/velocity/tools/tools DateTool.java
>> >>                       MathTool.java ParameterParser.java ToolLoader.java
>> >>                       package.html
>> >
>> > Why is it that these fiels are in a tools/tools directory?
>> >
>> 
>> Tools is the subpackage that holds all for the -tools project.
>
> yuk!?
> .../tools/tools/*Tool.java
>
> In the commons sandbox the *Utils and *Tools was discussed and
> the java.util.* approach was taken where the radix is just postfixed
> with a plural - like java.util.Arrays, java.util.Collections, 
> Something like DateUtils became Dates, XmlUtils -> XmlStrings,
> MathUtils -> Numbers or just Math (which has no plural form).
>
> How about such an approach?

That worked well for the Commons packages, but I'm not sure how well
it applies to the class names of the Java source files in the tools
component.  If I've got it right now, these are context/pull tools.

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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xmlMathTool.xml ParameterParser.xml ToolLoader.xml

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
On 4/4/02 3:07 AM, "Christoph Reck" <Ch...@dlr.de> wrote:

> "Geir Magnusson Jr." wrote:
>> 
>> On 4/3/02 12:46 PM, "Jon Scott Stevens" <jo...@latchkey.com> wrote:
>> 
>>> on 4/3/02 1:10 AM, "sidler@apache.org" <si...@apache.org> wrote:
>>> 
>>>>              tools/src/java/org/apache/velocity/tools/tools DateTool.java
>>>>                       MathTool.java ParameterParser.java ToolLoader.java
>>>>                       package.html
>>> 
>>> Why is it that these fiels are in a tools/tools directory?
>>> 
>> 
>> Tools is the subpackage that holds all for the -tools project.
> 
> yuk!?
> .../tools/tools/*Tool.java
> 
> In the commons sandbox the *Utils and *Tools was discussed and
> the java.util.* approach was taken where the radix is just postfixed
> with a plural - like java.util.Arrays, java.util.Collections,
> Something like DateUtils became Dates, XmlUtils -> XmlStrings,
> MathUtils -> Numbers or just Math (which has no plural form).

Why is the plural of 'XMLUtil' -> XMLStrings ?  And why did XML get demoted
to Xml?
 
> How about such an approach?

You think there will be enough tools for each bucket?  I am afraid there
will be single-class packages, or when that wants to be avoided, things
misplaced...

One solution is to have

  o.a.v.tools.components/<here is where tools live...>

If the name is so offensive...


-- 
Geir Magnusson Jr.                                     geirm@optonline.net
System and Software Consulting
"We will be judged not by the monuments we build, but by the monuments we
destroy" - Ada Louise Huxtable


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xmlMathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Christoph Reck <Ch...@dlr.de>.
"Geir Magnusson Jr." wrote:
> 
> On 4/3/02 12:46 PM, "Jon Scott Stevens" <jo...@latchkey.com> wrote:
> 
> > on 4/3/02 1:10 AM, "sidler@apache.org" <si...@apache.org> wrote:
> >
> >>              tools/src/java/org/apache/velocity/tools/tools DateTool.java
> >>                       MathTool.java ParameterParser.java ToolLoader.java
> >>                       package.html
> >
> > Why is it that these fiels are in a tools/tools directory?
> >
> 
> Tools is the subpackage that holds all for the -tools project.

yuk!?
.../tools/tools/*Tool.java

In the commons sandbox the *Utils and *Tools was discussed and
the java.util.* approach was taken where the radix is just postfixed
with a plural - like java.util.Arrays, java.util.Collections, 
Something like DateUtils became Dates, XmlUtils -> XmlStrings,
MathUtils -> Numbers or just Math (which has no plural form).

How about such an approach?

-- 
:) Christoph Reck

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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
On 4/3/02 12:46 PM, "Jon Scott Stevens" <jo...@latchkey.com> wrote:

> on 4/3/02 1:10 AM, "sidler@apache.org" <si...@apache.org> wrote:
> 
>>              tools/src/java/org/apache/velocity/tools/tools DateTool.java
>>                       MathTool.java ParameterParser.java ToolLoader.java
>>                       package.html
> 
> Why is it that these fiels are in a tools/tools directory?
> 

Tools is the subpackage that holds all for the -tools project.


-- 
Geir Magnusson Jr.                                     geirm@optonline.net
System and Software Consulting
"He who throws mud only loses ground." - Fat Albert


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


Re: cvs commit: jakarta-velocity-tools/tools/xdocs DateTool.xml MathTool.xml ParameterParser.xml ToolLoader.xml

Posted by Jon Scott Stevens <jo...@latchkey.com>.
on 4/3/02 1:10 AM, "sidler@apache.org" <si...@apache.org> wrote:

>              tools/src/java/org/apache/velocity/tools/tools DateTool.java
>                       MathTool.java ParameterParser.java ToolLoader.java
>                       package.html

Why is it that these fiels are in a tools/tools directory?

-jon


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