/* java.beans.IndexedPropertyDescriptor
   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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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
 ** @version 1.1.0, 26 Jul 1998
 **/

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;
	}

	public Method getIndexedWriteMethod() {
		return setIndex;
	}

	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.");
		}
	}
}
