All Downloads are FREE. Search and download functionalities are using the official Maven repository.

flex.messaging.config.ConfigMap Maven / Gradle / Ivy

Go to download

BlazeDS is the server-based Java remoting and web messaging technology that enables developers to easily connect to back-end distributed data and push data in real-time to Adobe Flex and Adobe AIR applications for more responsive rich Internet application (RIA) experiences.

There is a newer version: 3.2.0.3978
Show newest version
/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  [2002] - [2007] Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated
 * and its suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 */
package flex.messaging.config;

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

/**
 * The ConfigMap class is a helper implementation of Map that makes it easier
 * to handle properties that can appear one or more times. If a property is set
 * more than once, it is converted to a List and added as another property
 * rather than replacing the existing property. It also provides utility APIs
 * for getting properties from the Map, cast to a certain type and allows a
 * default to be specified in the event that the property is missing.
 *
 * @author Peter Farland
 */
public class ConfigMap extends LinkedHashMap
{
    /**
     * This number was generated using the 'serialver' command line tool.
     * This number should remain consistent with the version used by
     * ColdFusion to communicate with the message broker over RMI.
     */
    private static final long serialVersionUID = 8913604659150919550L;

    private static final int UNEXPECTED_MULTIPLE_VALUES = 10169;
    private HashSet accessedKeys = new HashSet();

    /**
     * Constructs an empty ConfigMap with the default initial
     * capacity of 10.
     */
    public ConfigMap()
    {
        super();
    }

    /**
     * Constructs a new ConfigMap with the initial
     * capacity specified.
     * 
     * @param  initialCapacity the initial capacity.
     */
    public ConfigMap(int initialCapacity)
    {
        super(initialCapacity);
    }

    /**
     * Constructs a new ConfigMap and copies the values
     * from the supplied map to this map.
     * 
     * @param m a ConfigMap whose properties are to be added to
     * this ConfigMap.
     */
    public ConfigMap(ConfigMap m)
    {
        this();
        addProperties(m);
    }

    /**
     * Adds all properties from a map to this map.
     * 
     * @param p a ConfigMap whose properties are to be added to
     * this ConfigMap.
     */
    public void addProperties(ConfigMap p)
    {
        Iterator it = p.entrySet().iterator();
        while (it.hasNext())
        {
            Map.Entry entry = (Map.Entry) it.next();
            Object key = entry.getKey();
            Object value = entry.getValue();
            if (value instanceof ValueList)
            {
                addProperties(key, (ValueList) value);
            }
            else
            {
                addPropertyLogic(key, value);
            }
        }
    }

    private void addProperties(Object key, ValueList values)
    {
        ValueList list = getValueList(key);
        if (list == null)
        {
            put(key, values.clone());
        }
        else
        {
            list.addAll(values);
        }
    }

    private void addPropertyLogic(Object key, Object value)
    {
        ValueList list = getValueList(key);
        if (list == null)
        {
            put(key, value);
        }
        else
        {
            list.add(value);
        }
    }

    private static class ValueList extends ArrayList
    {
        static final long serialVersionUID = -5637755312744414675L;
    }

    private ValueList getValueList(Object key)
    {
        ValueList list;
        Object old = super.get(key);
        if (old instanceof ValueList)
        {
            list = (ValueList) old;
        }
        else if (old != null)
        {
            list = new ValueList();
            list.add(old);
            put(key, list);
        }
        else
        {
            list = null;
        }
        return list;
    }

    /**
     * Adds a String value to this map for the given property
     * name.
     * 
     * @param name  the property name
     * @param value the property value
     */
    public void addProperty(String name, String value)
    {
        addPropertyLogic(name, value);
    }

    /**
     * Adds a ConfigMap value to this map for the given property
     * name.
     * 
     * @param name  the property name
     * @param value the property value
     */
    public void addProperty(String name, ConfigMap value)
    {
        addPropertyLogic(name, value);
    }

    /**
     * Gets the set of property names contained in this map.
     * 
     * @return a Set of property name Strings.
     */
    public Set propertyNames()
    {
        return keySet();
    }

    /**
     * Sets a property name as allowed without needing to access the property
     * value. This marks a property as allowed for validation purposes.
     * 
     * @param name  the property name to allow
     */
    public void allowProperty(String name)
    {
        accessedKeys.add(name);
    }

    /**
     * Gets the value for the given property name. Also records that this
     * property was accessed.
     * 
     * @param name  the property name
     * @return the value for the property, or null if property does not exist
     * in this map.
     */
    public Object get(Object name)
    {
        accessedKeys.add(name);
        return super.get(name);
    }

    private Object getSinglePropertyOrFail(Object name)
    {
        Object result = get(name);
        if (result instanceof ValueList)
        {
            ConfigurationException exception = new ConfigurationException();
            exception.setMessage
                (UNEXPECTED_MULTIPLE_VALUES, new Object[] {name});
            throw exception;
        }
        return result;
    }

    /**
     * Gets the property with the specified name as a string if possible.
     * 
     * @throws ConfigurationException if there are multiple values for the
     * property name.
     */
    public String getProperty(String name)
    {
        return getPropertyAsString(name, null);
    }

    /**
     * Gets the property with the specified name as a ConfigMap if possible,
     * or returns the default value if the property is undefined.
     * 
     * @throws ConfigurationException if there are multiple values for the
     * property name.
     */
    public ConfigMap getPropertyAsMap(String name, ConfigMap defaultValue)
    {
        Object prop = getSinglePropertyOrFail(name);
        if (prop instanceof ConfigMap)
        {
            return (ConfigMap)prop;
        }
        return defaultValue;
    }

    /**
     * Gets the property with the specified name as a String if possible,
     * or returns the default value if the property is undefined.
     * 
     * @throws ConfigurationException if there are multiple values for the
     * property name.
     */
    public String getPropertyAsString(String name, String defaultValue)
    {
        Object prop = getSinglePropertyOrFail(name);
        if (prop instanceof String)
        {
            return (String)prop;
        }
        return defaultValue;
    }

    /**
     * Gets a property (or set of properties) as a List. If only one
     * property exists it is added as the only entry to a new List.
     * 
     * @param name  the property name
     * @param defaultValue  the value to return if the property is not found
     * @return the value for the property as a List if it exists in this map, 
     * otherwise the defaultValue is returned.
     */
    public List getPropertyAsList(String name, List defaultValue)
    {
        Object prop = get(name);
        if (prop != null)
        {
            if (prop instanceof List)
            {
                return (List) prop;
            }
            else
            {
                List list = new ArrayList();
                list.add(prop);
                return list;
            }
        }
        return defaultValue;
    }

    /**
     * Gets the property with the specified name as a boolean if possible,
     * or returns the default value if the property is undefined.
     * 
     * @throws ConfigurationException if there are multiple values for the
     * property name.
     */
    public boolean getPropertyAsBoolean(String name, boolean defaultValue)
    {
        Object prop = getSinglePropertyOrFail(name);
        if (prop instanceof String)
        {
            return Boolean.valueOf((String)prop).booleanValue();
        }
        return defaultValue;
    }

    /**
     * Gets the property with the specified name as an int if possible,
     * or returns the default value if the property is undefined.
     * 
     * @throws ConfigurationException if there are multiple values for the
     * property name.
     */
    public int getPropertyAsInt(String name, int defaultValue)
    {
        Object prop = getSinglePropertyOrFail(name);
        if (prop instanceof String)
        {
            try
            {
                return Integer.parseInt((String)prop);
            }
            catch (NumberFormatException ex)
            {
            }
        }
        return defaultValue;
    }

    /**
     * Gets the property with the specified name as a long if possible,
     * or returns the default value if the property is undefined.
     * 
     * @throws ConfigurationException if there are multiple values for the
     * property name.
     */
    public long getPropertyAsLong(String name, long defaultValue)
    {
        Object prop = getSinglePropertyOrFail(name);
        if (prop instanceof String)
        {
            try
            {
                return Long.parseLong((String)prop);
            }
            catch (NumberFormatException ex)
            {
            }
        }
        return defaultValue;
    }

    /**
     * Returns a list of qualified property names that have not been accessed
     * by one of the get*() methods.
     */
    public List findAllUnusedProperties()
    {
        List result = new ArrayList();
        findUnusedProperties("", true, result);
        return result;
    }

    /**
     * Gathers a collection of properties that exist in the map but have not
     * been explicitly accessed nor marked as allowed. This list is helpful
     * in validating a set of properties as one can detect those that are
     * unknown or unexpected. 
     * 
     * @param parentPath Used to track the depth of property in a potential
     * hierarchy of ConfigMaps. 
     * @param recurse Whether sub maps should be recursively searched.
     * @param result the collection of unused properties in this map. 
     */
    public void findUnusedProperties
        (String parentPath, boolean recurse, Collection result)
    {
        Iterator itr = entrySet().iterator();
        while (itr.hasNext())
        {
            Map.Entry entry = (Map.Entry) itr.next();
            Object key = entry.getKey();
            String currentPath = parentPath + '/' + String.valueOf(key);
            if (!accessedKeys.contains(key))
            {
                result.add(currentPath);
            }
            else if (recurse)
            {
                Object value = entry.getValue();
                List values = value instanceof List ?
                              (List) value : Collections.singletonList(value);
                for (int i = 0; i < values.size(); i++)
                {
                    Object child = values.get(i);
                    if (child instanceof ConfigMap)
                    {
                        ((ConfigMap) child).findUnusedProperties
                            (currentPath, recurse, result);
                    }
                }
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy