| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
package java.beans;  | 
 | 
 | 
 | 
import java.lang.ref.Reference;  | 
 | 
import java.lang.reflect.Method;  | 
 | 
import java.lang.reflect.Constructor;  | 
 | 
import sun.reflect.misc.ReflectUtil;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
public class PropertyDescriptor extends FeatureDescriptor { | 
 | 
 | 
 | 
    private Reference<? extends Class<?>> propertyTypeRef;  | 
 | 
    private final MethodRef readMethodRef = new MethodRef();  | 
 | 
    private final MethodRef writeMethodRef = new MethodRef();  | 
 | 
    private Reference<? extends Class<?>> propertyEditorClassRef;  | 
 | 
 | 
 | 
    private boolean bound;  | 
 | 
    private boolean constrained;  | 
 | 
 | 
 | 
    // The base name of the method name which will be prefixed with the  | 
 | 
      | 
 | 
    private String baseName;  | 
 | 
 | 
 | 
    private String writeMethodName;  | 
 | 
    private String readMethodName;  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public PropertyDescriptor(String propertyName, Class<?> beanClass)  | 
 | 
                throws IntrospectionException { | 
 | 
        this(propertyName, beanClass,  | 
 | 
                Introspector.IS_PREFIX + NameGenerator.capitalize(propertyName),  | 
 | 
                Introspector.SET_PREFIX + NameGenerator.capitalize(propertyName));  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public PropertyDescriptor(String propertyName, Class<?> beanClass,  | 
 | 
                String readMethodName, String writeMethodName)  | 
 | 
                throws IntrospectionException { | 
 | 
        if (beanClass == null) { | 
 | 
            throw new IntrospectionException("Target Bean class is null"); | 
 | 
        }  | 
 | 
        if (propertyName == null || propertyName.length() == 0) { | 
 | 
            throw new IntrospectionException("bad property name"); | 
 | 
        }  | 
 | 
        if ("".equals(readMethodName) || "".equals(writeMethodName)) { | 
 | 
            throw new IntrospectionException("read or write method name should not be the empty string"); | 
 | 
        }  | 
 | 
        setName(propertyName);  | 
 | 
        setClass0(beanClass);  | 
 | 
 | 
 | 
        this.readMethodName = readMethodName;  | 
 | 
        if (readMethodName != null && getReadMethod() == null) { | 
 | 
            throw new IntrospectionException("Method not found: " + readMethodName); | 
 | 
        }  | 
 | 
        this.writeMethodName = writeMethodName;  | 
 | 
        if (writeMethodName != null && getWriteMethod() == null) { | 
 | 
            throw new IntrospectionException("Method not found: " + writeMethodName); | 
 | 
        }  | 
 | 
        // If this class or one of its base classes allow PropertyChangeListener,  | 
 | 
        // then we assume that any properties we discover are "bound".  | 
 | 
          | 
 | 
        Class[] args = { PropertyChangeListener.class }; | 
 | 
        this.bound = null != Introspector.findMethod(beanClass, "addPropertyChangeListener", args.length, args);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public PropertyDescriptor(String propertyName, Method readMethod, Method writeMethod)  | 
 | 
                throws IntrospectionException { | 
 | 
        if (propertyName == null || propertyName.length() == 0) { | 
 | 
            throw new IntrospectionException("bad property name"); | 
 | 
        }  | 
 | 
        setName(propertyName);  | 
 | 
        setReadMethod(readMethod);  | 
 | 
        setWriteMethod(writeMethod);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    PropertyDescriptor(Class<?> bean, String base, Method read, Method write) throws IntrospectionException { | 
 | 
        if (bean == null) { | 
 | 
            throw new IntrospectionException("Target Bean class is null"); | 
 | 
        }  | 
 | 
        setClass0(bean);  | 
 | 
        setName(Introspector.decapitalize(base));  | 
 | 
        setReadMethod(read);  | 
 | 
        setWriteMethod(write);  | 
 | 
        this.baseName = base;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public synchronized Class<?> getPropertyType() { | 
 | 
        Class<?> type = getPropertyType0();  | 
 | 
        if (type  == null) { | 
 | 
            try { | 
 | 
                type = findPropertyType(getReadMethod(), getWriteMethod());  | 
 | 
                setPropertyType(type);  | 
 | 
            } catch (IntrospectionException ex) { | 
 | 
                // Fall  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return type;  | 
 | 
    }  | 
 | 
 | 
 | 
    private void setPropertyType(Class<?> type) { | 
 | 
        this.propertyTypeRef = getWeakReference(type);  | 
 | 
    }  | 
 | 
 | 
 | 
    private Class<?> getPropertyType0() { | 
 | 
        return (this.propertyTypeRef != null)  | 
 | 
                ? this.propertyTypeRef.get()  | 
 | 
                : null;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public synchronized Method getReadMethod() { | 
 | 
        Method readMethod = this.readMethodRef.get();  | 
 | 
        if (readMethod == null) { | 
 | 
            Class<?> cls = getClass0();  | 
 | 
            if (cls == null || (readMethodName == null && !this.readMethodRef.isSet())) { | 
 | 
                  | 
 | 
                return null;  | 
 | 
            }  | 
 | 
            String nextMethodName = Introspector.GET_PREFIX + getBaseName();  | 
 | 
            if (readMethodName == null) { | 
 | 
                Class<?> type = getPropertyType0();  | 
 | 
                if (type == boolean.class || type == null) { | 
 | 
                    readMethodName = Introspector.IS_PREFIX + getBaseName();  | 
 | 
                } else { | 
 | 
                    readMethodName = nextMethodName;  | 
 | 
                }  | 
 | 
            }  | 
 | 
 | 
 | 
            // Since there can be multiple write methods but only one getter  | 
 | 
            // method, find the getter method first so that you know what the  | 
 | 
            // property type is.  For booleans, there can be "is" and "get"  | 
 | 
            // methods.  If an "is" method exists, this is the official  | 
 | 
              | 
 | 
            readMethod = Introspector.findMethod(cls, readMethodName, 0);  | 
 | 
            if ((readMethod == null) && !readMethodName.equals(nextMethodName)) { | 
 | 
                readMethodName = nextMethodName;  | 
 | 
                readMethod = Introspector.findMethod(cls, readMethodName, 0);  | 
 | 
            }  | 
 | 
            try { | 
 | 
                setReadMethod(readMethod);  | 
 | 
            } catch (IntrospectionException ex) { | 
 | 
                // fall  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return readMethod;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public synchronized void setReadMethod(Method readMethod)  | 
 | 
                                throws IntrospectionException { | 
 | 
        this.readMethodRef.set(readMethod);  | 
 | 
        if (readMethod == null) { | 
 | 
            readMethodName = null;  | 
 | 
            return;  | 
 | 
        }  | 
 | 
          | 
 | 
        setPropertyType(findPropertyType(readMethod, this.writeMethodRef.get()));  | 
 | 
        setClass0(readMethod.getDeclaringClass());  | 
 | 
 | 
 | 
        readMethodName = readMethod.getName();  | 
 | 
        setTransient(readMethod.getAnnotation(Transient.class));  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public synchronized Method getWriteMethod() { | 
 | 
        Method writeMethod = this.writeMethodRef.get();  | 
 | 
        if (writeMethod == null) { | 
 | 
            Class<?> cls = getClass0();  | 
 | 
            if (cls == null || (writeMethodName == null && !this.writeMethodRef.isSet())) { | 
 | 
                  | 
 | 
                return null;  | 
 | 
            }  | 
 | 
 | 
 | 
              | 
 | 
            Class<?> type = getPropertyType0();  | 
 | 
            if (type == null) { | 
 | 
                try { | 
 | 
                      | 
 | 
                    type = findPropertyType(getReadMethod(), null);  | 
 | 
                    setPropertyType(type);  | 
 | 
                } catch (IntrospectionException ex) { | 
 | 
                    // Without the correct property type we can't be guaranteed  | 
 | 
                      | 
 | 
                    return null;  | 
 | 
                }  | 
 | 
            }  | 
 | 
 | 
 | 
            if (writeMethodName == null) { | 
 | 
                writeMethodName = Introspector.SET_PREFIX + getBaseName();  | 
 | 
            }  | 
 | 
 | 
 | 
            Class<?>[] args = (type == null) ? null : new Class<?>[] { type }; | 
 | 
            writeMethod = Introspector.findMethod(cls, writeMethodName, 1, args);  | 
 | 
            if (writeMethod != null) { | 
 | 
                if (!writeMethod.getReturnType().equals(void.class)) { | 
 | 
                    writeMethod = null;  | 
 | 
                }  | 
 | 
            }  | 
 | 
            try { | 
 | 
                setWriteMethod(writeMethod);  | 
 | 
            } catch (IntrospectionException ex) { | 
 | 
                // fall through  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return writeMethod;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public synchronized void setWriteMethod(Method writeMethod)  | 
 | 
                                throws IntrospectionException { | 
 | 
        this.writeMethodRef.set(writeMethod);  | 
 | 
        if (writeMethod == null) { | 
 | 
            writeMethodName = null;  | 
 | 
            return;  | 
 | 
        }  | 
 | 
          | 
 | 
        setPropertyType(findPropertyType(getReadMethod(), writeMethod));  | 
 | 
        setClass0(writeMethod.getDeclaringClass());  | 
 | 
 | 
 | 
        writeMethodName = writeMethod.getName();  | 
 | 
        setTransient(writeMethod.getAnnotation(Transient.class));  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    void setClass0(Class<?> clz) { | 
 | 
        if (getClass0() != null && clz.isAssignableFrom(getClass0())) { | 
 | 
              | 
 | 
            return;  | 
 | 
        }  | 
 | 
        super.setClass0(clz);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public boolean isBound() { | 
 | 
        return bound;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public void setBound(boolean bound) { | 
 | 
        this.bound = bound;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public boolean isConstrained() { | 
 | 
        return constrained;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public void setConstrained(boolean constrained) { | 
 | 
        this.constrained = constrained;  | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public void setPropertyEditorClass(Class<?> propertyEditorClass) { | 
 | 
        this.propertyEditorClassRef = getWeakReference(propertyEditorClass);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public Class<?> getPropertyEditorClass() { | 
 | 
        return (this.propertyEditorClassRef != null)  | 
 | 
                ? this.propertyEditorClassRef.get()  | 
 | 
                : null;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public PropertyEditor createPropertyEditor(Object bean) { | 
 | 
        Object editor = null;  | 
 | 
 | 
 | 
        final Class<?> cls = getPropertyEditorClass();  | 
 | 
        if (cls != null && PropertyEditor.class.isAssignableFrom(cls)  | 
 | 
                && ReflectUtil.isPackageAccessible(cls)) { | 
 | 
            Constructor<?> ctor = null;  | 
 | 
            if (bean != null) { | 
 | 
                try { | 
 | 
                    ctor = cls.getConstructor(new Class<?>[] { Object.class }); | 
 | 
                } catch (Exception ex) { | 
 | 
                    // Fall through  | 
 | 
                }  | 
 | 
            }  | 
 | 
            try { | 
 | 
                if (ctor == null) { | 
 | 
                    editor = cls.newInstance();  | 
 | 
                } else { | 
 | 
                    editor = ctor.newInstance(new Object[] { bean }); | 
 | 
                }  | 
 | 
            } catch (Exception ex) { | 
 | 
                // Fall through  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return (PropertyEditor)editor;  | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public boolean equals(Object obj) { | 
 | 
        if (this == obj) { | 
 | 
            return true;  | 
 | 
        }  | 
 | 
        if (obj != null && obj instanceof PropertyDescriptor) { | 
 | 
            PropertyDescriptor other = (PropertyDescriptor)obj;  | 
 | 
            Method otherReadMethod = other.getReadMethod();  | 
 | 
            Method otherWriteMethod = other.getWriteMethod();  | 
 | 
 | 
 | 
            if (!compareMethods(getReadMethod(), otherReadMethod)) { | 
 | 
                return false;  | 
 | 
            }  | 
 | 
 | 
 | 
            if (!compareMethods(getWriteMethod(), otherWriteMethod)) { | 
 | 
                return false;  | 
 | 
            }  | 
 | 
 | 
 | 
            if (getPropertyType() == other.getPropertyType() &&  | 
 | 
                getPropertyEditorClass() == other.getPropertyEditorClass() &&  | 
 | 
                bound == other.isBound() && constrained == other.isConstrained() &&  | 
 | 
                writeMethodName == other.writeMethodName &&  | 
 | 
                readMethodName == other.readMethodName) { | 
 | 
                return true;  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return false;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    boolean compareMethods(Method a, Method b) { | 
 | 
          | 
 | 
        if ((a == null) != (b == null)) { | 
 | 
            return false;  | 
 | 
        }  | 
 | 
 | 
 | 
        if (a != null && b != null) { | 
 | 
            if (!a.equals(b)) { | 
 | 
                return false;  | 
 | 
            }  | 
 | 
        }  | 
 | 
        return true;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    PropertyDescriptor(PropertyDescriptor x, PropertyDescriptor y) { | 
 | 
        super(x,y);  | 
 | 
 | 
 | 
        if (y.baseName != null) { | 
 | 
            baseName = y.baseName;  | 
 | 
        } else { | 
 | 
            baseName = x.baseName;  | 
 | 
        }  | 
 | 
 | 
 | 
        if (y.readMethodName != null) { | 
 | 
            readMethodName = y.readMethodName;  | 
 | 
        } else { | 
 | 
            readMethodName = x.readMethodName;  | 
 | 
        }  | 
 | 
 | 
 | 
        if (y.writeMethodName != null) { | 
 | 
            writeMethodName = y.writeMethodName;  | 
 | 
        } else { | 
 | 
            writeMethodName = x.writeMethodName;  | 
 | 
        }  | 
 | 
 | 
 | 
        if (y.propertyTypeRef != null) { | 
 | 
            propertyTypeRef = y.propertyTypeRef;  | 
 | 
        } else { | 
 | 
            propertyTypeRef = x.propertyTypeRef;  | 
 | 
        }  | 
 | 
 | 
 | 
          | 
 | 
        Method xr = x.getReadMethod();  | 
 | 
        Method yr = y.getReadMethod();  | 
 | 
 | 
 | 
          | 
 | 
        try { | 
 | 
            if (isAssignable(xr, yr)) { | 
 | 
                setReadMethod(yr);  | 
 | 
            } else { | 
 | 
                setReadMethod(xr);  | 
 | 
            }  | 
 | 
        } catch (IntrospectionException ex) { | 
 | 
            // fall through  | 
 | 
        }  | 
 | 
 | 
 | 
        // However, if both x and y reference read methods in the same class,  | 
 | 
          | 
 | 
        if (xr != null && yr != null &&  | 
 | 
                   xr.getDeclaringClass() == yr.getDeclaringClass() &&  | 
 | 
                   getReturnType(getClass0(), xr) == boolean.class &&  | 
 | 
                   getReturnType(getClass0(), yr) == boolean.class &&  | 
 | 
                   xr.getName().indexOf(Introspector.IS_PREFIX) == 0 &&  | 
 | 
                   yr.getName().indexOf(Introspector.GET_PREFIX) == 0) { | 
 | 
            try { | 
 | 
                setReadMethod(xr);  | 
 | 
            } catch (IntrospectionException ex) { | 
 | 
                // fall through  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        Method xw = x.getWriteMethod();  | 
 | 
        Method yw = y.getWriteMethod();  | 
 | 
 | 
 | 
        try { | 
 | 
            if (yw != null) { | 
 | 
                setWriteMethod(yw);  | 
 | 
            } else { | 
 | 
                setWriteMethod(xw);  | 
 | 
            }  | 
 | 
        } catch (IntrospectionException ex) { | 
 | 
            // Fall through  | 
 | 
        }  | 
 | 
 | 
 | 
        if (y.getPropertyEditorClass() != null) { | 
 | 
            setPropertyEditorClass(y.getPropertyEditorClass());  | 
 | 
        } else { | 
 | 
            setPropertyEditorClass(x.getPropertyEditorClass());  | 
 | 
        }  | 
 | 
 | 
 | 
 | 
 | 
        bound = x.bound | y.bound;  | 
 | 
        constrained = x.constrained | y.constrained;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    PropertyDescriptor(PropertyDescriptor old) { | 
 | 
        super(old);  | 
 | 
        propertyTypeRef = old.propertyTypeRef;  | 
 | 
        this.readMethodRef.set(old.readMethodRef.get());  | 
 | 
        this.writeMethodRef.set(old.writeMethodRef.get());  | 
 | 
        propertyEditorClassRef = old.propertyEditorClassRef;  | 
 | 
 | 
 | 
        writeMethodName = old.writeMethodName;  | 
 | 
        readMethodName = old.readMethodName;  | 
 | 
        baseName = old.baseName;  | 
 | 
 | 
 | 
        bound = old.bound;  | 
 | 
        constrained = old.constrained;  | 
 | 
    }  | 
 | 
 | 
 | 
    void updateGenericsFor(Class<?> type) { | 
 | 
        setClass0(type);  | 
 | 
        try { | 
 | 
            setPropertyType(findPropertyType(this.readMethodRef.get(), this.writeMethodRef.get()));  | 
 | 
        }  | 
 | 
        catch (IntrospectionException exception) { | 
 | 
            setPropertyType(null);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    private Class<?> findPropertyType(Method readMethod, Method writeMethod)  | 
 | 
        throws IntrospectionException { | 
 | 
        Class<?> propertyType = null;  | 
 | 
        try { | 
 | 
            if (readMethod != null) { | 
 | 
                Class<?>[] params = getParameterTypes(getClass0(), readMethod);  | 
 | 
                if (params.length != 0) { | 
 | 
                    throw new IntrospectionException("bad read method arg count: " | 
 | 
                                                     + readMethod);  | 
 | 
                }  | 
 | 
                propertyType = getReturnType(getClass0(), readMethod);  | 
 | 
                if (propertyType == Void.TYPE) { | 
 | 
                    throw new IntrospectionException("read method " + | 
 | 
                                        readMethod.getName() + " returns void");  | 
 | 
                }  | 
 | 
            }  | 
 | 
            if (writeMethod != null) { | 
 | 
                Class<?>[] params = getParameterTypes(getClass0(), writeMethod);  | 
 | 
                if (params.length != 1) { | 
 | 
                    throw new IntrospectionException("bad write method arg count: " | 
 | 
                                                     + writeMethod);  | 
 | 
                }  | 
 | 
                if (propertyType != null && !params[0].isAssignableFrom(propertyType)) { | 
 | 
                    throw new IntrospectionException("type mismatch between read and write methods"); | 
 | 
                }  | 
 | 
                propertyType = params[0];  | 
 | 
            }  | 
 | 
        } catch (IntrospectionException ex) { | 
 | 
            throw ex;  | 
 | 
        }  | 
 | 
        return propertyType;  | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public int hashCode() { | 
 | 
        int result = 7;  | 
 | 
 | 
 | 
        result = 37 * result + ((getPropertyType() == null) ? 0 :  | 
 | 
                                getPropertyType().hashCode());  | 
 | 
        result = 37 * result + ((getReadMethod() == null) ? 0 :  | 
 | 
                                getReadMethod().hashCode());  | 
 | 
        result = 37 * result + ((getWriteMethod() == null) ? 0 :  | 
 | 
                                getWriteMethod().hashCode());  | 
 | 
        result = 37 * result + ((getPropertyEditorClass() == null) ? 0 :  | 
 | 
                                getPropertyEditorClass().hashCode());  | 
 | 
        result = 37 * result + ((writeMethodName == null) ? 0 :  | 
 | 
                                writeMethodName.hashCode());  | 
 | 
        result = 37 * result + ((readMethodName == null) ? 0 :  | 
 | 
                                readMethodName.hashCode());  | 
 | 
        result = 37 * result + getName().hashCode();  | 
 | 
        result = 37 * result + ((bound == false) ? 0 : 1);  | 
 | 
        result = 37 * result + ((constrained == false) ? 0 : 1);  | 
 | 
 | 
 | 
        return result;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
    String getBaseName() { | 
 | 
        if (baseName == null) { | 
 | 
            baseName = NameGenerator.capitalize(getName());  | 
 | 
        }  | 
 | 
        return baseName;  | 
 | 
    }  | 
 | 
 | 
 | 
    void appendTo(StringBuilder sb) { | 
 | 
        appendTo(sb, "bound", this.bound);  | 
 | 
        appendTo(sb, "constrained", this.constrained);  | 
 | 
        appendTo(sb, "propertyEditorClass", this.propertyEditorClassRef);  | 
 | 
        appendTo(sb, "propertyType", this.propertyTypeRef);  | 
 | 
        appendTo(sb, "readMethod", this.readMethodRef.get());  | 
 | 
        appendTo(sb, "writeMethod", this.writeMethodRef.get());  | 
 | 
    }  | 
 | 
 | 
 | 
    boolean isAssignable(Method m1, Method m2) { | 
 | 
        if (m1 == null) { | 
 | 
            return true;   | 
 | 
        }  | 
 | 
        if (m2 == null) { | 
 | 
            return false;   | 
 | 
        }  | 
 | 
        if (!m1.getName().equals(m2.getName())) { | 
 | 
            return true;   | 
 | 
        }  | 
 | 
        Class<?> type1 = m1.getDeclaringClass();  | 
 | 
        Class<?> type2 = m2.getDeclaringClass();  | 
 | 
        if (!type1.isAssignableFrom(type2)) { | 
 | 
            return false;   | 
 | 
        }  | 
 | 
        type1 = getReturnType(getClass0(), m1);  | 
 | 
        type2 = getReturnType(getClass0(), m2);  | 
 | 
        if (!type1.isAssignableFrom(type2)) { | 
 | 
            return false;   | 
 | 
        }  | 
 | 
        Class<?>[] args1 = getParameterTypes(getClass0(), m1);  | 
 | 
        Class<?>[] args2 = getParameterTypes(getClass0(), m2);  | 
 | 
        if (args1.length != args2.length) { | 
 | 
            return true;   | 
 | 
        }  | 
 | 
        for (int i = 0; i < args1.length; i++) { | 
 | 
            if (!args1[i].isAssignableFrom(args2[i])) { | 
 | 
                return false;   | 
 | 
            }  | 
 | 
        }  | 
 | 
        return true;   | 
 | 
    }  | 
 | 
}  |