/************************************************************************** * Copyright (c) 2003 by Acunia N.V. All rights reserved. * * * * This software is copyrighted by and is the sole property of Acunia N.V. * * and its licensors, if any. All rights, title, ownership, or other * * interests in the software remain the property of Acunia N.V. and its * * licensors, if any. * * * * This software may only be used in accordance with the corresponding * * license agreement. Any unauthorized use, duplication, transmission, * * distribution or disclosure of this software is expressly forbidden. * * * * This Copyright notice may not be removed or modified without prior * * written consent of Acunia N.V. * * * * Acunia N.V. reserves the right to modify this software without notice. * * * * Acunia N.V. * * Philips-site 5, box 3 info@acunia.com * * 3001 Leuven http://www.acunia.com * * Belgium - EUROPE * **************************************************************************/ package java.beans; import java.lang.reflect.Method; /** * Describes a property with a getter and setter method */ public class PropertyDescriptor extends FeatureDescriptor { protected Class beanClass = null; protected Method getter = null; protected Method setter = null; protected boolean bound; protected boolean constrained; protected Class propertyEditorClass; /** * Create a PropertyDescriptor with the specified name for the specified class */ public PropertyDescriptor(String propertyName, Class beanClass) throws IntrospectionException { super(); name = propertyName; this.beanClass = beanClass; String capName = propertyName; if (propertyName == null || propertyName.length() == 0) throw new IntrospectionException("Invalid property name"); if (Character.isLowerCase(capName.charAt(0))) capName = Character.toUpperCase(capName.charAt(0)) + capName.substring(1); setMethods("get"+capName, "is"+capName, "set"+capName); bound = false; constrained = false; propertyEditorClass = null; } /** * Create a PropertyDescriptor with the specified name with the specified getter and setter methods * on the specified class */ public PropertyDescriptor(String propertyName, Class beanClass, String getterName, String setterName) throws IntrospectionException { super(); name = propertyName; this.beanClass = beanClass; setMethods(getterName, null, setterName); bound = false; constrained = false; propertyEditorClass = null; } /** * Create a PropertyDescriptor with the specified name, class and methods */ public PropertyDescriptor(String propertyName, Method getter, Method setter) throws IntrospectionException { super(); name = propertyName; this.beanClass = null; this.getter = getter; this.setter = setter; bound = false; constrained = false; propertyEditorClass = null; } /** * Tries to find the specified methods in the beanClass */ private void setMethods(String getterName, String isName, String setterName) throws IntrospectionException { try { // try the getter method if not null if (getterName !=null) { try { getter = beanClass.getMethod(getterName, null); } catch (NoSuchMethodException e) { // coould fail if we have an is method instead of a get // but if no isName specified then throw exception if (isName == null) throw new IntrospectionException("No getter method"); } // try the is method // for boolean properties this is preferred even if their is a get if (isName != null) { try { getter = beanClass.getMethod(isName, null); } catch (NoSuchMethodException e) { // will fail for non boolean properties // but throw exception if there is not a get if (getter == null) throw new IntrospectionException("No getter method"); } } } // find the setter method if not null if (setterName != null) { // if a getter exists, use its return type to find the setter // otherwise, search through all methods for the setter if (getter != null) { Class retType = getter.getReturnType(); Class[] args = {retType}; setter = beanClass.getMethod(setterName, args); } else { Method[] methods = beanClass.getMethods(); boolean found = false; for (int i=0; i < methods.length && !found; i++) { if (methods[i].getName().equals(setterName)) { setter = methods[i]; found = true; } } // if not found then throw exception if (!found) throw new IntrospectionException("No setter method"); } } } catch(NoSuchMethodException e) { throw new IntrospectionException(e.getMessage()); } } /** * Returns the property type ie. the return type of the getter */ public Class getPropertyType() { if (getter != null) return getter.getReturnType(); else return null; } /** * Return the getter method */ public Method getReadMethod() { return getter; } /** * Set the getter method */ public void setReadMethod(Method getter) throws IntrospectionException { this.getter = getter; } /** * Return the setter method */ public Method getWriteMethod() { return setter; } /** * Set the setter method */ public void setWriteMethod(Method setter) throws IntrospectionException { this.setter = setter; } /** * Returns whether the property is bound */ public boolean isBound() { return bound; } /** * Sets whether the property is bound */ public void setBound(boolean bound) { this.bound = bound; } /** * Returns whether the property is constrained */ public boolean isConstrained() { return constrained; } /** * Sets whether the property is constrained */ public void setConstrained(boolean constrained) { this.constrained = constrained; } /** * Sets the property editor class */ public void setPropertyEditorClass(Class propertyEditorClass) { this.propertyEditorClass = propertyEditorClass; } /** * Gets the property editor class */ public Class getPropertyEditorClass() { return propertyEditorClass; } /** * Returns whether two PropertyDescriptors are equal */ public boolean equals(Object obj) { PropertyDescriptor pd = (PropertyDescriptor) obj; // two property descriptors are equal if the read, write, // property types, property editor and flags are equivalent if (!this.getReadMethod().equals(pd.getReadMethod())) return false; if (!this.getWriteMethod().equals(pd.getWriteMethod())) return false; if (!this.getPropertyType().equals(pd.getPropertyType())) return false; if (!this.getPropertyEditorClass().equals(pd.getPropertyEditorClass())) return false; if (this.isConstrained() != pd.isConstrained()) return false; if (this.isBound() != pd.isBound()) return false; // all tests pass so return true return true; } }