You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@velocity.apache.org by nb...@apache.org on 2007/06/08 07:16:02 UTC
svn commit: r545415 - in
/velocity/tools/branches/2.x/src/main/java/org/apache/velocity/tools:
ConversionUtils.java generic/ConversionTool.java
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:
+ * <tools>
+ * <toolbox scope="application">
+ * <tool class="org.apache.velocity.tools.generic.ConversionTool"
+ * dateFormat="yyyy-MM-dd"/>
+ * </toolbox>
+ * </tools>
+ * </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