/* IndexedPropertyDescriptor.java --
   Copyright (C) 1998, 2003 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.Array;
import java.lang.reflect.Method;

/**
 * IndexedPropertyDescriptor describes information about a JavaBean
 * indexed property, by which we mean an array-like property that
 * has been exposed via a pair of get and set methods and another
 * pair that allows you to get to the property by an index.<P>
 *
 * An example property would have four methods like this:<P>
 * <CODE>FooBar[] getFoo()</CODE><BR>
 * <CODE>void setFoo(FooBar[])</CODE><BR>
 * <CODE>FooBar getFoo(int)</CODE><BR>
 * <CODE>void setFoo(int,FooBar)</CODE><P>
 *
 * The constraints put on get and set methods are:<P>
 * <OL>
 * <LI>There must be at least a get(int) or a set(int,...) method.
 * Nothing else is required.  <B>Spec note:</B>One nice restriction
 * would be that if there is a get() there must be a get(int), same
 * with set, but that is not in the spec and is fairly harmless.)</LI>
 * <LI>A get array method must have signature
 *     <CODE>&lt;propertyType&gt;[] &lt;getMethodName&gt;()</CODE></LI>
 * <LI>A set array method must have signature
 *     <CODE>void &lt;setMethodName&gt;(&lt;propertyType&gt;[])</CODE></LI>
 * <LI>A get index method must have signature
 *     <CODE>&lt;propertyType&gt; &lt;getMethodName&gt;(int)</CODE></LI>
 * <LI>A set index method must have signature
 *     <CODE>void &lt;setMethodName&gt;(int,&lt;propertyType&gt;)</CODE></LI>
 * <LI>All these methods may throw any exception.</LI>
 * <LI>All these methods must be public.</LI>
 * </OL>
 *
 * @author John Keiser
 * @since JDK1.1
 */
public class IndexedPropertyDescriptor extends PropertyDescriptor
{
  private Class<?> indexedPropertyType;
  private Method setIndex;
  private Method getIndex;

  /**
   * Create a new IndexedPropertyDescriptor by introspection.
   * This form of constructor creates the PropertyDescriptor by
   * looking for getter methods named <CODE>get&lt;name&gt;()</CODE>
   * and setter methods named
   * <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>
   *
   * <B>Implementation note:</B> If there is a get(int) method,
   * then the return type of that method is used to find the
   * remaining methods.  If there is no get method, then the
   * set(int) method is searched for exhaustively and that type
   * is used to find the others.<P>
   *
   * <B>Spec note:</B>
   * If there is no get(int) method and multiple set(int) methods with
   * the same name and the correct parameters (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.
   *
   * @exception IntrospectionException if the methods are not found or
   *            invalid.
   */
  public IndexedPropertyDescriptor(String name, Class<?> beanClass)
    throws IntrospectionException
  {
    super(name);
    String capitalized;
    try
      {
        capitalized = Character.toUpperCase(name.charAt(0))
          + name.substring(1);
      }
    catch(StringIndexOutOfBoundsException e)
      {
        capitalized = "";
      }
    findMethods(beanClass, "get" + capitalized, "set" + capitalized,
                "get" + capitalized, "set" + capitalized);
  }

  /**
   * Create a new IndexedPropertyDescriptor 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(int) method,
   * then the return type of that method is used to find the
   * remaining methods.  If there is no get method, then the
   * set(int) method is searched for exhaustively and that type
   * is used to find the others.<P>
   *
   * <B>Spec note:</B>
   * If there is no get(int) method and multiple set(int) methods with
   * the same name and the correct parameters (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 array method.
   * @param setMethodName the name of the set array method.
   * @param getIndexName the name of the get index method.
   * @param setIndexName the name of the set index method.
   *
   * @exception IntrospectionException if the methods are not found or invalid.
   */
  public IndexedPropertyDescriptor(String name, Class<?> beanClass,
                                   String getMethodName, String setMethodName,
                                   String getIndexName, String setIndexName)
    throws IntrospectionException
  {
    super(name);
    findMethods(beanClass, getMethodName, setMethodName, getIndexName,
                setIndexName);
  }

  /**
   * 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.
   *
   * @param name the programmatic name of the property, usually
   *             starting with a lowercase letter (e.g. fooManChu
   *             instead of FooManChu).
   * @param getMethod the get array method.
   * @param setMethod the set array method.
   * @param getIndex the get index method.
   * @param setIndex the set index method.
   *
   * @exception IntrospectionException if the methods are not found or invalid.
   */
  public IndexedPropertyDescriptor(String name, Method getMethod,
                                   Method setMethod, Method getIndex,
                                   Method setIndex)
    throws IntrospectionException
  {
    super(name);
    if(getMethod != null && getMethod.getParameterTypes().length > 0)
      throw new IntrospectionException("get method has parameters");
    if(getMethod != null && setMethod.getParameterTypes().length != 1)
      throw new IntrospectionException("set method does not have exactly one parameter");
    if(getMethod != null && setMethod != null)
      {
        if(!getMethod.getReturnType().equals(setMethod.getParameterTypes()[0]))
          {
            throw new IntrospectionException("set and get methods do not "
                                             + "share the same type");
          }
        if(!getMethod.getDeclaringClass().isAssignableFrom
           (setMethod.getDeclaringClass())
           && !setMethod.getDeclaringClass().isAssignableFrom
           (getMethod.getDeclaringClass()))
          {
            throw new IntrospectionException("set and get methods are not in "
                                             + "the same class.");
          }
      }

    if (getIndex != null
        && (getIndex.getParameterTypes().length != 1
         || !(getIndex.getParameterTypes()[0]).equals(java.lang.Integer.TYPE)))
      {
        throw new IntrospectionException("get index method has wrong "
                                         + "parameters");
      }
    if (setIndex != null
       && (setIndex.getParameterTypes().length != 2
         || !(setIndex.getParameterTypes()[0]).equals(java.lang.Integer.TYPE)))
      {
        throw new IntrospectionException("set index method has wrong "
                                         + "parameters");
      }
    if (getIndex != null && setIndex != null)
      {
        if(!getIndex.getReturnType().equals(setIndex.getParameterTypes()[1]))
          {
            throw new IntrospectionException("set index methods do not share "
                                             + "the same type");
          }
        if(!getIndex.getDeclaringClass().isAssignableFrom
           (setIndex.getDeclaringClass())
           && !setIndex.getDeclaringClass().isAssignableFrom
           (getIndex.getDeclaringClass()))
          {
            throw new IntrospectionException("get and set index methods are "
                                             + "not in the same class.");
          }
      }

    if (getIndex != null && getMethod != null
        && !getIndex.getDeclaringClass().isAssignableFrom
        (getMethod.getDeclaringClass())
        && !getMethod.getDeclaringClass().isAssignableFrom
        (getIndex.getDeclaringClass()))
      {
        throw new IntrospectionException("methods are not in the same class.");
      }

    if (getIndex != null && getMethod != null
        && !Array.newInstance(getIndex.getReturnType(),0)
        .getClass().equals(getMethod.getReturnType()))
      {
        throw new IntrospectionException("array methods do not match index "
                                         + "methods.");
      }

    this.getMethod = getMethod;
    this.setMethod = setMethod;
    this.getIndex = getIndex;
    this.setIndex = setIndex;
    this.indexedPropertyType = getIndex != null ? getIndex.getReturnType()
                                             : setIndex.getParameterTypes()[1];
    this.propertyType = getMethod != null ? getMethod.getReturnType()
      : (setMethod != null ? setMethod.getParameterTypes()[0]
         : Array.newInstance(this.indexedPropertyType,0).getClass());
  }

  public Class<?> getIndexedPropertyType()
  {
    return indexedPropertyType;
  }

  public Method getIndexedReadMethod()
  {
    return getIndex;
  }

  /**
   * Sets the method that is used to read an indexed property.
   *
   * @param m the method to set
   */
  public void setIndexedReadMethod(Method m) throws IntrospectionException
  {
    getIndex = m;
  }

  public Method getIndexedWriteMethod()
  {
    return setIndex;
  }

  /**
   * Sets the method that is used to write an indexed property.
   *
   * @param m the method to set
   */
  public void setIndexedWriteMethod(Method m) throws IntrospectionException
  {
    setIndex = m;
  }

  private void findMethods(Class beanClass, String getMethodName,
                           String setMethodName, String getIndexName,
                           String setIndexName)
    throws IntrospectionException
  {
    try
      {
        if(getIndexName != null)
          {
            try
              {
                Class[] getArgs = new Class[1];
                getArgs[0] = java.lang.Integer.TYPE;
                getIndex = beanClass.getMethod(getIndexName,getArgs);
                indexedPropertyType = getIndex.getReturnType();
              }
            catch(NoSuchMethodException E)
              {
              }
          }
        if(getIndex != null)
          {
            if(setIndexName != null)
              {
                try
                  {
                    Class[] setArgs = new Class[2];
                    setArgs[0] = java.lang.Integer.TYPE;
                    setArgs[1] = indexedPropertyType;
                    setIndex = beanClass.getMethod(setIndexName,setArgs);
                    if(!setIndex.getReturnType().equals(java.lang.Void.TYPE))
                      {
                        throw new IntrospectionException(setIndexName
                                                + " has non-void return type");
                      }
                  }
                catch(NoSuchMethodException E)
                  {
                  }
              }
          }
        else if(setIndexName != null)
          {
            Method[] m = beanClass.getMethods();
            for(int i=0;i<m.length;i++)
              {
                Method current = m[i];
                if(current.getName().equals(setIndexName)
                   && current.getParameterTypes().length == 2
                   && (current.getParameterTypes()[0])
                   .equals(java.lang.Integer.TYPE)
                   && current.getReturnType().equals(java.lang.Void.TYPE))
                  {
                    if(setIndex != null)
                      {
                        throw new IntrospectionException("Multiple, different "
                                     + "set methods found that fit the bill!");
                      }
                    else
                      {
                        setIndex = current;
                        indexedPropertyType = current.getParameterTypes()[1];
                      }
                  }
              }
            if(setIndex == null)
              {
                throw new IntrospectionException("Cannot find get or set "
                                                 + "methods.");
              }
          }
        else
          {
           throw new IntrospectionException("Cannot find get or set methods.");
          }

        Class arrayType = Array.newInstance(indexedPropertyType,0).getClass();

        Class[] setArgs = new Class[1];
        setArgs[0] = arrayType;
        try
          {
            setMethod = beanClass.getMethod(setMethodName,setArgs);
            if (!setMethod.getReturnType().equals(java.lang.Void.TYPE))
              {
                setMethod = null;
              }
          }
        catch(NoSuchMethodException E)
          {
          }

        Class[] getArgs = new Class[0];
        try
          {
            getMethod = beanClass.getMethod(getMethodName,getArgs);
            if (!getMethod.getReturnType().equals(arrayType))
              {
                getMethod = null;
              }
          }
        catch(NoSuchMethodException E)
          {
          }
      }
    catch(SecurityException E)
      {
        throw new IntrospectionException("SecurityException while trying to "
                                         + "find methods.");
      }
  }
}
