Package org.restlet.util

Source Code of org.restlet.util.Series

/**
* Copyright 2005-2011 Noelios Technologies.
*
* The contents of this file are subject to the terms of one of the following
* open source licenses: LGPL 3.0 or LGPL 2.1 or CDDL 1.0 or EPL 1.0 (the
* "Licenses"). You can select the license that you prefer but you may not use
* this file except in compliance with one of these Licenses.
*
* You can obtain a copy of the LGPL 3.0 license at
* http://www.opensource.org/licenses/lgpl-3.0.html
*
* You can obtain a copy of the LGPL 2.1 license at
* http://www.opensource.org/licenses/lgpl-2.1.php
*
* You can obtain a copy of the CDDL 1.0 license at
* http://www.opensource.org/licenses/cddl1.php
*
* You can obtain a copy of the EPL 1.0 license at
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the Licenses for the specific language governing permissions and
* limitations under the Licenses.
*
* Alternatively, you can obtain a royalty free commercial license with less
* limitations, transferable or non-transferable, directly at
* http://www.noelios.com/products/restlet-engine
*
* Restlet is a registered trademark of Noelios Technologies.
*/

package org.restlet.util;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.restlet.data.Form;
import org.restlet.data.Parameter;
import org.restlet.engine.Edition;

/**
* Modifiable list of entries with many helper methods. Note that this class
* uses the Parameter class as the template type. This allows you to use an
* instance of this class as any other java.util.List, in particular all the
* helper methods in java.util.Collections.
*
* @author Jerome Louvel
* @param <E>
*            The contained type
* @see org.restlet.data.Parameter
* @see java.util.Collections
* @see java.util.List
*/
public abstract class Series<E extends Parameter> extends WrapperList<E> {

    /**
     * A marker for empty values to differentiate from non existing values
     * (null).
     */
    public static final Object EMPTY_VALUE = new Object();

    /**
     * Returns an unmodifiable view of the specified series. Attempts to call a
     * modification method will throw an UnsupportedOperationException.
     *
     * @param series
     *            The series for which an unmodifiable view should be returned.
     * @return The unmodifiable view of the specified series.
     */
    @SuppressWarnings("unchecked")
    public static Series<? extends Parameter> unmodifiableSeries(
            Series<? extends Parameter> series) {
        if (Edition.CURRENT != Edition.GWT) {
            return new Form(java.util.Collections.unmodifiableList(series
                    .getDelegate()));
        }

        return new Form((List<Parameter>) series.getDelegate());
    }

    /**
     * Constructor.
     */
    public Series() {
        super();
    }

    /**
     * Constructor.
     *
     * @param initialCapacity
     *            The initial list capacity.
     */
    public Series(int initialCapacity) {
        super(initialCapacity);
    }

    /**
     * Constructor.
     *
     * @param delegate
     *            The delegate list.
     */
    public Series(List<E> delegate) {
        super(delegate);
    }

    /**
     * Creates then adds a parameter at the end of the list.
     *
     * @param name
     *            The parameter name.
     * @param value
     *            The parameter value.
     * @return True (as per the general contract of the Collection.add method).
     */
    public boolean add(String name, String value) {
        return add(createEntry(name, value));
    }

    /**
     * Copies the parameters whose name is a key in the given map.<br>
     * If a matching parameter is found, its value is put in the map.<br>
     * If multiple values are found, a list is created and set in the map.
     *
     * @param params
     *            The map controlling the copy.
     */
    @SuppressWarnings("unchecked")
    public void copyTo(Map<String, Object> params) {
        Parameter param;
        Object currentValue = null;
        for (final Iterator<E> iter = iterator(); iter.hasNext();) {
            param = iter.next();

            if (params.containsKey(param.getName())) {
                currentValue = params.get(param.getName());

                if (currentValue != null) {
                    List<Object> values = null;

                    if (currentValue instanceof List) {
                        // Multiple values already found for this entry
                        values = (List<Object>) currentValue;
                    } else {
                        // Second value found for this entry
                        // Create a list of values
                        values = new ArrayList<Object>();
                        values.add(currentValue);
                        params.put(param.getName(), values);
                    }

                    if (param.getValue() == null) {
                        values.add(Series.EMPTY_VALUE);
                    } else {
                        values.add(param.getValue());
                    }
                } else {
                    if (param.getValue() == null) {
                        params.put(param.getName(), Series.EMPTY_VALUE);
                    } else {
                        params.put(param.getName(), param.getValue());
                    }
                }
            }
        }
    }

    /**
     * Creates a new entry.
     *
     * @param name
     *            The name of the entry.
     * @param value
     *            The value of the entry.
     * @return A new entry.
     */
    public abstract E createEntry(String name, String value);

    /**
     * Creates a new series.
     *
     * @param delegate
     *            Optional delegate series.
     * @return A new series.
     */
    public abstract Series<E> createSeries(List<E> delegate);

    /**
     * Tests the equality of two string, potentially null, which a case
     * sensitivity flag.
     *
     * @param value1
     *            The first value.
     * @param value2
     *            The second value.
     * @param ignoreCase
     *            Indicates if the test should be case insensitive.
     * @return True if both values are equal.
     */
    private boolean equals(String value1, String value2, boolean ignoreCase) {
        boolean result = (value1 == value2);

        if (!result) {
            if ((value1 != null) && (value2 != null)) {
                if (ignoreCase) {
                    result = value1.equalsIgnoreCase(value2);
                } else {
                    result = value1.equals(value2);
                }
            }
        }

        return result;
    }

    /**
     * Returns the first parameter found with the given name.
     *
     * @param name
     *            The parameter name (case sensitive).
     * @return The first parameter found with the given name.
     */
    public E getFirst(String name) {
        return getFirst(name, false);
    }

    /**
     * Returns the first parameter found with the given name.
     *
     * @param name
     *            The parameter name.
     * @param ignoreCase
     *            Indicates if the name comparison is case insensitive.
     * @return The first parameter found with the given name.
     */
    public E getFirst(String name, boolean ignoreCase) {
        for (final E param : this) {
            if (equals(param.getName(), name, ignoreCase)) {
                return param;
            }
        }

        return null;
    }

    /**
     * Returns the value of the first parameter found with the given name.
     *
     * @param name
     *            The parameter name (case sensitive).
     * @return The value of the first parameter found with the given name.
     */
    public String getFirstValue(String name) {
        return getFirstValue(name, false);
    }

    /**
     * Returns the value of the first parameter found with the given name.
     *
     * @param name
     *            The parameter name.
     * @param ignoreCase
     *            Indicates if the name comparison is case sensitive.
     * @return The value of the first parameter found with the given name.
     */
    public String getFirstValue(String name, boolean ignoreCase) {
        return getFirstValue(name, ignoreCase, null);
    }

    /**
     * Returns the value of the first parameter found with the given name.
     *
     * @param name
     *            The parameter name.
     * @param ignoreCase
     *            Indicates if the name comparison is case sensitive.
     * @param defaultValue
     *            The default value to return if no matching parameter found or
     *            if the parameter has a null value.
     * @return The value of the first parameter found with the given name or the
     *         default value.
     */
    public String getFirstValue(String name, boolean ignoreCase,
            String defaultValue) {
        String result = defaultValue;
        Parameter param = getFirst(name, ignoreCase);

        if ((param != null) && (param.getValue() != null)) {
            result = param.getValue();
        }

        return result;
    }

    /**
     * Returns the value of the first parameter found with the given name.
     *
     * @param name
     *            The parameter name (case sensitive).
     * @param defaultValue
     *            The default value to return if no matching parameter found or
     *            if the parameter has a null value.
     * @return The value of the first parameter found with the given name or the
     *         default value.
     */
    public String getFirstValue(String name, String defaultValue) {
        return getFirstValue(name, false, defaultValue);
    }

    /**
     * Returns the set of parameter names (case sensitive).
     *
     * @return The set of parameter names.
     */
    public Set<String> getNames() {
        final Set<String> result = new HashSet<String>();

        for (final Parameter param : this) {
            result.add(param.getName());
        }

        return result;
    }

    /**
     * Returns the values of the parameters with a given name. If multiple
     * parameters with the same name are found, all values are concatenated and
     * separated by a comma (like for HTTP message headers).
     *
     * @param name
     *            The parameter name (case insensitive).
     * @return The values of the parameters with a given name.
     */
    public String getValues(String name) {
        return getValues(name, ",", true);
    }

    /**
     * Returns the parameter values with a given name. If multiple parameters
     * with the same name are found, all values are concatenated and separated
     * by the given separator.
     *
     * @param name
     *            The parameter name.
     * @param separator
     *            The separator character.
     * @param ignoreCase
     *            Indicates if the name comparison is case sensitive.
     * @return The sequence of values.
     */
    public String getValues(String name, String separator, boolean ignoreCase) {
        String result = null;
        StringBuilder sb = null;

        for (final E param : this) {
            if ((ignoreCase && param.getName().equalsIgnoreCase(name))
                    || param.getName().equals(name)) {
                if (sb == null) {
                    if (result == null) {
                        result = param.getValue();
                    } else {
                        sb = new StringBuilder();
                        sb.append(result).append(separator)
                                .append(param.getValue());
                    }
                } else {
                    sb.append(separator).append(param.getValue());
                }
            }
        }

        if (sb != null) {
            result = sb.toString();
        }

        return result;
    }

    /**
     * Returns an array of all the values associated to the given parameter
     * name.
     *
     * @param name
     *            The parameter name to match.
     * @return The array of values.
     */
    public String[] getValuesArray(String name) {
        return getValuesArray(name, false);
    }

    /**
     * Returns an array of all the values associated to the given parameter
     * name.
     *
     * @param name
     *            The parameter name to match.
     * @param ignoreCase
     *            Indicates if the name comparison is case sensitive.
     * @return The array of values.
     */
    public String[] getValuesArray(String name, boolean ignoreCase) {
        return getValuesArray(name, ignoreCase, null);
    }

    /**
     * Returns an array of all the values associated to the given parameter
     * name.
     *
     * @param name
     *            The parameter name to match.
     * @param ignoreCase
     *            Indicates if the name comparison is case sensitive.
     * @param defaultValue
     *            The default value to return if no matching parameter found or
     *            if the parameter has a null value.
     * @return The array of values.
     */
    public String[] getValuesArray(String name, boolean ignoreCase,
            String defaultValue) {
        String[] result = null;
        List<E> params = subList(name, ignoreCase);

        if ((params.size() == 0) && (defaultValue != null)) {
            result = new String[1];
            result[0] = defaultValue;
        } else {
            result = new String[params.size()];

            for (int i = 0; i < params.size(); i++) {
                result[i] = params.get(i).getValue();
            }
        }

        return result;
    }

    /**
     * Returns an array of all the values associated to the given parameter
     * name.
     *
     * @param name
     *            The parameter name to match.
     * @param defaultValue
     *            The default value to return if no matching parameter found or
     *            if the parameter has a null value.
     * @return The array of values.
     */
    public String[] getValuesArray(String name, String defaultValue) {
        return getValuesArray(name, false, defaultValue);
    }

    /**
     * Returns a map of name, value pairs. The order of the map keys is
     * respected based on the series order. When a name has multiple values,
     * only the first one is put in the map.
     *
     * @return The map of name, value pairs.
     */
    public Map<String, String> getValuesMap() {
        Map<String, String> result = new LinkedHashMap<String, String>();

        for (Parameter param : this) {
            if (!result.containsKey(param.getName())) {
                result.put(param.getName(), param.getValue());
            }
        }

        return result;
    }

    /**
     * Removes all the parameters with a given name.
     *
     * @param name
     *            The parameter name (case sensitive).
     * @return True if the list changed.
     */
    public boolean removeAll(String name) {
        return removeAll(name, false);
    }

    /**
     * Removes all the parameters with a given name.
     *
     * @param name
     *            The parameter name.
     * @param ignoreCase
     *            Indicates if the name comparison is case insensitive.
     * @return True if the list changed.
     */
    public boolean removeAll(String name, boolean ignoreCase) {
        boolean changed = false;
        Parameter param = null;

        for (final Iterator<E> iter = iterator(); iter.hasNext();) {
            param = iter.next();
            if (equals(param.getName(), name, ignoreCase)) {
                iter.remove();
                changed = true;
            }
        }

        return changed;
    }

    /**
     * Removes from this list the first entry whose name equals the specified
     * name ignoring the case.
     *
     * @param name
     *            The name of the entries to be removed (case sensitive).
     * @return false if no entry has been removed, true otherwise.
     */
    public boolean removeFirst(String name) {
        return removeFirst(name, false);
    }

    /**
     * Removes from this list the first entry whose name equals the specified
     * name ignoring the case or not.
     *
     * @param name
     *            The name of the entries to be removed.
     * @param ignoreCase
     *            Indicates if the name comparison is case insensitive.
     * @return false if no entry has been removed, true otherwise.
     */
    public boolean removeFirst(String name, boolean ignoreCase) {
        boolean changed = false;
        Parameter param = null;

        for (final Iterator<E> iter = iterator(); iter.hasNext() && !changed;) {
            param = iter.next();
            if (equals(param.getName(), name, ignoreCase)) {
                iter.remove();
                changed = true;
            }
        }

        return changed;
    }

    /**
     * Replaces the value of the first parameter with the given name and removes
     * all other parameters with the same name. The name matching is case
     * sensitive.
     *
     * @param name
     *            The parameter name.
     * @param value
     *            The value to set.
     * @return The parameter set or added.
     */
    public E set(String name, String value) {
        return set(name, value, false);
    }

    /**
     * Replaces the value of the first parameter with the given name and removes
     * all other parameters with the same name.
     *
     * @param name
     *            The parameter name.
     * @param value
     *            The value to set.
     * @param ignoreCase
     *            Indicates if the name comparison is case insensitive.
     * @return The parameter set or added.
     */
    public E set(String name, String value, boolean ignoreCase) {
        E result = null;
        E param = null;
        boolean found = false;

        for (final Iterator<E> iter = iterator(); iter.hasNext();) {
            param = iter.next();

            if (equals(param.getName(), name, ignoreCase)) {
                if (found) {
                    // Remove other entries with the same name
                    iter.remove();
                } else {
                    // Change the value of the first matching entry
                    found = true;
                    param.setValue(value);
                    result = param;
                }
            }
        }

        if (!found) {
            add(name, value);
        }

        return result;
    }

    /**
     * Returns a view of the portion of this list between the specified
     * fromIndex, inclusive, and toIndex, exclusive.
     *
     * @param fromIndex
     *            The start position.
     * @param toIndex
     *            The end position (exclusive).
     * @return The sub-list.
     */
    @Override
    public Series<E> subList(int fromIndex, int toIndex) {
        return createSeries(getDelegate().subList(fromIndex, toIndex));
    }

    /**
     * Returns a list of all the values associated to the parameter name.
     *
     * @param name
     *            The parameter name (case sensitive).
     * @return The list of values.
     */
    public Series<E> subList(String name) {
        return subList(name, false);
    }

    /**
     * Returns a list of all the values associated to the parameter name.
     *
     * @param name
     *            The parameter name.
     * @param ignoreCase
     *            Indicates if the name comparison is case insensitive.
     * @return The list of values.
     */
    public Series<E> subList(String name, boolean ignoreCase) {
        Series<E> result = createSeries(null);

        for (E param : this) {
            if (equals(param.getName(), name, ignoreCase)) {
                result.add(param);
            }
        }

        return result;
    }

}
TOP

Related Classes of org.restlet.util.Series

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.