/* java.beans.PropertyDescriptor
   Copyright (C) 1998, 2001, 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.beans;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 ** PropertyDescriptor describes information about a JavaBean property,
 ** by which we mean a property that has been exposed via a pair of
 ** get and set methods.  (There may be no get method, which means
 ** the property is write-only, or no set method, which means the
 ** the property is read-only.)<P>
 **
 ** The constraints put on get and set methods are:<P>
 ** <OL>
 ** <LI>A get method must have signature
 **     <CODE>&lt;propertyType&gt; &lt;getMethodName&gt;()</CODE></LI>
 ** <LI>A set method must have signature
 **     <CODE>void &lt;setMethodName&gt;(&lt;propertyType&gt;)</CODE></LI>
 ** <LI>Either method type may throw any exception.</LI>
 ** <LI>Both methods must be public.</LI>
 ** </OL>
 **
 ** @author John Keiser
 ** @author Robert Schuster (thebohemian@gmx.net)
 ** @since 1.1
 ** @status updated to 1.4
 **/
public class PropertyDescriptor extends FeatureDescriptor
{
    Class propertyType;
    Method getMethod;
    Method setMethod;

    Class propertyEditorClass;
    boolean bound;
    boolean constrained;

    PropertyDescriptor(String name)
    {
        setName(name);
    }

    /** Create a new PropertyDescriptor by introspection.
     ** This form of constructor creates the PropertyDescriptor by
     ** looking for a getter method named <CODE>get&lt;name&gt;()</CODE>
     ** (or, optionally, if the property is boolean,
     ** <CODE>is&lt;name&gt;()</CODE>) and
     ** <CODE>set&lt;name&gt;()</CODE> in class
     ** <CODE>&lt;beanClass&gt;</CODE>, where &lt;name&gt; has its
     ** first letter capitalized by the constructor.<P>
     **
     ** Note that using this constructor the given property must be read- <strong>and</strong>
     ** writeable. If the implementation does not both, a read and a write method, an
     ** <code>IntrospectionException</code> is thrown.
     **
     ** <B>Implementation note:</B> If there is both are both isXXX and
     ** getXXX methods, the former is used in preference to the latter.
     ** We do not check that an isXXX method returns a boolean. In both
     ** cases, this matches the behaviour of JDK 1.4<P>
     **
     ** @param name the programmatic name of the property, usually
     **             starting with a lowercase letter (e.g. fooManChu
     **             instead of FooManChu).
     ** @param beanClass the class the get and set methods live in.
     ** @exception IntrospectionException if the methods are not found 
     **            or invalid.
     **/
    public PropertyDescriptor(String name, Class beanClass)
        throws IntrospectionException
    {
        setName(name);
        if (name.length() == 0)
        {
            throw new IntrospectionException("empty property name");
        }
        String caps = Character.toUpperCase(name.charAt(0)) + name.substring(1);
        findMethods(beanClass, "is" + caps, "get" + caps, "set" + caps);

        if (getMethod == null)
        {
            throw new IntrospectionException(
                "Cannot find a is" + caps + " or get" + caps + " method");
        }

        if (setMethod == null)
        {
            throw new IntrospectionException(
                "Cannot find a " + caps + " method");
        }

        // finally check the methods compatibility        
        propertyType = checkMethods(getMethod, setMethod);
    }

    /** Create a new PropertyDescriptor by introspection.
     ** This form of constructor allows you to specify the
     ** names of the get and set methods to search for.<P>
     **
     ** <B>Implementation note:</B> If there is a get method (or
     ** boolean isXXX() method), then the return type of that method
     ** is used to find the set method.  If there is no get method,
     ** then the set method is searched for exhaustively.<P>
     **
     ** <B>Spec note:</B>
     ** If there is no get method and multiple set methods with
     ** the same name and a single parameter (different type of course),
     ** then an IntrospectionException is thrown.  While Sun's spec
     ** does not state this, it can make Bean behavior different on
     ** different systems (since method order is not guaranteed) and as
     ** such, can be treated as a bug in the spec.  I am not aware of
     ** whether Sun's implementation catches this.
     **
     ** @param name the programmatic name of the property, usually
     **             starting with a lowercase letter (e.g. fooManChu
     **             instead of FooManChu).
     ** @param beanClass the class the get and set methods live in.
     ** @param getMethodName the name of the get method or <code>null</code> if the property is write-only.
     ** @param setMethodName the name of the set method or <code>null</code> if the property is read-only.
     ** @exception IntrospectionException if the methods are not found 
     **            or invalid.
     **/
    public PropertyDescriptor(
        String name,
        Class beanClass,
        String getMethodName,
        String setMethodName)
        throws IntrospectionException
    {
        setName(name);
        findMethods(beanClass, getMethodName, null, setMethodName);

        if (getMethod == null && getMethodName != null)
        {
            throw new IntrospectionException(
                "Cannot find a getter method called " + getMethodName);
        }

        if (setMethod == null && setMethodName != null)
        {
            throw new IntrospectionException(
                "Cannot find a setter method called " + setMethodName);
        }

        propertyType = checkMethods(getMethod, setMethod);
    }

    /** Create a new PropertyDescriptor using explicit Methods.
     ** Note that the methods will be checked for conformance to standard
     ** Property method rules, as described above at the top of this class.
     **<br>
     ** It is possible to call this method with both <code>Method</code> arguments
     ** being <code>null</code>. In such a case the property type is <code>null</code>.
     ** 
     ** @param name the programmatic name of the property, usually
     **             starting with a lowercase letter (e.g. fooManChu
     **             instead of FooManChu).
     ** @param readMethod the read method or <code>null</code> if the property is write-only.
     ** @param writeMethod the write method or <code>null</code> if the property is read-only.
     ** @exception IntrospectionException if the methods are not found 
     **            or invalid.
     **/
    public PropertyDescriptor(
        String name,
        Method readMethod,
        Method writeMethod)
        throws IntrospectionException
    {
        setName(name);
        getMethod = readMethod;
        setMethod = writeMethod;
        propertyType = checkMethods(getMethod, setMethod);
    }

    /** Get the property type.
     ** This is the type the get method returns and the set method
     ** takes in.
     **/
    public Class getPropertyType()
    {
        return propertyType;
    }

    /** Get the get method.  Why they call it readMethod here and
     ** get everywhere else is beyond me.
     **/
    public Method getReadMethod()
    {
        return getMethod;
    }

    /** Sets the read method.<br/>
     * The read method is used to retrieve the value of a property. A legal
     * read method must have no arguments. Its return type must not be
     * <code>void</code>. If this methods succeeds the property type
     * is adjusted to the return type of the read method.<br/>
     * <br/>
     * It is legal to set the read and the write method to <code>null</code>
     * or provide method which have been declared in distinct classes.
     * 
     * @param readMethod The new method to be used or <code>null</code>.
     * @throws IntrospectionException If the given method is invalid.
     * @since 1.2
     */
    public void setReadMethod(Method readMethod) throws IntrospectionException
    {
        propertyType = checkMethods(readMethod, setMethod);

        getMethod = readMethod;
    }

    /** Get the set method.  Why they call it writeMethod here and
     ** set everywhere else is beyond me.
     **/
    public Method getWriteMethod()
    {
        return setMethod;
    }

    /** Sets the write method.<br/>
     * The write method is used to set the value of a property. A legal write method
     * must have a single argument which can be assigned to the property. If no
     * read method exists the property type changes to the argument type of the
     * write method.<br/>
     * <br/>
     * It is legal to set the read and the write method to <code>null</code>
     * or provide method which have been declared in distinct classes.
     * 
     * @param writeMethod The new method to be used or <code>null</code>.
     * @throws IntrospectionException If the given method is invalid.
     * @since 1.2
     */
    public void setWriteMethod(Method writeMethod)
        throws IntrospectionException
    {
        propertyType = checkMethods(getMethod, writeMethod);

        setMethod = writeMethod;
    }

    /** Get whether the property is bound.  Defaults to false. **/
    public boolean isBound()
    {
        return bound;
    }

    /** Set whether the property is bound.
     ** As long as the the bean implements addPropertyChangeListener() and
     ** removePropertyChangeListener(), setBound(true) may safely be called.<P>
     ** If these things are not true, then the behavior of the system
     ** will be undefined.<P>
     **
     ** When a property is bound, its set method is required to fire the
     ** <CODE>PropertyChangeListener.propertyChange())</CODE> event
     ** after the value has changed.
     ** @param bound whether the property is bound or not.
     **/
    public void setBound(boolean bound)
    {
        this.bound = bound;
    }

    /** Get whether the property is constrained.  Defaults to false. **/
    public boolean isConstrained()
    {
        return constrained;
    }

    /** Set whether the property is constrained.
     ** If the set method throws <CODE>java.beans.PropertyVetoException</CODE>
     ** (or subclass thereof) and the bean implements addVetoableChangeListener()
     ** and removeVetoableChangeListener(), then setConstrained(true) may safely
     ** be called.  Otherwise, the system behavior is undefined.
     ** <B>Spec note:</B> given those strict parameters, it would be nice if it
     ** got set automatically by detection, but oh well.<P>
     ** When a property is constrained, its set method is required to:<P>
     ** <OL>
     ** <LI>Fire the <CODE>VetoableChangeListener.vetoableChange()</CODE>
     **     event notifying others of the change and allowing them a chance to
     **     say it is a bad thing.</LI>
     ** <LI>If any of the listeners throws a PropertyVetoException, then
     **     it must fire another vetoableChange() event notifying the others
     **     of a reversion to the old value (though, of course, the change
     **     was never made).  Then it rethrows the PropertyVetoException and
     **     exits.</LI>
     ** <LI>If all has gone well to this point, the value may be changed.</LI>
     ** </OL>
     ** @param constrained whether the property is constrained or not.
     **/
    public void setConstrained(boolean constrained)
    {
        this.constrained = constrained;
    }

    /** Get the PropertyEditor class.  Defaults to null. **/
    public Class getPropertyEditorClass()
    {
        return propertyEditorClass;
    }

    /** Set the PropertyEditor class.  If the class does not implement
     ** the PropertyEditor interface, you will likely get an exception
     ** late in the game.
     ** @param propertyEditorClass the PropertyEditor class for this 
     **        class to use.
     **/
    public void setPropertyEditorClass(Class propertyEditorClass)
    {
        this.propertyEditorClass = propertyEditorClass;
    }

    /**
     * Instantiate a property editor using the property editor class.
     * If no property editor class has been set, this will return null.
     * If the editor class has a public constructor which takes a single
     * argument, that will be used and the bean parameter will be passed
     * to it.  Otherwise, a public no-argument constructor will be used,
     * if available.  This method will return null if no constructor is
     * found or if construction fails for any reason.
     * @param bean the argument to the constructor
     * @return a new PropertyEditor, or null on error
     * @since 1.5
     */
    public PropertyEditor createPropertyEditor(Object bean)
    {
      if (propertyEditorClass == null)
        return null;
      Constructor c = findConstructor(propertyEditorClass,
                                      new Class[] { Object.class });
      if (c != null)
        return instantiateClass(c, new Object[] { bean });
      c = findConstructor(propertyEditorClass, null);
      if (c != null)
        return instantiateClass(c, null);
      return null;
    }

    // Helper method to look up a constructor and return null if it is not
    // found.
    private Constructor findConstructor(Class k, Class[] argTypes)
    {
      try
        {
          return k.getConstructor(argTypes);
        }
      catch (NoSuchMethodException _)
        {
          return null;
        }
    }

    // Helper method to instantiate an object but return null on error.
    private PropertyEditor instantiateClass(Constructor c, Object[] args)
    {
      try
        {
          return (PropertyEditor) c.newInstance(args);
        }
      catch (InstantiationException _)
        {
          return null;
        }
      catch (InvocationTargetException _)
        {
          return null;
        }
      catch (IllegalAccessException _)
        {
          return null;
        }
      catch (ClassCastException _)
        {
          return null;
        }
    }

    private void findMethods(
        Class beanClass,
        String getMethodName1,
        String getMethodName2,
        String setMethodName)
        throws IntrospectionException
    {
        try
        {
            // Try the first get method name
            if (getMethodName1 != null)
            {
                try
                {
                    getMethod =
                        beanClass.getMethod(getMethodName1, new Class[0]);
                }
                catch (NoSuchMethodException e)
                {}
            }

            // Fall back to the second get method name
            if (getMethod == null && getMethodName2 != null)
            {
                try
                {
                    getMethod =
                        beanClass.getMethod(getMethodName2, new Class[0]);
                }
                catch (NoSuchMethodException e)
                {}
            }

            // Try the set method name
            if (setMethodName != null)
            {
                if (getMethod != null)
                {
                    // If there is a get method, use its return type to help
                    // select the corresponding set method.
                    Class propertyType = getMethod.getReturnType();
                    if (propertyType == Void.TYPE)
                    {
                        String msg =
                            "The property's read method has return type 'void'";
                        throw new IntrospectionException(msg);
                    }

                    Class[] setArgs = new Class[] { propertyType };
                    try
                    {
                        setMethod = beanClass.getMethod(setMethodName, setArgs);
                    }
                    catch (NoSuchMethodException e)
                    {}
                }
                else if (getMethodName1 == null && getMethodName2 == null)
                {
                    // If this is a write-only property, choose the first set method
                    // with the required name, one parameter and return type 'void'
                    Method[] methods = beanClass.getMethods();
                    for (int i = 0; i < methods.length; i++)
                    {
                        if (methods[i].getName().equals(setMethodName)
                            && methods[i].getParameterTypes().length == 1
                            && methods[i].getReturnType() == Void.TYPE)
                        {
                            setMethod = methods[i];
                            break;
                        }
                    }
                }
            }
        }
        catch (SecurityException e)
        {
            // FIXME -- shouldn't we just allow SecurityException to propagate?
            String msg =
                "SecurityException thrown on attempt to access methods.";
            throw new IntrospectionException(msg);
        }
    }

    /** Checks whether the given <code>Method</code> instances are legal read and
     * write methods. The following requirements must be met:<br/>
     * <ul>
     * <li>the read method must not have an argument</li>
     * <li>the read method must have a non void return type</li>
     * <li>the read method may not exist</li>
     * <li>the write method must have a single argument</li>
     * <li>the property type and the read method's return type must be assignable from the
     * write method's argument type</li>
     * <li>the write method may not exist</li>
     * </ul>
     * While checking the methods a common new property type is calculated. If the method
     * succeeds this property type is returned.<br/>
     * <br/>
     * For compatibility this has to be noted:<br/>
     * The two methods are allowed to be defined in two distinct classes and may both be null.
     * 
     * @param readMethod The new read method to check.
     * @param writeMethod The new write method to check.
     * @return The common property type of the two method.
     * @throws IntrospectionException If any of the above requirements are not met.
     */
    private Class checkMethods(Method readMethod, Method writeMethod)
        throws IntrospectionException
    {
        Class newPropertyType = propertyType;

        // a valid read method has zero arguments and a non-void return type.
        if (readMethod != null)
        {
            if (readMethod.getParameterTypes().length > 0)
            {
                throw new IntrospectionException("read method has unexpected parameters");
            }

            newPropertyType = readMethod.getReturnType();

            if (newPropertyType == Void.TYPE)
            {
                throw new IntrospectionException("read method return type is void");
            }
        }

        // a valid write method has one argument which can be assigned to the property
        if (writeMethod != null)
        {
            if (writeMethod.getParameterTypes().length != 1)
            {
                String msg = "write method does not have exactly one parameter";
                throw new IntrospectionException(msg);
            }

            if (readMethod == null)
            {
                // changes the property type if there is no read method
                newPropertyType = writeMethod.getParameterTypes()[0];
            }
            else
            {
                // checks whether the write method can be assigned to the return type of the read
                // method (if this is not the case, the methods are not compatible)
                // note: newPropertyType may be null if no methods or method names have been
                // delivered in the constructor.
                if (newPropertyType != null
                    && !newPropertyType.isAssignableFrom(
                        writeMethod.getParameterTypes()[0]))
                {
                    // note: newPropertyType is the same as readMethod.getReturnType() at this point
                    throw new IntrospectionException("read and write method are not compatible");
                }

                /* note: the check whether both method are defined in related classes makes sense but is not
                 * done in the JDK. 
                 * I leave this code here in case someone at Sun decides to add that functionality in later versions (rschuster)
                if ((!readMethod
                    .getDeclaringClass()
                    .isAssignableFrom(writeMethod.getDeclaringClass()))
                    && (!writeMethod
                        .getDeclaringClass()
                        .isAssignableFrom(readMethod.getDeclaringClass())))
                {
                    String msg =
                        "set and get methods are not in the same class.";
                    throw new IntrospectionException(msg);
                }
                */

            }
        }

        return newPropertyType;
    }

    /**
     * Return a hash code for this object, conforming to the contract described
     * in {@link Object#hashCode()}.
     * @return the hash code
     * @since 1.5
     */
    public int hashCode()
    {
      return ((propertyType == null ? 0 : propertyType.hashCode())
              | (propertyEditorClass == null ? 0 : propertyEditorClass.hashCode())
              | (bound ? Boolean.TRUE : Boolean.FALSE).hashCode()
              | (constrained ? Boolean.TRUE : Boolean.FALSE).hashCode()
              | (getMethod == null ? 0 : getMethod.hashCode())
              | (setMethod == null ? 0 : setMethod.hashCode()));
    }

    /** Compares this <code>PropertyDescriptor</code> against the
     * given object.
     * Two PropertyDescriptors are equals if
     * <ul>
     * <li>the read methods are equal</li>
     * <li>the write methods are equal</li>
     * <li>the property types are equals</li>
     * <li>the property editor classes are equal</li>
     * <li>the flags (constrained and bound) are equal</li>
     * </ul>
     * @return Whether both objects are equal according to the rules given above.
     * @since 1.4
    */
    public boolean equals(Object o)
    {
        if (o instanceof PropertyDescriptor)
        {
            PropertyDescriptor that = (PropertyDescriptor) o;

            // compares the property types and checks the case where both are null
            boolean samePropertyType =
                (propertyType == null)
                    ? that.propertyType == null
                    : propertyType.equals(that.propertyType);

            // compares the property editor classes and checks the case where both are null
            boolean samePropertyEditorClass =
                (propertyEditorClass == null)
                    ? that.propertyEditorClass == null
                    : propertyEditorClass.equals(that.propertyEditorClass);

            // compares the flags for equality
            boolean sameFlags =
                bound == that.bound && constrained == that.constrained;

            // compares the read methods and checks the case where both are null
            boolean sameReadMethod =
                (getMethod == null)
                    ? that.getMethod == null
                    : getMethod.equals(that.getMethod);

            boolean sameWriteMethod =
                (setMethod == null)
                    ? that.setMethod == null
                    : setMethod.equals(that.setMethod);

            return samePropertyType
                && sameFlags
                && sameReadMethod
                && sameWriteMethod
                && samePropertyEditorClass;
        }
        else
        {
            return false;
        }
        
    }

}
