velocity-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nbu...@apache.org
Subject svn commit: r545415 - in /velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools: ConversionUtils.java generic/ConversionTool.java
Date Fri, 08 Jun 2007 05:16:02 GMT
Author: nbubna
Date: Thu Jun  7 22:16:01 2007
New Revision: 545415

URL: http://svn.apache.org/viewvc?view=rev&rev=545415
Log:
initial revision of ConversionTool (much derived from ValueParser) and ConversionUtils (derived
from parts ValueParser, DateTool, and NumberTool which it will subsume)

Added:
    velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/ConversionUtils.java
  (with props)
    velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/generic/ConversionTool.java
  (with props)

Added: velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/ConversionUtils.java
URL: http://svn.apache.org/viewvc/velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/ConversionUtils.java?view=auto&rev=545415
==============================================================================
--- velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/ConversionUtils.java
(added)
+++ velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/ConversionUtils.java
Thu Jun  7 22:16:01 2007
@@ -0,0 +1,534 @@
+package org.apache.velocity.tools;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Calendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/**
+ * Utility methods for parsing or otherwise converting between types.
+ *
+ * @author Nathan Bubna
+ */
+public class ConversionUtils
+{
+    private static final int STYLE_NUMBER       = 0;
+    private static final int STYLE_CURRENCY     = 1;
+    private static final int STYLE_PERCENT      = 2;
+    //NOTE: '3' belongs to a non-public "scientific" style
+    private static final int STYLE_INTEGER      = 4;
+
+    /**
+     * Returns a {@link NumberFormat} instance for the specified
+     * format and {@link Locale}.  If the format specified is a standard
+     * style pattern, then a number instance
+     * will be returned with the number style set to the
+     * specified style.  If it is a custom format, then a customized
+     * {@link NumberFormat} will be returned.
+     *
+     * @param format the custom or standard formatting pattern to be used
+     * @param locale the {@link Locale} to be used
+     * @return an instance of {@link NumberFormat}
+     * @see NumberFormat
+     */
+    public static NumberFormat getNumberFormat(String format, Locale locale)
+    {
+        if (format == null || locale == null)
+        {
+            return null;
+        }
+
+        NumberFormat nf = null;
+        int style = getNumberStyleAsInt(format);
+        if (style < 0)
+        {
+            // we have a custom format
+            nf = new DecimalFormat(format, new DecimalFormatSymbols(locale));
+        }
+        else
+        {
+            // we have a standard format
+            nf = getNumberFormat(style, locale);
+        }
+        return nf;
+    }
+
+    /**
+     * Returns a {@link NumberFormat} instance for the specified
+     * number style and {@link Locale}.
+     *
+     * @param numberStyle the number style (number will be ignored if this is
+     *        less than zero or the number style is not recognized)
+     * @param locale the {@link Locale} to be used
+     * @return an instance of {@link NumberFormat} or <code>null</code>
+     *         if an instance cannot be constructed with the given
+     *         parameters
+     */
+    public static NumberFormat getNumberFormat(int numberStyle, Locale locale)
+    {
+        try
+        {
+            NumberFormat nf;
+            switch (numberStyle)
+            {
+                case STYLE_NUMBER:
+                    nf = NumberFormat.getNumberInstance(locale);
+                    break;
+                case STYLE_CURRENCY:
+                    nf = NumberFormat.getCurrencyInstance(locale);
+                    break;
+                case STYLE_PERCENT:
+                    nf = NumberFormat.getPercentInstance(locale);
+                    break;
+                case STYLE_INTEGER:
+                    nf = NumberFormat.getIntegerInstance(locale);
+                    break;
+                default:
+                    // invalid style was specified, return null
+                    nf = null;
+            }
+            return nf;
+        }
+        catch (Exception suppressed)
+        {
+            // let it go...
+            return null;
+        }
+    }
+
+    /**
+     * Checks a string to see if it matches one of the standard
+     * NumberFormat style patterns:
+     *      number, currency, percent, integer, or default.
+     * if it does it will return the integer constant for that pattern.
+     * if not, it will return -1.
+     *
+     * @see NumberFormat
+     * @param style the string to be checked
+     * @return the int identifying the style pattern
+     */
+    public static int getNumberStyleAsInt(String style)
+    {
+        // avoid needlessly running through all the string comparisons
+        if (style == null || style.length() < 6 || style.length() > 8) {
+            return -1;
+        }
+        if (style.equalsIgnoreCase("default"))
+        {
+            //NOTE: java.text.NumberFormat returns "number" instances
+            //      as the default (at least in Java 1.3 and 1.4).
+            return STYLE_NUMBER;
+        }
+        if (style.equalsIgnoreCase("number"))
+        {
+            return STYLE_NUMBER;
+        }
+        if (style.equalsIgnoreCase("currency"))
+        {
+            return STYLE_CURRENCY;
+        }
+        if (style.equalsIgnoreCase("percent"))
+        {
+            return STYLE_PERCENT;
+        }
+        if (style.equalsIgnoreCase("integer"))
+        {
+            return STYLE_INTEGER;
+        }
+        // ok, it's not any of the standard patterns
+        return -1;
+    }
+
+
+    // ----------------- number conversion methods ---------------
+
+    /**
+     * Attempts to convert an unidentified {@link Object} into a {@link Number},
+     * just short of turning it into a string and parsing it.  In other words,
+     * this will convert to {@link Number} from a {@link Number}, {@link Calendar},
+     * or {@link Date}.  If it can't do that, it will return {@code null}.
+     *
+     * @param obj - the object to convert
+     */
+    public static Number toNumber(Object obj)
+    {
+        if (obj == null)
+        {
+            return null;
+        }
+        if (obj instanceof Number)
+        {
+            return (Number)obj;
+        }
+        if (obj instanceof Date)
+        {
+            return new Long(((Date)obj).getTime());
+        }
+        if (obj instanceof Calendar)
+        {
+            Date date = ((Calendar)obj).getTime();
+            return new Long(date.getTime());
+        }
+        return null;
+    }
+
+    /**
+     * Converts a string to an instance of {@link Number} using the
+     * specified format and {@link Locale} to parse it.
+     *
+     * @param value - the string to convert
+     * @param format - the format the number is in
+     * @param locale - the {@link Locale}
+     * @return the string as a {@link Number} or <code>null</code> if no
+     *         conversion is possible
+     * @see NumberFormat#parse
+     */
+    public static Number toNumber(String value, String format, Locale locale)
+    {
+        if (value == null || format == null || locale == null)
+        {
+            return null;
+        }
+        try
+        {
+            NumberFormat parser = getNumberFormat(format, locale);
+            return parser.parse(value);
+        }
+        catch (Exception e)
+        {
+            return null;
+        }
+    }
+
+    /**
+     * Converts an object to an instance of {@link Number} using the
+     * specified format and {@link Locale} to parse it, if necessary.
+     *
+     * @param value - the object to convert
+     * @param format - the format the number is in
+     * @param locale - the {@link Locale}
+     * @return the object as a {@link Number} or <code>null</code> if no
+     *         conversion is possible
+     * @see NumberFormat#parse
+     */
+    public static Number toNumber(Object value, String format, Locale locale)
+    {
+        // first try the easy stuff
+        Number number = toNumber(value);
+        if (number != null)
+        {
+            return number;
+        }
+
+        // turn it into a string and try parsing it
+        return toNumber(String.valueOf(value), format, locale);
+    }
+
+
+    // -------------------------- DateFormat creation methods --------------
+
+    /**
+     * Returns a {@link DateFormat} instance for the specified
+     * format, {@link Locale}, and {@link TimeZone}.  If the format
+     * specified is a standard style pattern, then a date-time instance
+     * will be returned with both the date and time styles set to the
+     * specified style.  If it is a custom format, then a customized
+     * {@link SimpleDateFormat} will be returned.
+     *
+     * @param format the custom or standard formatting pattern to be used
+     * @param locale the {@link Locale} to be used
+     * @param timezone the {@link TimeZone} to be used
+     * @return an instance of {@link DateFormat}
+     * @see SimpleDateFormat
+     * @see DateFormat
+     */
+    public static DateFormat getDateFormat(String format, Locale locale,
+                                           TimeZone timezone)
+    {
+        if (format == null)
+        {
+            return null;
+        }
+
+        DateFormat df = null;
+        // do they want a date instance
+        if (format.endsWith("_date"))
+        {
+            String fmt = format.substring(0, format.length() - 5);
+            int style = getStyleAsInt(fmt);
+            df = getDateFormat(style, -1, locale, timezone);
+        }
+        // do they want a time instance?
+        else if (format.endsWith("_time"))
+        {
+            String fmt = format.substring(0, format.length() - 5);
+            int style = getStyleAsInt(fmt);
+            df = getDateFormat(-1, style, locale, timezone);
+        }
+        // ok, they either want a custom or date-time instance
+        else
+        {
+            int style = getStyleAsInt(format);
+            if (style < 0)
+            {
+                // we have a custom format
+                df = new SimpleDateFormat(format, locale);
+                df.setTimeZone(timezone);
+            }
+            else
+            {
+                // they want a date-time instance
+                df = getDateFormat(style, style, locale, timezone);
+            }
+        }
+        return df;
+    }
+
+    /**
+     * Returns a {@link DateFormat} instance for the specified
+     * date style, time style, {@link Locale}, and {@link TimeZone}.
+     *
+     * @param dateStyle the date style
+     * @param timeStyle the time style
+     * @param locale the {@link Locale} to be used
+     * @param timezone the {@link TimeZone} to be used
+     * @return an instance of {@link DateFormat}
+     * @see #getDateFormat(int timeStyle, int dateStyle, Locale locale, TimeZone timezone)
+     */
+    public static DateFormat getDateFormat(String dateStyle, String timeStyle,
+                                           Locale locale, TimeZone timezone)
+    {
+        int ds = getStyleAsInt(dateStyle);
+        int ts = getStyleAsInt(timeStyle);
+        return getDateFormat(ds, ts, locale, timezone);
+    }
+
+    /**
+     * Returns a {@link DateFormat} instance for the specified
+     * time style, date style, {@link Locale}, and {@link TimeZone}.
+     *
+     * @param dateStyle the date style (date will be ignored if this is
+     *        less than zero and the date style is not)
+     * @param timeStyle the time style (time will be ignored if this is
+     *        less than zero and the date style is not)
+     * @param locale the {@link Locale} to be used
+     * @param timezone the {@link TimeZone} to be used
+     * @return an instance of {@link DateFormat} or <code>null</code>
+     *         if an instance cannot be constructed with the given
+     *         parameters
+     */
+    public static DateFormat getDateFormat(int dateStyle, int timeStyle,
+                                           Locale locale, TimeZone timezone)
+    {
+        try
+        {
+            DateFormat df;
+            if (dateStyle < 0 && timeStyle < 0)
+            {
+                // no style was specified, use default instance
+                df = DateFormat.getInstance();
+            }
+            else if (timeStyle < 0)
+            {
+                // only a date style was specified
+                df = DateFormat.getDateInstance(dateStyle, locale);
+            }
+            else if (dateStyle < 0)
+            {
+                // only a time style was specified
+                df = DateFormat.getTimeInstance(timeStyle, locale);
+            }
+            else
+            {
+                df = DateFormat.getDateTimeInstance(dateStyle, timeStyle,
+                                                    locale);
+            }
+            df.setTimeZone(timezone);
+            return df;
+        }
+        catch (Exception suppressed)
+        {
+            // let it go...
+            return null;
+        }
+    }
+
+    /**
+     * Checks a string to see if it matches one of the standard DateFormat
+     * style patterns: full, long, medium, short, or default.  If it does,
+     * it will return the integer constant for that pattern.  If not, it
+     * will return -1.
+     *
+     * @see DateFormat
+     * @param style the string to be checked
+     * @return the int identifying the style pattern
+     */
+    public static int getStyleAsInt(String style)
+    {
+        // avoid needlessly running through all the string comparisons
+        if (style == null || style.length() < 4 || style.length() > 7) {
+            return -1;
+        }
+        if (style.equalsIgnoreCase("full"))
+        {
+            return DateFormat.FULL;
+        }
+        if (style.equalsIgnoreCase("long"))
+        {
+            return DateFormat.LONG;
+        }
+        if (style.equalsIgnoreCase("medium"))
+        {
+            return DateFormat.MEDIUM;
+        }
+        if (style.equalsIgnoreCase("short"))
+        {
+            return DateFormat.SHORT;
+        }
+        if (style.equalsIgnoreCase("default"))
+        {
+            return DateFormat.DEFAULT;
+        }
+        // ok, it's not any of the standard patterns
+        return -1;
+    }
+
+
+    // ----------------- date conversion methods ---------------
+
+    /**
+     * Attempts to convert an unidentified {@link Object} into a {@link Date},
+     * just short of turning it into a string and parsing it.  In other words,
+     * this will convert to {@link Date} from a {@link Date}, {@link Calendar},
+     * or {@link Number}.  If it can't do that, it will return {@code null}.
+     *
+     * @param obj - the object to convert
+     */
+    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();
+        }
+        if (obj instanceof Number)
+        {
+            Date d = new Date();
+            d.setTime(((Number)obj).longValue());
+            return d;
+        }
+        return null;
+    }
+
+    /**
+     * Converts an object to an instance of {@link Date} using the
+     * specified format, {@link Locale}, and {@link TimeZone} if the
+     * object is not already an instance of Date, Calendar, or Long.
+     *
+     * @param obj - the date to convert
+     * @param format - the format the date is in
+     * @param locale - the {@link Locale}
+     * @param timezone - the {@link TimeZone}
+     * @return the object as a {@link Date} or <code>null</code> if no
+     *         conversion is possible
+     * @see #getDateFormat
+     * @see SimpleDateFormat#parse
+     */
+    public static Date toDate(Object obj, String format,
+                              Locale locale, TimeZone timezone)
+    {
+        // first try the easy stuff
+        Date date = toDate(obj);
+        if (date != null)
+        {
+            return date;
+        }
+
+        // turn it into a string and try parsing it
+        return toDate(String.valueOf(obj), format, locale, timezone);
+    }
+
+    /**
+     * Converts an object to an instance of {@link Date} using the
+     * specified format, {@link Locale}, and {@link TimeZone} if the
+     * object is not already an instance of Date, Calendar, or Long.
+     *
+     * @param str - the string to parse
+     * @param format - the format the date is in
+     * @param locale - the {@link Locale}
+     * @param timezone - the {@link TimeZone}
+     * @return the string as a {@link Date} or <code>null</code> if the
+     *         parsing fails
+     * @see #getDateFormat
+     * @see SimpleDateFormat#parse
+     */
+    public static Date toDate(String str, String format,
+                              Locale locale, TimeZone timezone)
+    {
+        try
+        {
+            //try parsing w/a customized SimpleDateFormat
+            DateFormat parser = getDateFormat(format, locale, timezone);
+            return parser.parse(str);
+        }
+        catch (Exception e)
+        {
+            return null;
+        }
+    }
+
+    public static Calendar toCalendar(Date date, Locale locale)
+    {
+        if (date == null)
+        {
+            return null;
+        }
+
+        Calendar cal;
+        if (locale == null)
+        {
+            cal = Calendar.getInstance();
+        }
+        else
+        {
+            cal = Calendar.getInstance(locale);
+        }
+        cal.setTime(date);
+        // HACK: Force all fields to update. see link for explanation of this.
+        //http://java.sun.com/j2se/1.4/docs/api/java/util/Calendar.html
+        cal.getTime();
+        return cal;
+    }
+
+}

Propchange: velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/ConversionUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/ConversionUtils.java
------------------------------------------------------------------------------
    svn:keywords = Revision

Added: velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/generic/ConversionTool.java
URL: http://svn.apache.org/viewvc/velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/generic/ConversionTool.java?view=auto&rev=545415
==============================================================================
--- velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/generic/ConversionTool.java
(added)
+++ velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/generic/ConversionTool.java
Thu Jun  7 22:16:01 2007
@@ -0,0 +1,849 @@
+package org.apache.velocity.tools.generic;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.lang.reflect.Array;
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+import org.apache.velocity.tools.ConversionUtils;
+import org.apache.velocity.tools.config.DefaultKey;
+
+/**
+ * <p>Utility class for easy conversion of String values to richer types.</p>
+ * <p><pre>
+ * Template example(s):
+ *   $convert.toNumber('12.6')   ->  12.6
+ *   $convert.toInt('12.6')      ->  12
+ *   $convert.toNumbers('12.6,42')  ->  [12.6, 42]
+ *
+ * Toolbox configuration:
+ * &lt;tools&gt;
+ *   &lt;toolbox scope="application"&gt;
+ *     &lt;tool class="org.apache.velocity.tools.generic.ConversionTool"
+ *              dateFormat="yyyy-MM-dd"/&gt;
+ *   &lt;/toolbox&gt;
+ * &lt;/tools&gt;
+ * </pre></p>
+ *
+ * <p>This comes in very handy when parsing anything.</p>
+ *
+ * @author Nathan Bubna
+ * @version $Revision$ $Date: 2007-02-26 11:24:39 -0800 (Mon, 26 Feb 2007) $
+ * @since VelocityTools 2.0
+ */
+@DefaultKey("convert")
+public class ConversionTool extends LocaleConfig
+{
+    public static final String STRINGS_DELIMITER_FORMAT_KEY = "stringsDelimiter";
+    public static final String DATE_FORMAT_KEY = "dateFormat";
+    public static final String NUMBER_FORMAT_KEY = "numberFormat";
+
+    public static final String DEFAULT_STRINGS_DELIMITER = ",";
+    public static final String DEFAULT_NUMBER_FORMAT = "default";
+    public static final String DEFAULT_DATE_FORMAT = "default";
+
+    private String stringsDelimiter = DEFAULT_STRINGS_DELIMITER;
+    private String numberFormat = DEFAULT_NUMBER_FORMAT;
+    private String dateFormat = DEFAULT_DATE_FORMAT;
+
+    /**
+     * Does the actual configuration. This is protected, so
+     * subclasses may share the same ValueParser and call configure
+     * at any time, while preventing templates from doing so when 
+     * configure(Map) is locked.
+     */
+    protected void configure(ValueParser values)
+    {
+        super.configure(values);
+
+        String delimiter = values.getString(STRINGS_DELIMITER_FORMAT_KEY);
+        if (delimiter != null)
+        {
+            setStringsDelimiter(delimiter);
+        }
+
+        String dateFormat = values.getString(DATE_FORMAT_KEY);
+        if (dateFormat != null)
+        {
+            setDateFormat(dateFormat);
+        }
+
+        String numberFormat = values.getString(NUMBER_FORMAT_KEY);
+        if (numberFormat != null)
+        {
+            setNumberFormat(numberFormat);
+        }
+    }
+
+    /**
+     * Sets the delimiter used for separating values in a single String value.
+     * The default string delimiter is a comma.
+     *
+     * @see #parseStringList
+     */
+    protected final void setStringsDelimiter(String stringsDelimiter)
+    {
+        this.stringsDelimiter = stringsDelimiter;
+    }
+
+    public final String getStringsDelimiter()
+    {
+        return this.stringsDelimiter;
+    }
+
+    protected final void setNumberFormat(String format)
+    {
+        this.numberFormat = format;
+    }
+
+    public final String getNumberFormat()
+    {
+        return this.numberFormat;
+    }
+
+    protected final void setDateFormat(String format)
+    {
+        this.dateFormat = format;
+    }
+
+    public final String getDateFormat()
+    {
+        return this.dateFormat;
+    }
+
+    // ----------------- public parsing methods --------------------------
+
+    /**
+     * @param value the object to be turned into a String
+     * @return the string value of the object or null if the value is null
+     *         or it is an array whose first value is null
+     */
+    public String toString(Object value)
+    {
+        if (value instanceof String)
+        {
+            return (String)value;
+        }
+        if (value == null)
+        {
+            return null;
+        }
+        if (value.getClass().isArray())
+        {
+            if (Array.getLength(value) > 0)
+            {
+                // take the first value
+                value = Array.get(value, 0);
+            }
+        }
+        return String.valueOf(value);
+    }
+
+    /**
+     * @param value the Collection to be turned into a string
+     * @return the string value of the first object in the collection
+     *         or null if the collection is empty
+     */
+    public String toString(Collection values)
+    {
+        if (values == null || !values.isEmpty())
+        {
+            return String.valueOf(values.iterator().next());
+        }
+        return null;
+    }
+
+    /**
+     * @param value the object to be converted
+     * @return a {@link Boolean} object for the specified value or
+     *         <code>null</code> if the value is null or the conversion failed
+     */
+    public Boolean toBoolean(Object value)
+    {
+        if (value instanceof Boolean)
+        {
+            return (Boolean)value;
+        }
+
+        String s = toString(value);
+        return (s != null) ? parseBoolean(s) : null;
+    }
+
+    /**
+     * @param value the object to be converted
+     * @return a {@link Integer} for the specified value or
+     *         <code>null</code> if the value is null or the conversion failed
+     */
+    public Integer toInteger(Object value)
+    {
+        if (value == null || value instanceof Integer)
+        {
+            return (Integer)value;
+        }
+        Number num = toNumber(value);
+        return new Integer(num.intValue());
+    }
+
+    /**
+     * @param value the object to be converted
+     * @return a {@link Double} for the specified value or
+     *         <code>null</code> if the value is null or the conversion failed
+     */
+    public Double toDouble(Object value)
+    {
+        if (value == null || value instanceof Double)
+        {
+            return (Double)value;
+        }
+        Number num = toNumber(value);
+        return new Double(num.intValue());
+    }
+
+    /**
+     * @param value the object to be converted
+     * @return a {@link Number} for the specified value or
+     *         <code>null</code> if the value is null or the conversion failed
+     */
+    public Number toNumber(Object value)
+    {
+        Number number = ConversionUtils.toNumber(value);
+        if (number != null)
+        {
+            return number;
+        }
+
+        String s = toString(value);
+        if (s == null || s.length() == 0)
+        {
+            return null;
+        }
+        return parseNumber(s);
+    }
+
+    /**
+     * @param value the object to be converted
+     * @return a {@link Locale} for the specified value or
+     *         <code>null</code> if the value is null or the conversion failed
+     */
+    public Locale toLocale(Object value)
+    {
+        if (value instanceof Locale)
+        {
+            return (Locale)value;
+        }
+        String s = toString(value);
+        if (s == null || s.length() == 0)
+        {
+            return null;
+        }
+        return parseLocale(s);
+    }
+
+    /**
+     * Converts an object to an instance of {@link Date}, when necessary
+     * using the configured date parsing format, the configured default
+     * {@link Locale}, and the system's default {@link TimeZone} to parse
+     * the string value of the specified object.
+     *
+     * @param value the date to convert
+     * @return the object as a {@link Date} or <code>null</code> if no
+     *         conversion is possible
+     */
+    public Date toDate(Object value)
+    {
+        Date d = ConversionUtils.toDate(value);
+        if (d != null)
+        {
+            return d;
+        }
+        String s = toString(value);
+        if (s == null || s.length() == 0)
+        {
+            return null;
+        }
+        return parseDate(s);
+    }
+
+    public Calendar toCalendar(Object value)
+    {
+        if (value == null)
+        {
+            return null;
+        }
+        if (value instanceof Calendar)
+        {
+            return (Calendar)value;
+        }
+
+        Date date = toDate(value);
+        if (date == null)
+        {
+            return null;
+        }
+
+        //convert the date to a calendar
+        return ConversionUtils.toCalendar(date, getLocale());
+    }
+
+
+    /**
+     * @param value the value to be converted
+     * @return an array of String objects containing all of the values
+     *         derived from the specified array, Collection, or delimited String
+     */
+    public String[] toStrings(Object value)
+    {
+        if (value == null)
+        {
+            return null;
+        }
+        if (value instanceof String[])
+        {
+            return (String[])value;
+        }
+
+        String[] strings = null;
+        if (value instanceof Collection)
+        {
+            Collection values = (Collection)value;
+            if (!values.isEmpty())
+            {
+                strings = new String[values.size()];
+                int index = 0;
+                for (Iterator i = values.iterator(); i.hasNext(); )
+                {
+                    strings[index++] = toString(i.next());
+                }
+            }
+        }
+        else if (value.getClass().isArray())
+        {
+            strings = new String[Array.getLength(value)];
+            for (int i=0; i < strings.length; i++)
+            {
+                strings[i] = toString(Array.get(value, i));
+            }
+        }
+        else
+        {
+            strings = parseStringList(toString(value));
+        }
+        return strings;
+    }
+
+
+
+    /**
+     * @param value the value to be converted
+     * @return an array of Boolean objects derived from the specified value,
+     *         or <code>null</code>.
+     */
+    public Boolean[] toBooleans(Object value)
+    {
+        if (value != null && !value.getClass().isArray())
+        {
+            value = toStrings(value);
+        }
+        if (value == null)
+        {
+            return null;
+        }
+
+        Boolean[] bools = new Boolean[Array.getLength(value)];
+        for (int i=0; i < bools.length; i++)
+        {
+            bools[i] = toBoolean(Array.get(value, i));
+        }
+        return bools;
+    }
+
+    /**
+     * @param values the collection of values to be converted
+     * @return an array of Boolean objects derived from the specified values,
+     *         or <code>null</code>.
+     */
+    public Boolean[] toBooleans(Collection values)
+    {
+        if (values == null || !values.isEmpty())
+        {
+            return null;
+        }
+        Boolean[] bools = new Boolean[values.size()];
+        int index = 0;
+        for (Object val : values)
+        {
+            bools[index++] = toBoolean(val);
+        }
+        return bools;
+    }
+
+
+    /**
+     * @param value the value to be converted
+     * @return an array of Number objects derived from the specified value,
+     *         or <code>null</code>.
+     */
+    public Number[] toNumbers(Object value)
+    {
+        if (value != null && !value.getClass().isArray())
+        {
+            value = toStrings(value);
+        }
+        if (value == null)
+        {
+            return null;
+        }
+
+        Number[] numbers = new Number[Array.getLength(value)];
+        for (int i=0; i < numbers.length; i++)
+        {
+            numbers[i] = toNumber(Array.get(value, i));
+        }
+        return numbers;
+    }
+
+    /**
+     * @param values the collection of values to be converted
+     * @return an array of Number objects derived from the specified values,
+     *         or <code>null</code>.
+     */
+    public Number[] toNumbers(Collection values)
+    {
+        if (values == null || !values.isEmpty())
+        {
+            return null;
+        }
+        Number[] numbers = new Number[values.size()];
+        int index = 0;
+        for (Object val : values)
+        {
+            numbers[index++] = toNumber(val);
+        }
+        return numbers;
+    }
+
+    /**
+     * @param value the value to be converted
+     * @return an array of int values derived from the specified value,
+     *         or <code>null</code>.
+     */
+    public int[] toInts(Object value)
+    {
+        Number[] numbers = toNumbers(value);
+        if (numbers == null)
+        {
+            return null;
+        }
+
+        int[] ints = new int[numbers.length];
+        for (int i=0; i<ints.length; i++)
+        {
+            if (numbers[i] != null)
+            {
+                ints[i] = numbers[i].intValue();
+            }
+        }
+        return ints;
+    }
+
+    /**
+     * @param value the value to be converted
+     * @return an array of double values derived from the specified value,
+     *         or <code>null</code>.
+     */
+    public double[] toDoubles(Object value)
+    {
+        Number[] numbers = toNumbers(value);
+        if (numbers == null)
+        {
+            return null;
+        }
+
+        double[] doubles = new double[numbers.length];
+        for (int i=0; i<doubles.length; i++)
+        {
+            if (numbers[i] != null)
+            {
+                doubles[i] = numbers[i].doubleValue();
+            }
+        }
+        return doubles;
+    }
+
+    /**
+     * @param value the value to be converted
+     * @return an array of Locale objects derived from the specified value,
+     *         or <code>null</code>.
+     */
+    public Locale[] toLocales(Object value)
+    {
+        if (value != null && !value.getClass().isArray())
+        {
+            value = toStrings(value);
+        }
+        if (value == null)
+        {
+            return null;
+        }
+
+        Locale[] locales = new Locale[Array.getLength(value)];
+        for (int i=0; i < locales.length; i++)
+        {
+            locales[i] = toLocale(Array.get(value, i));
+        }
+        return locales;
+    }
+
+    /**
+     * @param values the collection of values to be converted
+     * @return an array of Locale objects derived from the specified values,
+     *         or <code>null</code>.
+     */
+    public Locale[] toLocales(Collection values)
+    {
+        if (values == null || !values.isEmpty())
+        {
+            return null;
+        }
+        Locale[] locales = new Locale[values.size()];
+        int index = 0;
+        for (Object val : values)
+        {
+            locales[index++] = toLocale(val);
+        }
+        return locales;
+    }
+
+
+    /**
+     * @param value the value to be converted
+     * @return an array of Date objects derived from the specified value,
+     *         or <code>null</code>.
+     */
+    public Date[] toDates(Object value)
+    {
+        if (value != null && !value.getClass().isArray())
+        {
+            value = toStrings(value);
+        }
+        if (value == null)
+        {
+            return null;
+        }
+
+        Date[] dates = new Date[Array.getLength(value)];
+        for (int i=0; i < dates.length; i++)
+        {
+            dates[i] = toDate(Array.get(value, i));
+        }
+        return dates;
+    }
+
+    /**
+     * @param values the collection of values to be converted
+     * @return an array of Date objects derived from the specified values,
+     *         or <code>null</code>.
+     */
+    public Date[] toDates(Collection values)
+    {
+        if (values == null || !values.isEmpty())
+        {
+            return null;
+        }
+        Date[] dates = new Date[values.size()];
+        int index = 0;
+        for (Object val : values)
+        {
+            dates[index++] = toDate(val);
+        }
+        return dates;
+    }
+
+    /**
+     * @param value the value to be converted
+     * @return an array of Calendar objects derived from the specified value,
+     *         or <code>null</code>.
+     */
+    public Calendar[] toCalendars(Object value)
+    {
+        if (value != null && !value.getClass().isArray())
+        {
+            value = toStrings(value);
+        }
+        if (value == null)
+        {
+            return null;
+        }
+
+        Calendar[] calendars = new Calendar[Array.getLength(value)];
+        for (int i=0; i < calendars.length; i++)
+        {
+            calendars[i] = toCalendar(Array.get(value, i));
+        }
+        return calendars;
+    }
+
+    /**
+     * @param values the collection of values to be converted
+     * @return an array of Calendar objects derived from the specified values,
+     *         or <code>null</code>.
+     */
+    public Calendar[] toCalendars(Collection values)
+    {
+        if (values == null || !values.isEmpty())
+        {
+            return null;
+        }
+        Calendar[] calendars = new Calendar[values.size()];
+        int index = 0;
+        for (Object val : values)
+        {
+            calendars[index++] = toCalendar(val);
+        }
+        return calendars;
+    }
+
+
+    // --------------------- basic string parsing methods --------------
+
+    /**
+     * Converts a parameter value into a {@link Boolean}
+     * Sub-classes can override to allow for customized boolean parsing.
+     * (e.g. to handle "Yes/No" or "T/F")
+     *
+     * @param value the string to be parsed
+     * @return the value as a {@link Boolean}
+     */
+    protected Boolean parseBoolean(String value)
+    {
+        return Boolean.valueOf(value);
+    }
+
+    /**
+     * Converts a single String value into an array of Strings by splitting
+     * it on the tool's set stringsDelimiter.  The default stringsDelimiter is a comma.
+     *
+     */
+    protected String[] parseStringList(String value)
+    {
+        if (value.indexOf(this.stringsDelimiter) < 0)
+        {
+            return new String[] { value };
+        }
+        return value.split(this.stringsDelimiter);
+    }
+
+    /**
+     * Converts a String value into a Locale.
+     *
+     */
+    protected Locale parseLocale(String value)
+    {
+        if (value.indexOf("_") < 0)
+        {
+            return new Locale(value);
+        }
+
+        String[] params = value.split("_");
+        if (params.length == 2)
+        {
+            return new Locale(params[0], params[1]);
+        }
+        else if (params.length == 3)
+        {
+            return new Locale(params[0], params[1], params[2]);
+        }
+        else
+        {
+            // there's only 3 possible params, so this must be invalid
+            return null;
+        }
+    }
+
+
+    // ------------------------- number parsing methods ---------------
+
+    /**
+     * Converts an object to an instance of {@link Number} using the
+     * format returned by {@link #getFormat()} and the default {@link Locale}
+     * if the object is not already an instance of Number.
+     *
+     * @param value the string to parse
+     * @return the string as a {@link Number} or <code>null</code> if no
+     *         conversion is possible
+     */
+    public Number parseNumber(String value)
+    {
+        return parseNumber(value, this.numberFormat);
+    }
+
+    /**
+     * Converts an object to an instance of {@link Number} using the
+     * specified format and the {@link Locale} returned by
+     * {@link #getLocale()}.
+     *
+     * @param value - the string to parse
+     * @param format - the format the number is in
+     * @return the string as a {@link Number} or <code>null</code> if no
+     *         conversion is possible
+     * @see #parseNumber(String format, Object obj, Locale locale)
+     */
+    public Number parseNumber(String value, String format)
+    {
+        return parseNumber(value, format, getLocale());
+    }
+
+    /**
+     * Converts an object to an instance of {@link Number} using the
+     * configured number format and the specified {@link Locale}.
+     *
+     * @param value - the string to parse
+     * @param locale - the {@link Locale}
+     * @return the string as a {@link Number} or <code>null</code> if no
+     *         conversion is possible
+     * @see NumberFormat#parse
+     */
+    public Number parseNumber(String value, Locale locale)
+    {
+        return parseNumber(value, this.numberFormat, locale);
+    }
+
+    /**
+     * Converts an object to an instance of {@link Number} using the
+     * specified format and {@link Locale}.
+     *
+     * @param value - the string to parse
+     * @param format - the format the number is in
+     * @param locale - the {@link Locale}
+     * @return the string as a {@link Number} or <code>null</code> if no
+     *         conversion is possible
+     * @see NumberFormat#parse
+     */
+    public Number parseNumber(String value, String format, Object locale)
+    {
+        Locale lcl = toLocale(locale);
+        if (lcl == null && locale != null)
+        {
+            // then they gave a broken locale value; fail, to inform them
+            return null;
+        }
+        return ConversionUtils.toNumber(value, format, lcl);
+    }
+
+    // ----------------- date parsing methods ---------------
+
+    /**
+     * Converts a string to an instance of {@link Date},
+     * using the configured date parsing format, the configured default
+     * {@link Locale}, and the system's default {@link TimeZone} to parse it.
+     *
+     * @param value the date to convert
+     * @return the object as a {@link Date} or <code>null</code> if no
+     *         conversion is possible
+     */
+    public Date parseDate(String value)
+    {
+        return parseDate(value, this.dateFormat);
+    }
+
+    /**
+     * Converts a string to an instance of {@link Date} using the
+     * specified format,the configured default {@link Locale},
+     * and the system's default {@link TimeZone} to parse it.
+     *
+     * @param value - the date to convert
+     * @param format - the format the date is in
+     * @return the string as a {@link Date} or <code>null</code> if no
+     *         conversion is possible
+     * @see ConversionUtils#toDate(String value, String format, Object locale, TimeZone timezone)
+     */
+    public Date parseDate(String value, String format)
+    {
+        return parseDate(value, format, getLocale());
+    }
+
+    /**
+     * Converts a string to an instance of {@link Date} using the
+     * configured date format and specified {@link Locale} to parse it.
+     *
+     * @param value - the date to convert
+     * @param locale - the {@link Locale}
+     * @return the string as a {@link Date} or <code>null</code> if no
+     *         conversion is possible
+     * @see SimpleDateFormat#parse
+     */
+    public Date parseDate(String value, Locale locale)
+    {
+        return parseDate(value, this.dateFormat, locale);
+    }
+
+    /**
+     * Converts a string to an instance of {@link Date} using the
+     * specified format and {@link Locale} to parse it.
+     *
+     * @param value - the date to convert
+     * @param format - the format the date is in
+     * @param locale - the {@link Locale}
+     * @return the string as a {@link Date} or <code>null</code> if no
+     *         conversion is possible
+     * @see SimpleDateFormat#parse
+     */
+    public Date parseDate(String value, String format, Object locale)
+    {
+        return parseDate(value, format, locale, TimeZone.getDefault());
+    }
+
+    /**
+     * Converts a string to an instance of {@link Date} using the
+     * specified format, {@link Locale}, and {@link TimeZone}.
+     *
+     * @param value - the date to convert
+     * @param format - the format the date is in
+     * @param locale - the {@link Locale}
+     * @param timezone - the {@link TimeZone}
+     * @return the string as a {@link Date} or <code>null</code> if no
+     *         conversion is possible
+     * @see #getDateFormat
+     * @see SimpleDateFormat#parse
+     */
+    public Date parseDate(String value, String format,
+                          Object locale, TimeZone timezone)
+    {
+        Locale lcl = toLocale(locale);
+        if (lcl == null && locale != null)
+        {
+            // the 'locale' passed in was broken, so don't pretend it worked
+            return null;
+        }
+        return ConversionUtils.toDate(value, format, lcl, timezone);
+    }
+
+}

Propchange: velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/generic/ConversionTool.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools/generic/ConversionTool.java
------------------------------------------------------------------------------
    svn:keywords = Revision



Mime
View raw message