/*
 * 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.
 */
package javax.faces.component;

import javax.el.ValueExpression;
import javax.faces.FacesException;
import javax.faces.context.FacesContext;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.*;

/**
 * A custom implementation of the Map interface, where get and put calls
 * try to access getter/setter methods of an associated UIComponent before
 * falling back to accessing a real Map object.
 * <p/>
 * Some of the behaviours of this class don't really comply with the
 * definitions of the Map class; for example the key parameter to all
 * methods is required to be of type String only, and after clear(),
 * calls to get can return non-null values. However the JSF spec
 * requires that this class behave in the way implemented below. See
 * UIComponent.getAttributes for more details.
 * <p/>
 * The term "property" is used here to refer to real javabean properties
 * on the underlying UIComponent, while "attribute" refers to an entry
 * in the associated Map.
 *
 * @author Manfred Geiler (latest modification by $Author$)
 * @version $Revision$ $Date$
 */
class _ComponentAttributesMap
        implements Map, Serializable
{
    private static final long serialVersionUID = -9106832179394257866L;

    private static final Object[] EMPTY_ARGS = new Object[0];

    // The component that is read/written via this map.
    private UIComponent _component;

    // We delegate instead of derive from HashMap, so that we can later
    // optimize Serialization
    private Map<Object, Object> _attributes = null;

    // A cached hashmap of propertyName => PropertyDescriptor object for all
    // the javabean properties of the associated component. This is built by
    // introspection on the associated UIComponent. Don't serialize this as
    // it can always be recreated when needed.
    private transient Map<String, PropertyDescriptor> _propertyDescriptorMap = null;

    // Cache for component property descriptors
    private static Map<Class, Map<String, PropertyDescriptor>> _propertyDescriptorCache = new WeakHashMap<Class, Map<String, PropertyDescriptor>>();

    /**
     * Create a map backed by the specified component.
     * <p/>
     * This method is expected to be called when a component is first created.
     */
    _ComponentAttributesMap(UIComponent component)
    {
        _component = component;
        _attributes = new HashMap<Object, Object>();
    }

    /**
     * Create a map backed by the specified component. Attributes already
     * associated with the component are provided in the specified Map
     * class. A reference to the provided map is kept; this object's contents
     * are updated during put calls on this instance.
     * <p/>
     * This method is expected to be called during the "restore view" phase.
     */
    _ComponentAttributesMap(UIComponent component, Map<Object, Object> attributes)
    {
        _component = component;
        _attributes = new HashMap(attributes);
    }

    /**
     * Return the number of <i>attributes</i> in this map. Properties of the
     * underlying UIComponent are not counted.
     * <p/>
     * Note that because the get method can read properties of the
     * UIComponent and evaluate value-bindings, it is possible to have
     * size return zero while calls to the get method return non-null
     * values.
     */
    public int size()
    {
        return _attributes.size();
    }

    /**
     * Clear all the <i>attributes</i> in this map. Properties of the
     * underlying UIComponent are not modified.
     * <p/>
     * Note that because the get method can read properties of the
     * UIComponent and evaluate value-bindings, it is possible to have
     * calls to the get method return non-null values immediately after
     * a call to clear.
     */
    public void clear()
    {
        _attributes.clear();
    }

    /**
     * Return true if there are no <i>attributes</i> in this map. Properties
     * of the underlying UIComponent are not counted.
     * <p/>
     * Note that because the get method can read properties of the
     * UIComponent and evaluate value-bindings, it is possible to have
     * isEmpty return true, while calls to the get method return non-null
     * values.
     */
    public boolean isEmpty()
    {
        return _attributes.isEmpty();
    }

    /**
     * Return true if there is an <i>attribute</i> with the specified name,
     * but false if there is a javabean <i>property</i> of that name on the
     * associated UIComponent.
     * <p/>
     * Note that it should be impossible for the attributes map to contain
     * an entry with the same name as a javabean property on the associated
     * UIComponent.
     *
     * @param key <i>must</i> be a String. Anything else will cause a
     *            ClassCastException to be thrown.
     */
    public boolean containsKey(Object key)
    {
        checkKey(key);

        return getPropertyDescriptor((String) key) == null ? _attributes.containsKey(key) : false;
    }

    /**
     * Returns true if there is an <i>attribute</i> with the specified
     * value. Properties of the underlying UIComponent aren't examined,
     * nor value-bindings.
     *
     * @param value null is allowed
     */
    public boolean containsValue(Object value)
    {
        return _attributes.containsValue(value);
    }

    /**
     * Return a collection of the values of all <i>attributes</i>. Property
     * values are not included, nor value-bindings.
     */
    public Collection<Object> values()
    {
        return _attributes.values();
    }

    /**
     * Call put(key, value) for each entry in the provided map.
     */
    public void putAll(Map t)
    {
        for (Iterator it = t.entrySet().iterator(); it.hasNext();)
        {
            Map.Entry entry = (Entry) it.next();
            put(entry.getKey(), entry.getValue());
        }
    }

    /**
     * Return a set of all <i>attributes</i>. Properties of the underlying
     * UIComponent are not included, nor value-bindings.
     */
    public Set entrySet()
    {
        return _attributes.entrySet();
    }

    /**
     * Return a set of the keys for all <i>attributes</i>. Properties of the
     * underlying UIComponent are not included, nor value-bindings.
     */
    public Set<Object> keySet()
    {
        return _attributes.keySet();
    }

    /**
     * In order: get the value of a <i>property</i> of the underlying
     * UIComponent, read an <i>attribute</i> from this map, or evaluate
     * the component's value-binding of the specified name.
     *
     * @param key must be a String. Any other type will cause ClassCastException.
     */
    public Object get(Object key)
    {
        checkKey(key);

        // is there a javabean property to read?
        PropertyDescriptor propertyDescriptor
                = getPropertyDescriptor((String) key);
        if (propertyDescriptor != null)
        {
            return getComponentProperty(propertyDescriptor);
        }

        // is there a literal value to read?
        Object mapValue = _attributes.get(key);
        if (mapValue != null)
        {
            return mapValue;
        }

        // is there a value-binding to read?
        ValueExpression ve = _component.getValueExpression((String) key);
        if (ve != null)
        {
            return ve.getValue(_component.getFacesContext().getELContext());
        }

        // no value found
        return null;
    }

    /**
     * Remove the attribute with the specified name. An attempt to
     * remove an entry whose name is that of a <i>property</i> on
     * the underlying UIComponent will cause an IllegalArgumentException.
     * Value-bindings for the underlying component are ignored.
     *
     * @param key must be a String. Any other type will cause ClassCastException.
     */
    public Object remove(Object key)
    {
        checkKey(key);
        PropertyDescriptor propertyDescriptor = getPropertyDescriptor((String) key);
        if (propertyDescriptor != null)
        {
            throw new IllegalArgumentException("Cannot remove component property attribute");
        }
        return _attributes.remove(key);
    }

    /**
     * Store the provided value as a <i>property</i> on the underlying
     * UIComponent, or as an <i>attribute</i> in a Map if no such property
     * exists. Value-bindings associated with the component are ignored; to
     * write to a value-binding, the value-binding must be explicitly
     * retrieved from the component and evaluated.
     * <p/>
     * Note that this method is different from the get method, which
     * does read from a value-binding if one exists. When a value-binding
     * exists for a non-property, putting a value here essentially "masks"
     * the value-binding until that attribute is removed.
     * <p/>
     * The put method is expected to return the previous value of the
     * property/attribute (if any). Because UIComponent property getter
     * methods typically try to evaluate any value-binding expression of
     * the same name this can cause an EL expression to be evaluated,
     * thus invoking a getter method on the user's model. This is fine
     * when the returned value will be used; Unfortunately this is quite
     * pointless when initialising a freshly created component with whatever
     * attributes were specified in the view definition (eg JSP tag
     * attributes). Because the UIComponent.getAttributes method
     * only returns a Map class and this class must be package-private,
     * there is no way of exposing a "putNoReturn" type method.
     *
     * @param key   String, null is not allowed
     * @param value null is allowed
     */
    public Object put(Object key, Object value)
    {
        checkKey(key);

        PropertyDescriptor propertyDescriptor = getPropertyDescriptor((String) key);
        if (propertyDescriptor == null)
        {
            if (value == null)
            {
                throw new NullPointerException("value is null for a not available property: " + key);
            }
        }
        else
        {
            if (propertyDescriptor.getReadMethod() != null)
            {
                Object oldValue = getComponentProperty(propertyDescriptor);
                setComponentProperty(propertyDescriptor, value);
                return oldValue;
            }
            setComponentProperty(propertyDescriptor, value);
            return null;
        }
        return _attributes.put(key, value);
    }

    /**
     * Retrieve info about getter/setter methods for the javabean property
     * of the specified name on the underlying UIComponent object.
     * <p/>
     * This method optimises access to javabean properties of the underlying
     * UIComponent by maintaining a cache of ProperyDescriptor objects for
     * that class.
     * <p/>
     * TODO: Consider making the cache shared between component instances;
     * currently 100 UIInputText components means performing introspection
     * on the UIInputText component 100 times.
     */
    private PropertyDescriptor getPropertyDescriptor(String key)
    {
        if (_propertyDescriptorMap == null)
        {
            // Try to get descriptor map from cache
            _propertyDescriptorMap = _propertyDescriptorCache.get(_component.getClass());
            // Cache miss: create descriptor map and put it in cache
            if (_propertyDescriptorMap == null)
            {
                // Create descriptor map...
                BeanInfo beanInfo;
                try
                {
                    beanInfo = Introspector.getBeanInfo(_component.getClass());
                }
                catch (IntrospectionException e)
                {
                    throw new FacesException(e);
                }
                PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
                _propertyDescriptorMap = new HashMap<String, PropertyDescriptor>();
                for (int i = 0; i < propertyDescriptors.length; i++)
                {
                    PropertyDescriptor propertyDescriptor = propertyDescriptors[i];
                    if (propertyDescriptor.getReadMethod() != null)
                    {
                        _propertyDescriptorMap.put(propertyDescriptor.getName(),
                                propertyDescriptor);
                    }
                }
                // ... and put it in cache
                synchronized(_propertyDescriptorCache)
                {
                    // Use a synchronized block to ensure proper operation on concurrent use cases.
                    // This is a racy single check, because initialization over the same class could happen
                    // multiple times, but the same result is always calculated. The synchronized block 
                    // just ensure thread-safety, because only one thread will modify the cache map
                    // at the same time.
                    _propertyDescriptorCache.put(_component.getClass(), _propertyDescriptorMap);
                }
            }
        }
        return _propertyDescriptorMap.get(key);
    }


    /**
     * Execute the getter method of the specified property on the underlying
     * component.
     *
     * @param propertyDescriptor specifies which property to read.
     * @return the value returned by the getter method.
     * @throws IllegalArgumentException if the property is not readable.
     * @throws FacesException           if any other problem occurs while invoking
     *                                  the getter method.
     */
    private Object getComponentProperty(PropertyDescriptor propertyDescriptor)
    {
        Method readMethod = propertyDescriptor.getReadMethod();
        if (readMethod == null)
        {
            throw new IllegalArgumentException("Component property " + propertyDescriptor.getName() + " is not readable");
        }
        try
        {
            return readMethod.invoke(_component, EMPTY_ARGS);
        }
        catch (Exception e)
        {
            FacesContext facesContext = _component.getFacesContext();
            throw new FacesException("Could not get property " + propertyDescriptor.getName() + " of component " + _component.getClientId(facesContext), e);
        }
    }

    /**
     * Execute the setter method of the specified property on the underlying
     * component.
     *
     * @param propertyDescriptor specifies which property to write.
     * @throws IllegalArgumentException if the property is not writable.
     * @throws FacesException           if any other problem occurs while invoking
     *                                  the getter method.
     */
    private void setComponentProperty(PropertyDescriptor propertyDescriptor, Object value)
    {
        Method writeMethod = propertyDescriptor.getWriteMethod();
        if (writeMethod == null)
        {
            throw new IllegalArgumentException("Component property " + propertyDescriptor.getName() + " is not writable");
        }
        try
        {
            writeMethod.invoke(_component, new Object[]{value});
        }
        catch (Exception e)
        {
            FacesContext facesContext = _component.getFacesContext();
            throw new FacesException("Could not set property " + propertyDescriptor.getName() +
                    " of component " + _component.getClientId(facesContext) + " to value : " + value + " with type : " +
                    (value == null ? "null" : value.getClass().getName()), e);
        }
    }

    private void checkKey(Object key)
    {
        if (key == null)
        {
            throw new NullPointerException("key");
        }
        if (!(key instanceof String))
        {
            throw new ClassCastException("key is not a String");
        }
    }

    /**
     * Return the map containing the attributes.
     * <p/>
     * This method is package-scope so that the UIComponentBase class can access it
     * directly when serializing the component.
     */
    Map<Object, Object> getUnderlyingMap()
    {
        return _attributes;
    }

    /**
     * TODO: Document why this method is necessary, and why it doesn't try to
     * compare the _component field.
     */
    public boolean equals(Object obj)
    {
        return _attributes.equals(obj);
    }

    public int hashCode()
    {
        return _attributes.hashCode();
    }
}
