package org.apache.fulcrum.parser;

/*
 * 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.beans.IndexedPropertyDescriptor;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import java.util.Set;

import org.apache.avalon.framework.logger.LogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

/**
 * BaseValueParser is a base class for classes that need to parse
 * name/value Parameters, for example GET/POST data or Cookies
 * (DefaultParameterParser and DefaultCookieParser)
 *
 * <p>It can also be used standalone, for an example see DataStreamParser.
 *
 * <p>NOTE: The name= portion of a name=value pair may be converted
 * to lowercase or uppercase when the object is initialized and when
 * new data is added.  This behavior is determined by the url.case.folding
 * property in TurbineResources.properties.  Adding a name/value pair may
 * overwrite existing name=value pairs if the names match:
 *
 * <pre>
 * ValueParser vp = new BaseValueParser();
 * vp.add("ERROR",1);
 * vp.add("eRrOr",2);
 * int result = vp.getInt("ERROR");
 * </pre>
 *
 * In the above example, result is 2.
 *
 * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
 * @author <a href="mailto:jon@clearink.com">Jon S. Stevens</a>
 * @author <a href="mailto:sean@informage.net">Sean Legassick</a>
 * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a>
 * @author <a href="mailto:jh@byteaction.de">J&#252;rgen Hoffmann</a>
 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
 * @version $Id$
 */
public class BaseValueParser
    implements ValueParser,
               ParserServiceSupport, LogEnabled
{
    /** The ParserService instance to query for conversion and configuration */
    protected ParserService parserService;

    /** A convenience logger */
    private Logger logger;

    /** String values which would evaluate to Boolean.TRUE */
    private static final String[] TRUE_VALUES = {"TRUE","T","YES","Y","1","ON"};

    /** String values which would evaluate to Boolean.FALSE */
    private static final String[] FALSE_VALUES = {"FALSE","F","NO","N","0","OFF"};

    /**
     * The character encoding to use when converting to byte arrays
     */
    private String characterEncoding = DEFAULT_CHARACTER_ENCODING;

    /**
     * Random access storage for parameter data.
     */
    protected Hashtable<String, Object> parameters = new Hashtable<String, Object>();

    /** The locale to use when converting dates, floats and decimals */
    private Locale locale = Locale.getDefault();

    /** The DateFormat to use for converting dates */
    private DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, locale);

    /** The NumberFormat to use when converting floats and decimals */
    private NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);

    public BaseValueParser()
    {
        this(DEFAULT_CHARACTER_ENCODING);
    }

    /**
     * Constructor that takes a character encoding
     * 
     * @param characterEncoding desired character encoding
     */
    public BaseValueParser(String characterEncoding)
    {
        this(characterEncoding, Locale.getDefault());
    }

    /**
     * Constructor that takes a character encoding and a locale
     * 
     * @param characterEncoding Sets the character encoding
     * @param locale Sets the locale
     */
    public BaseValueParser(String characterEncoding, Locale locale)
    {
        super();
        recycle(characterEncoding);
        setLocale(locale);
    }

    /**
     * Set a ParserService instance
     * 
     * @param parserService The parser service instance
     */
    @Override
    public void setParserService(ParserService parserService)
    {
        this.parserService = parserService;
    }

    /**
     * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(org.apache.avalon.framework.logger.Logger)
     * @param logger The logger to be used
     */
    @Override
    public void enableLogging(Logger logger)
    {
        this.logger = logger;
    }

    /**
     * Provide an Avalon logger to the derived classes
     *
     * @return An Avalon logger instance
     */
    protected Logger getLogger()
    {
        return logger;
    }

    /**
     * Recycles the parser.
     */
    public final void recycle()
    {
        recycle(DEFAULT_CHARACTER_ENCODING);
    }

    /**
     * Recycles the parser with a character encoding.
     *
     * @param characterEncoding the character encoding.
     */
    public final void recycle(String characterEncoding)
    {
        setCharacterEncoding(characterEncoding);
    }

    /**
     * Disposes the parser.
     */
    @Override
    public void dispose()
    {
        clear();
        disposed = true;
    }

    /**
     * Clear all name/value pairs out of this object.
     */
    @Override
    public void clear()
    {
        parameters.clear();
    }

    /**
     * Set the character encoding that will be used by this ValueParser.
     */
    @Override
    public final void setCharacterEncoding(String s)
    {
        characterEncoding = s;
    }

    /**
     * Get the character encoding that will be used by this ValueParser.
     */
    @Override
    public String getCharacterEncoding()
    {
        return characterEncoding;
    }

    /**
     * Set the locale that will be used by this ValueParser.
     */
    @Override
    public final void setLocale(Locale l)
    {
        locale = l;
        setDateFormat(DateFormat.getDateInstance(DateFormat.SHORT, locale));
        setNumberFormat(NumberFormat.getNumberInstance(locale));
    }

    /**
     * Get the locale that will be used by this ValueParser.
     */
    @Override
    public final Locale getLocale()
    {
        return locale;
    }

    /**
     * Set the date format that will be used by this ValueParser.
     */
    @Override
    public final void setDateFormat(DateFormat df)
    {
        dateFormat = df;
    }

    /**
     * Get the date format that will be used by this ValueParser.
     */
    @Override
    public DateFormat getDateFormat()
    {
        return dateFormat;
    }

    /**
     * Set the number format that will be used by this ValueParser.
     */
    @Override
    public void setNumberFormat(NumberFormat nf)
    {
        numberFormat = nf;
    }

    /**
     * Get the number format that will be used by this ValueParser.
     */
    @Override
    public NumberFormat getNumberFormat()
    {
        return numberFormat;
    }

    /**
     * Add a name/value pair into this object.
     *
     * @param name A String with the name.
     * @param value A double with the value.
     */
    @Override
    public void add(String name, double value)
    {
        add(name, numberFormat.format(value));
    }

    /**
     * Add a name/value pair into this object.
     *
     * @param name A String with the name.
     * @param value An int with the value.
     */
    @Override
    public void add(String name, int value)
    {
        add(name, (long)value);
    }

    /**
     * Add a name/value pair into this object.
     *
     * @param name A String with the name.
     * @param value An Integer with the value.
     */
    @Override
    public void add(String name, Integer value)
    {
        if (value != null)
        {
            add(name, value.intValue());
        }
    }

    /**
     * Add a name/value pair into this object.
     *
     * @param name A String with the name.
     * @param value A long with the value.
     */
    @Override
    public void add(String name, long value)
    {
        add(name, Long.toString(value));
    }

    /**
     * Add a name/value pair into this object.
     *
     * @param name A String with the name.
     * @param value A long with the value.
     */
    @Override
    public void add(String name, String value)
    {
        if (value != null)
        {
            String [] items = getParam(name);
            items = ArrayUtils.add(items, value);
            putParam(name, items);
        }
    }

    /**
     * Add an array of Strings for a key. This
     * is simply adding all the elements in the
     * array one by one.
     *
     * @param name A String with the name.
     * @param value A String Array.
     */
    @Override
    public void add(String name, String [] value)
    {
        // ArrayUtils.addAll() looks promising but it would also add
        // null values into the parameters array, so we can't use that.
        if (value != null)
        {
            for (int i = 0 ; i < value.length; i++)
            {
                if (value[i] != null)
                {
                    add(name, value[i]);
                }
            }
        }
    }

    /**
     * Removes the named parameter from the contained hashtable. Wraps to the
     * contained <code>Map.remove()</code>.
     *
     * @return The value that was mapped to the key (a <code>String[]</code>)
     *         or <code>null</code> if the key was not mapped.
     */
    @Override
    public Object remove(String name)
    {
        return parameters.remove(convert(name));
    }

    /**
     * Trims the string data and applies the conversion specified in
     * the property given by URL_CASE_FOLDING.  It returns a new
     * string so that it does not destroy the value data.
     *
     * @param value A String to be processed.
     * @return A new String converted to lowercase and trimmed.
     */
    @Override
    public String convert(String value)
    {
        return convertAndTrim(value);
    }

    /**
     * Determine whether a given key has been inserted.  All keys are
     * stored in lowercase strings, so override method to account for
     * this.
     *
     * @param key An Object with the key to search for.
     * @return True if the object is found.
     */
    @Override
    public boolean containsKey(Object key)
    {
        return parameters.containsKey(convert(String.valueOf(key)));
    }

    /**
     * Gets the set of keys
     *
     * @return A <code>Set</code> of the keys.
     */
    @Override
    public Set<String> keySet()
    {
        return parameters.keySet();
    }

    /**
     * Returns all the available parameter names.
     *
     * @return A object array with the keys.
     */
    @Override
    public String[] getKeys()
    {
        return keySet().toArray(new String[0]);
    }

    /**
     * Gets an iterator over the set of keys
     *
     * @return An <code>Iterator</code> over the keys.
     */
    @Override
    public Iterator<String> iterator()
    {
        return parameters.keySet().iterator();
    }

    /**
     * Returns a Boolean object for the given string. If the value
     * can not be parsed as a boolean, null is returned.
     * <p>
     * Valid values for true: true, t, on, 1, yes, y<br>
     * Valid values for false: false, f, off, 0, no, n<br>
     * <p>
     * The string is compared without reguard to case.
     *
     * @param string A String with the value.
     * @return A Boolean.
     */
    private Boolean parseBoolean(String string)
    {
        Boolean result = null;
        String value = StringUtils.trim(string);

        if (StringUtils.isNotEmpty(value))
        {
            for (int cnt = 0;
            cnt < Math.max(TRUE_VALUES.length, FALSE_VALUES.length); cnt++)
            {
                // Short-cut evaluation or bust!
                if (cnt < TRUE_VALUES.length &&
                   value.equalsIgnoreCase(TRUE_VALUES[cnt]))
                {
                    result = Boolean.TRUE;
                    break;
                }

                if (cnt < FALSE_VALUES.length &&
                   value.equalsIgnoreCase(FALSE_VALUES[cnt]))
                {
                    result = Boolean.FALSE;
                    break;
                }
            }

            if (result == null && getLogger().isWarnEnabled() == true)
            {
                getLogger().warn("Parameter with value of ("
                        + value + ") could not be converted to a Boolean");
            }
        }

        return result;
    }

    /**
     * Return a boolean for the given name.  If the name does not
     * exist, return defaultValue.
     *
     * @param name A String with the name.
     * @param defaultValue The default value.
     * @return A boolean.
     */
    @Override
    public boolean getBoolean(String name, boolean defaultValue)
    {
        Boolean result = getBooleanObject(name);
        return (result == null ? defaultValue : result.booleanValue());
    }

    /**
     * Return a boolean for the given name.  If the name does not
     * exist, return false.
     *
     * @param name A String with the name.
     * @return A boolean.
     */
    @Override
    public boolean getBoolean(String name)
    {
        return getBoolean(name, false);
    }

    /**
     * Return an array of booleans for the given name.  If the name does
     * not exist, return null.
     *
     * @param name A String with the name.
     * @return A boolean[].
     */
    @Override
    public boolean[] getBooleans(String name)
    {
        boolean[] result = null;
        String value[] = getParam(name);
        if (value != null)
        {
            result = new boolean[value.length];
            for (int i = 0; i < value.length; i++)
            {
            	// default to false
            	result[i] = false;
            	
            	// update with parsed value if exists
            	Boolean bool = parseBoolean(value[i]);
                if ( bool != null )
                {
                	result[i] = bool.booleanValue();
                }            	
            }
        }
        return result;
    }

    /**
     * Returns a Boolean object for the given name.  If the parameter
     * does not exist or can not be parsed as a boolean, null is returned.
     * <p>
     * Valid values for true: true, on, 1, yes<br>
     * Valid values for false: false, off, 0, no<br>
     * <p>
     * The string is compared without reguard to case.
     *
     * @param name A String with the name.
     * @return A Boolean.
     */
    @Override
    public Boolean getBooleanObject(String name)
    {
        return parseBoolean(getString(name));
    }

    /**
     * Returns a Boolean object for the given name.  If the parameter
     * does not exist or can not be parsed as a boolean, null is returned.
     * <p>
     * Valid values for true: true, on, 1, yes<br>
     * Valid values for false: false, off, 0, no<br>
     * <p>
     * The string is compared without reguard to case.
     *
     * @param name A String with the name.
     * @param defaultValue The default value.
     * @return A Boolean.
     */
    @Override
    public Boolean getBooleanObject(String name, Boolean defaultValue)
    {
        Boolean result = getBooleanObject(name);
        return (result == null ? defaultValue : result);
    }

    /**
     * Return an array of Booleans for the given name.  If the name does
     * not exist, return null.
     *
     * @param name A String with the name.
     * @return A Boolean[].
     */
    @Override
    public Boolean[] getBooleanObjects(String name)
    {
        Boolean[] result = null;
        String value[] = getParam(name);
        if (value != null)
        {
            result = new Boolean[value.length];
            for (int i = 0; i < value.length; i++)
            {
                result[i] = parseBoolean(value[i]);
            }
        }
        return result;
    }

    /**
     * Return a {@link Number} for the given string.
     *
     * @param string A String with the value.
     * @return A Number.
     *
     */
    private Number parseNumber(String string)
    {
        Number result = null;
        String value = StringUtils.trim(string);

        if (StringUtils.isNotEmpty(value))
        {
            ParsePosition pos = new ParsePosition(0);
            Number number = numberFormat.parse(value, pos);

            if (pos.getIndex() == value.length())
            {
                // completely parsed
                result = number;
            }
            else
            {
                if (getLogger().isWarnEnabled())
                {
                    getLogger().warn("Parameter with value of ("
                            + value + ") could not be converted to a Number at position " + pos.getIndex());
                }
            }
        }

        return result;
    }

    /**
     * Return a {@link Number} for the given name.  If the name does not
     * exist, return null. This is the base function for all numbers.
     *
     * @param name A String with the name.
     * @return A Number.
     *
     */
    private Number getNumber(String name)
    {
        return parseNumber(getString(name));
    }

    /**
     * Return a double for the given name.  If the name does not
     * exist, return defaultValue.
     *
     * @param name A String with the name.
     * @param defaultValue The default value.
     * @return A double.
     */
    @Override
    public double getDouble(String name, double defaultValue)
    {
        Number number = getNumber(name);
        return (number == null ? defaultValue : number.doubleValue());
    }

    /**
     * Return a double for the given name.  If the name does not
     * exist, return 0.0.
     *
     * @param name A String with the name.
     * @return A double.
     */
    @Override
    public double getDouble(String name)
    {
        return getDouble(name, 0.0);
    }

    /**
     * Return an array of doubles for the given name.  If the name does
     * not exist, return null.
     *
     * @param name A String with the name.
     * @return A double[].
     */
    @Override
    public double[] getDoubles(String name)
    {
        double[] result = null;
        String value[] = getParam(name);
        if (value != null)
        {
            result = new double[value.length];
            for (int i = 0; i < value.length; i++)
            {
                Number number = parseNumber(value[i]);
                result[i] = (number == null ? 0.0 : number.doubleValue());
            }
        }
        return result;
    }

    /**
     * Return a Double for the given name.  If the name does not
     * exist, return defaultValue.
     *
     * @param name A String with the name.
     * @param defaultValue The default value.
     * @return A double.
     */
    @Override
    public Double getDoubleObject(String name, Double defaultValue)
    {
        Number result = getNumber(name);
        return (result == null ? defaultValue : new Double(result.doubleValue()));
    }

    /**
     * Return a Double for the given name.  If the name does not
     * exist, return null.
     *
     * @param name A String with the name.
     * @return A double.
     */
    @Override
    public Double getDoubleObject(String name)
    {
        return getDoubleObject(name, null);
    }

    /**
     * Return an array of doubles for the given name.  If the name does
     * not exist, return null.
     *
     * @param name A String with the name.
     * @return A double[].
     */
    @Override
    public Double[] getDoubleObjects(String name)
    {
        Double[] result = null;
        String value[] = getParam(name);
        if (value != null)
        {
            result = new Double[value.length];
            for (int i = 0; i < value.length; i++)
            {
                Number number = parseNumber(value[i]);
                result[i] = (number == null ? null : new Double(number.doubleValue()));
            }
        }
        return result;
    }

    /**
     * Return a float for the given name.  If the name does not
     * exist, return defaultValue.
     *
     * @param name A String with the name.
     * @param defaultValue The default value.
     * @return A float.
     */
    @Override
    public float getFloat(String name, float defaultValue)
    {
        Number number = getNumber(name);
        return (number == null ? defaultValue : number.floatValue());
    }

    /**
     * Return a float for the given name.  If the name does not
     * exist, return 0.0.
     *
     * @param name A String with the name.
     * @return A float.
     */
    @Override
    public float getFloat(String name)
    {
        return getFloat(name, 0.0f);
    }

    /**
     * Return an array of floats for the given name.  If the name does
     * not exist, return null.
     *
     * @param name A String with the name.
     * @return A float[].
     */
    @Override
    public float[] getFloats(String name)
    {
        float[] result = null;
        String value[] = getParam(name);
        if (value != null)
        {
            result = new float[value.length];
            for (int i = 0; i < value.length; i++)
            {
                Number number = parseNumber(value[i]);
                result[i] = (number == null ? 0.0f : number.floatValue());
            }
        }
        return result;
    }

    /**
     * Return a Float for the given name.  If the name does not
     * exist, return defaultValue.
     *
     * @param name A String with the name.
     * @param defaultValue The default value.
     * @return A Float.
     */
    @Override
    public Float getFloatObject(String name, Float defaultValue)
    {
        Number result = getNumber(name);
        return (result == null ? defaultValue : new Float(result.floatValue()));
    }

    /**
     * Return a float for the given name.  If the name does not
     * exist, return null.
     *
     * @param name A String with the name.
     * @return A Float.
     */
    @Override
    public Float getFloatObject(String name)
    {
        return getFloatObject(name, null);
    }

    /**
     * Return an array of floats for the given name.  If the name does
     * not exist, return null.
     *
     * @param name A String with the name.
     * @return A float[].
     */
    @Override
    public Float[] getFloatObjects(String name)
    {
        Float[] result = null;
        String value[] = getParam(name);
        if (value != null)
        {
            result = new Float[value.length];
            for (int i = 0; i < value.length; i++)
            {
                Number number = parseNumber(value[i]);
                result[i] = (number == null ? null : new Float(number.floatValue()));
            }
        }
        return result;
    }

    /**
     * Return a BigDecimal for the given name.  If the name does not
     * exist, return defaultValue.
     *
     * @param name A String with the name.
     * @param defaultValue The default value.
     * @return A BigDecimal.
     */
    @Override
    public BigDecimal getBigDecimal(String name, BigDecimal defaultValue)
    {
        Number result = getNumber(name);
        return (result == null ? defaultValue : new BigDecimal(result.doubleValue()));
    }

    /**
     * Return a BigDecimal for the given name.  If the name does not
     * exist, return null.
     *
     * @param name A String with the name.
     * @return A BigDecimal.
     */
    @Override
    public BigDecimal getBigDecimal(String name)
    {
        return getBigDecimal(name, null);
    }

    /**
     * Return an array of BigDecimals for the given name.  If the name
     * does not exist, return null.
     *
     * @param name A String with the name.
     * @return A BigDecimal[].
     */
    @Override
    public BigDecimal[] getBigDecimals(String name)
    {
        BigDecimal[] result = null;
        String value[] = getParam(name);
        if (value != null)
        {
            result = new BigDecimal[value.length];
            for (int i = 0; i < value.length; i++)
            {
                Number number = parseNumber(value[i]);
                result[i] = (number == null ? null : new BigDecimal(number.doubleValue()));
            }
        }
        return result;
    }

    /**
     * Return an int for the given name.  If the name does not exist,
     * return defaultValue.
     *
     * @param name A String with the name.
     * @param defaultValue The default value.
     * @return An int.
     */
    @Override
    public int getInt(String name, int defaultValue)
    {
        Number result = getNumber(name);
        return (result == null || result instanceof Double ? defaultValue : result.intValue());
    }

    /**
     * Return an int for the given name.  If the name does not exist,
     * return 0.
     *
     * @param name A String with the name.
     * @return An int.
     */
    @Override
    public int getInt(String name)
    {
        return getInt(name, 0);
    }

    /**
     * Return an array of ints for the given name.  If the name does
     * not exist, return null.
     *
     * @param name A String with the name.
     * @return An int[].
     */
    @Override
    public int[] getInts(String name)
    {
        int[] result = null;
        String value[] = getParam(name);
        if (value != null)
        {
            result = new int[value.length];
            for (int i = 0; i < value.length; i++)
            {
                Number number = parseNumber(value[i]);
                result[i] = (number == null || number instanceof Double ? 0 : number.intValue());
            }
        }
        return result;
    }

    /**
     * Return an Integer for the given name.  If the name does not exist,
     * return defaultValue.
     *
     * @param name A String with the name.
     * @param defaultValue The default value.
     * @return An Integer.
     */
    @Override
    public Integer getIntObject(String name, Integer defaultValue)
    {
        Number result = getNumber(name);
        return (result == null || result instanceof Double ? defaultValue : Integer.valueOf(result.intValue()));
    }

    /**
     * Return an Integer for the given name.  If the name does not exist,
     * return null.
     *
     * @param name A String with the name.
     * @return An Integer.
     */
    @Override
    public Integer getIntObject(String name)
    {
        return getIntObject(name, null);
    }

    /**
     * Return an array of Integers for the given name.  If the name
     * does not exist, return null.
     *
     * @param name A String with the name.
     * @return An Integer[].
     */
    @Override
    public Integer[] getIntObjects(String name)
    {
        Integer[] result = null;
        String value[] = getParam(name);
        if (value != null)
        {
            result = new Integer[value.length];
            for (int i = 0; i < value.length; i++)
            {
                Number number = parseNumber(value[i]);
                result[i] = (number == null || number instanceof Double ? null : Integer.valueOf(number.intValue()));
            }
        }
        return result;
    }

    /**
     * Return a long for the given name.  If the name does not exist,
     * return defaultValue.
     *
     * @param name A String with the name.
     * @param defaultValue The default value.
     * @return A long.
     */
    @Override
    public long getLong(String name, long defaultValue)
    {
        Number result = getNumber(name);
        return (result == null || result instanceof Double ? defaultValue : result.longValue());
    }

    /**
     * Return a long for the given name.  If the name does not exist,
     * return 0.
     *
     * @param name A String with the name.
     * @return A long.
     */
    @Override
    public long getLong(String name)
    {
        return getLong(name, 0);
    }

    /**
     * Return an array of longs for the given name.  If the name does
     * not exist, return null.
     *
     * @param name A String with the name.
     * @return A long[].
     */
    @Override
    public long[] getLongs(String name)
    {
        long[] result = null;
        String value[] = getParam(name);
        if (value != null)
        {
            result = new long[value.length];
            for (int i = 0; i < value.length; i++)
            {
                Number number = parseNumber(value[i]);
                result[i] = (number == null || number instanceof Double ? 0L : number.longValue());
            }
        }
        return result;
    }

    /**
     * Return an array of Longs for the given name.  If the name does
     * not exist, return null.
     *
     * @param name A String with the name.
     * @return A Long[].
     */
    @Override
    public Long[] getLongObjects(String name)
    {
        Long[] result = null;
        String value[] = getParam(name);
        if (value != null)
        {
            result = new Long[value.length];
            for (int i = 0; i < value.length; i++)
            {
                Number number = parseNumber(value[i]);
                result[i] = (number == null || number instanceof Double ? null : Long.valueOf(number.longValue()));
            }
        }
        return result;
    }

    /**
     * Return a Long for the given name.  If the name does
     * not exist, return null.
     *
     * @param name A String with the name.
     * @return A Long.
     */
    @Override
    public Long getLongObject(String name)
    {
        return getLongObject(name, null);
    }

    /**
     * Return a Long for the given name.  If the name does
     * not exist, return the default value.
     *
     * @param name A String with the name.
     * @param defaultValue The default value.
     * @return A Long.
     */
    @Override
    public Long getLongObject(String name, Long defaultValue)
    {
        Number result = getNumber(name);
        return (result == null || result instanceof Double ? defaultValue : Long.valueOf(result.longValue()));
    }

    /**
     * Return a byte for the given name.  If the name does not exist,
     * return defaultValue.
     *
     * @param name A String with the name.
     * @param defaultValue The default value.
     * @return A byte.
     */
    @Override
    public byte getByte(String name, byte defaultValue)
    {
        Number result = getNumber(name);
        return (result == null || result instanceof Double ? defaultValue : result.byteValue());
    }

    /**
     * Return a byte for the given name.  If the name does not exist,
     * return 0.
     *
     * @param name A String with the name.
     * @return A byte.
     */
    @Override
    public byte getByte(String name)
    {
        return getByte(name, (byte) 0);
    }

    /**
     * Return an array of bytes for the given name.  If the name does
     * not exist, return null. The array is returned according to the
     * HttpRequest's character encoding.
     *
     * @param name A String with the name.
     * @return A byte[].
     * @throws UnsupportedEncodingException Generic exception
     */
    @Override
    public byte[] getBytes(String name)
            throws UnsupportedEncodingException
    {
        byte result[] = null;
        String value = getString(name);
        if (value != null)
        {
            result = value.getBytes(getCharacterEncoding());
        }
        return result;
    }

    /**
     * Return a byte for the given name.  If the name does not exist,
     * return defaultValue.
     *
     * @param name A String with the name.
     * @param defaultValue The default value.
     * @return A byte.
     */
    @Override
    public Byte getByteObject(String name, Byte defaultValue)
    {
        Number result = getNumber(name);
        return (result == null || result instanceof Double ? defaultValue : Byte.valueOf(result.byteValue()));
    }

    /**
     * Return a byte for the given name.  If the name does not exist,
     * return 0.
     *
     * @param name A String with the name.
     * @return A byte.
     */
    @Override
    public Byte getByteObject(String name)
    {
        return getByteObject(name, null);
    }

    /**
     * Return a String for the given name.  If the name does not
     * exist, return null.
     *
     * @param name A String with the name.
     * @return A String or null if the key is unknown.
     */
    @Override
    public String getString(String name)
    {
        String [] value = getParam(name);
        return value == null || value.length == 0 ? null : value[0];
    }

    /**
     * Return a String for the given name.  If the name does not
     * exist, return null. It is the same as the getString() method
     * however has been added for simplicity when working with
     * template tools such as Velocity which allow you to do
     * something like this:
     *
     * <code>$data.Parameters.form_variable_name</code>
     *
     * @param name A String with the name.
     * @return A String.
     */
    @Override
    public String get(String name)
    {
        return getString(name);
    }

    /**
     * Return a String for the given name.  If the name does not
     * exist, return the defaultValue.
     *
     * @param name A String with the name.
     * @param defaultValue The default value.
     * @return A String.
     */
    @Override
    public String getString(String name, String defaultValue)
    {
        String value = getString(name);
        return StringUtils.isEmpty(value) ? defaultValue : value;
    }

    /**
     * Set a parameter to a specific value.
     *
     * This is useful if you want your action to override the values
     * of the parameters for the screen to use.
     * @param name The name of the parameter.
     * @param value The value to set.
     */
    @Override
    public void setString(String name, String value)
    {
        if (value != null)
        {
            putParam(name, new String[]{value});
        }
    }

    /**
     * Return an array of Strings for the given name.  If the name
     * does not exist, return null.
     *
     * @param name A String with the name.
     * @return A String[].
     */
    @Override
    public String[] getStrings(String name)
    {
        return getParam(name);
    }

    /**
     * Return an array of Strings for the given name.  If the name
     * does not exist, return the defaultValue.
     *
     * @param name A String with the name.
     * @param defaultValue The default value.
     * @return A String[].
     */
    @Override
    public String[] getStrings(String name, String[] defaultValue)
    {
        String[] value = getParam(name);
        return value == null || value.length == 0 ? defaultValue : value;
    }

    /**
     * Set a parameter to a specific value.
     *
     * This is useful if you want your action to override the values
     * of the parameters for the screen to use.
     * @param name The name of the parameter.
     * @param values The value to set.
     */
    @Override
    public void setStrings(String name, String[] values)
    {
        if (values != null)
        {
            putParam(name, values);
        }
    }

    /**
     * Return an Object for the given name.  If the name does not
     * exist, return null.
     *
     * @param name A String with the name.
     * @return An Object.
     */
    @Override
    public Object getObject(String name)
    {
        return getString(name);
    }

    /**
     * Return an array of Objects for the given name.  If the name
     * does not exist, return null.
     *
     * @param name A String with the name.
     * @return An Object[].
     */
    @Override
    public Object[] getObjects(String name)
    {
        return getParam(name);
    }

    /**
     * Returns a {@link java.util.Date} object.  String is parsed by supplied
     * DateFormat.  If the name does not exist or the value could not be
     * parsed into a date return the defaultValue.
     *
     * @param name A String with the name.
     * @param df A DateFormat.
     * @param defaultValue The default value.
     * @return A Date.
     */
    @Override
    public Date getDate(String name, DateFormat df, Date defaultValue)
    {
        Date result = defaultValue;
        String value = StringUtils.trim(getString(name));
        if (StringUtils.isNotEmpty(value))
        {
            try
            {
                // Reject invalid dates.
                df.setLenient(false);
                result = df.parse(value);
            }
            catch (ParseException e)
            {
                logConversionFailure(name, value, "Date");
            }
        }

        return result;
    }

    /**
     * Returns a {@link java.util.Date} object.  If there are DateSelector or
     * TimeSelector style parameters then these are used.  If not and there
     * is a parameter 'name' then this is parsed by DateFormat.  If the
     * name does not exist, return null.
     *
     * @param name A String with the name.
     * @return A Date.
     */
    @Override
    public Date getDate(String name)
    {
        return getDate(name, dateFormat, null);
    }

    /**
     * Returns a {@link java.util.Date} object.  String is parsed by supplied
     * DateFormat.  If the name does not exist, return null.
     *
     * @param name A String with the name.
     * @param df A DateFormat.
     * @return A Date.
     */
    @Override
    public Date getDate(String name, DateFormat df)
    {
        return getDate(name, df, null);
    }

    /**
     * Uses bean introspection to set writable properties of bean from
     * the parameters, where a (case-insensitive) name match between
     * the bean property and the parameter is looked for.
     *
     * @param bean An Object.
     * @throws Exception a generic exception.
     */
    @Override
    public void setProperties(Object bean) throws Exception
    {
        Class<?> beanClass = bean.getClass();
        PropertyDescriptor[] props
                = Introspector.getBeanInfo(beanClass).getPropertyDescriptors();

        for ( PropertyDescriptor pd : props )
        {
            String propname = pd.getName();
            Method setter = pd.getWriteMethod();
            if (setter != null && containsKey(propname))
            {
                setProperty(bean, pd);
            }
        }
    }

    /**
     * Simple method that attempts to get a textual representation of
     * this object's name/value pairs.  String[] handling is currently
     * a bit rough.
     *
     * @return A textual representation of the parsed name/value pairs.
     */
    @Override
    public String toString()
    {
        StringBuilder sb = new StringBuilder();
        for (String name : keySet())
        {
            sb.append('{');
            sb.append(name);
            sb.append('=');
            Object [] params = getToStringParam(name);

            if (params == null)
            {
                sb.append("unknown?");
            }
            else if (params.length == 0)
            {
                sb.append("empty");
            }
            else
            {
                sb.append('[');
                sb.append(StringUtils.join(params, ", "));
                sb.append(']');
            }
            sb.append("}\n");
        }

        return sb.toString();
    }

    /**
     * This method is only used in toString() and can be used by
     * derived classes to add their local parameters to the toString()

     * @param name A string with the name
     *
     * @return the value object array or null if not set
     */
    protected Object [] getToStringParam(final String name)
    {
        return getParam(name);
    }

    /**
     * Set the property 'prop' in the bean to the value of the
     * corresponding parameters.  Supports all types supported by
     * getXXX methods plus a few more that come for free because
     * primitives have to be wrapped before being passed to invoke
     * anyway.
     *
     * @param bean An Object.
     * @param prop A PropertyDescriptor.
     * @@throws Exception a generic exception.
     */
    protected void setProperty(Object bean,
                               PropertyDescriptor prop)
            throws Exception
    {
        if (prop instanceof IndexedPropertyDescriptor)
        {
            throw new Exception(prop.getName() +
                    " is an indexed property (not supported)");
        }

        Method setter = prop.getWriteMethod();
        if (setter == null)
        {
            throw new Exception(prop.getName() +
                    " is a read only property");
        }

        Class<?> propclass = prop.getPropertyType();
        Object arg = null;

        if (propclass == String.class)
        {
            arg = getString(prop.getName());
        }
        else if (propclass == Byte.class || propclass == Byte.TYPE)
        {
            arg = getByteObject(prop.getName());
        }
        else if (propclass == Integer.class || propclass == Integer.TYPE)
        {
            arg = getIntObject(prop.getName());
        }
        else if (propclass == Long.class || propclass == Long.TYPE)
        {
            arg = getLongObject(prop.getName());
        }
        else if (propclass == Boolean.class || propclass == Boolean.TYPE)
        {
            arg = getBooleanObject(prop.getName());
        }
        else if (propclass == Double.class || propclass == Double.TYPE)
        {
            arg = getDoubleObject(prop.getName());
        }
        else if (propclass == Float.class || propclass == Float.TYPE)
        {
            arg = getFloatObject(prop.getName());
        }
        else if (propclass == BigDecimal.class)
        {
            arg = getBigDecimal(prop.getName());
        }
        else if (propclass == String[].class)
        {
            arg = getStrings(prop.getName());
        }
        else if (propclass == Object.class)
        {
            arg = getObject(prop.getName());
        }
        else if (propclass == int[].class)
        {
            arg = getInts(prop.getName());
        }
        else if (propclass == Integer[].class)
        {
            arg = getIntObjects(prop.getName());
        }
        else if (propclass == Date.class)
        {
            arg = getDate(prop.getName());
        }
        else
        {
            throw new Exception("property "
                    + prop.getName()
                    + " is of unsupported type "
                    + propclass.toString());
        }

        setter.invoke(bean, arg);
    }

    /**
     * Puts a key into the parameters map. Makes sure that the name is always
     * mapped correctly. This method also enforces the usage of arrays for the
     * parameters.
     *
     * @param name A String with the name.
     * @param value An array of Objects with the values.
     *
     */
    protected void putParam(final String name, final String [] value)
    {
        String key = convert(name);
        if (key != null)
        {
            parameters.put(key, value);
        }
    }

    /**
     * fetches a key from the parameters map. Makes sure that the name is
     * always mapped correctly.
     *
     * @param name A string with the name
     *
     * @return the value object array or null if not set
     */
    protected String [] getParam(final String name)
    {
        String key = convert(name);
        Object value = parameters.get(key);

        // todo sgoeschl 20070405 quick fix for Scott's test case - need to
        // be reworked for proper functioning according to TV
        if(value instanceof String[])
        {
            return (String []) parameters.get(key);
        }
        else
        {
            return null;
        }
    }


    /** recyclable support **/

    /**
     * The disposed flag.
     */
    private boolean disposed;

    /**
     * Checks whether the object is disposed.
     *
     * @return true, if the object is disposed.
     */
    public boolean isDisposed()
    {
        return disposed;
    }

    /**
     * Writes a log message about a conversion failure.
     *
     * @param paramName name of the parameter which could not be converted
     * @param value value of the parameter
     * @param type target data type.
     */
    private void logConversionFailure(String paramName,
                                      String value, String type)
    {
        getLogger().warn("Parameter (" + paramName
                + ") with value of ("
                + value + ") could not be converted to a " + type);
    }

    /**
     * Convert a String value according to the url-case-folding property.
     *
     * @param value the String to convert
     *
     * @return a new String.
     *
     */
    @Override
    public String convertAndTrim(String value)
    {
        return parserService.convertAndTrim(value);
    }

    /**
     * A convert method, which trims the string data and applies the
     * conversion specified in the parameter given. It returns a new
     * string so that it does not destroy the value data.
     *
     * @param value A String to be processed.
     * @param fold The parameter folding to be applied
     * (see {@link ParserService})
     * @return A new String converted to the correct case and trimmed.
     */
    @Override
    public String convertAndTrim(String value, URLCaseFolding fold)
    {
        return parserService.convertAndTrim(value, fold);
    }

    /**
     * Gets the folding value from the ParserService configuration
     *
     * @return The current Folding Value
     */
    @Override
    public URLCaseFolding getUrlFolding()
    {
        return parserService.getUrlFolding();
    }

	public boolean isValid() 
	{
    	if ( this.parameters.size() == 0 )
    	{
    		return true;
    	}
    	return false;
	}
}
