| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package java.beans; |
| |
| import java.lang.reflect.Constructor; |
| import java.lang.reflect.Method; |
| import java.lang.reflect.Modifier; |
| import java.util.Vector; |
| import org.apache.harmony.beans.internal.nls.Messages; |
| |
| public class PropertyDescriptor extends FeatureDescriptor { |
| private Method getter; |
| |
| private Method setter; |
| |
| private Class<?> propertyEditorClass; |
| |
| private boolean constrained; |
| |
| private boolean bound; |
| |
| public PropertyDescriptor(String propertyName, Class<?> beanClass, String getterName, |
| String setterName) throws IntrospectionException { |
| super(); |
| if (beanClass == null) { |
| throw new IntrospectionException(Messages.getString("beans.03")); //$NON-NLS-1$ |
| } |
| if (propertyName == null || propertyName.length() == 0) { |
| throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$ |
| } |
| this.setName(propertyName); |
| this.setDisplayName(propertyName); |
| if (setterName != null) { |
| if (hasMethod(beanClass, setterName)) { |
| setWriteMethod(beanClass, setterName); |
| } else { |
| throw new IntrospectionException(Messages.getString("beans.20")); //$NON-NLS-1$ |
| } |
| } |
| if (getterName != null) { |
| if (hasMethod(beanClass, getterName)) { |
| setReadMethod(beanClass, getterName); |
| } else { |
| throw new IntrospectionException(Messages.getString("beans.1F")); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| public PropertyDescriptor(String propertyName, Method getter, Method setter) |
| throws IntrospectionException { |
| super(); |
| if (propertyName == null || propertyName.length() == 0) { |
| throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$ |
| } |
| this.setName(propertyName); |
| this.setDisplayName(propertyName); |
| setWriteMethod(setter); |
| setReadMethod(getter); |
| } |
| |
| public PropertyDescriptor(String propertyName, Class<?> beanClass) |
| throws IntrospectionException { |
| String getterName; |
| String setterName; |
| if (beanClass == null) { |
| throw new IntrospectionException(Messages.getString("beans.03")); //$NON-NLS-1$ |
| } |
| if (propertyName == null || propertyName.length() == 0) { |
| throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$ |
| } |
| this.setName(propertyName); |
| this.setDisplayName(propertyName); |
| getterName = createDefaultMethodName(propertyName, "is"); //$NON-NLS-1$ |
| if (hasMethod(beanClass, getterName)) { |
| setReadMethod(beanClass, getterName); |
| } else { |
| getterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$ |
| if (hasMethod(beanClass, getterName)) { |
| setReadMethod(beanClass, getterName); |
| } |
| } |
| setterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$ |
| if (hasMethod(beanClass, setterName)) { |
| setWriteMethod(beanClass, setterName); |
| } |
| if (getter == null && setter == null) { |
| throw new IntrospectionException(Messages.getString("beans.01", propertyName)); //$NON-NLS-1$ |
| } |
| } |
| |
| public void setWriteMethod(Method setter) throws IntrospectionException { |
| if (setter != null) { |
| int modifiers = setter.getModifiers(); |
| if (!Modifier.isPublic(modifiers)) { |
| throw new IntrospectionException(Messages.getString("beans.05")); //$NON-NLS-1$ |
| } |
| Class<?>[] parameterTypes = setter.getParameterTypes(); |
| if (parameterTypes.length != 1) { |
| throw new IntrospectionException(Messages.getString("beans.06")); //$NON-NLS-1$ |
| } |
| Class<?> parameterType = parameterTypes[0]; |
| Class<?> propertyType = getPropertyType(); |
| if (propertyType != null && !propertyType.equals(parameterType)) { |
| throw new IntrospectionException(Messages.getString("beans.07")); //$NON-NLS-1$ |
| } |
| } |
| this.setter = setter; |
| } |
| |
| public void setReadMethod(Method getter) throws IntrospectionException { |
| if (getter != null) { |
| int modifiers = getter.getModifiers(); |
| if (!Modifier.isPublic(modifiers)) { |
| throw new IntrospectionException(Messages.getString("beans.0A")); //$NON-NLS-1$ |
| } |
| Class<?>[] parameterTypes = getter.getParameterTypes(); |
| if (parameterTypes.length != 0) { |
| throw new IntrospectionException(Messages.getString("beans.08")); //$NON-NLS-1$ |
| } |
| Class<?> returnType = getter.getReturnType(); |
| if (returnType.equals(Void.TYPE)) { |
| throw new IntrospectionException(Messages.getString("beans.33")); //$NON-NLS-1$ |
| } |
| Class<?> propertyType = getPropertyType(); |
| if ((propertyType != null) && !returnType.equals(propertyType)) { |
| throw new IntrospectionException(Messages.getString("beans.09")); //$NON-NLS-1$ |
| } |
| } |
| this.getter = getter; |
| } |
| |
| public Method getWriteMethod() { |
| return setter; |
| } |
| |
| public Method getReadMethod() { |
| return getter; |
| } |
| |
| @Override |
| public boolean equals(Object object) { |
| boolean result = (object != null && object instanceof PropertyDescriptor); |
| if (result) { |
| PropertyDescriptor pd = (PropertyDescriptor) object; |
| boolean gettersAreEqual = (this.getter == null) && (pd.getReadMethod() == null) |
| || (this.getter != null) && (this.getter.equals(pd.getReadMethod())); |
| boolean settersAreEqual = (this.setter == null) && (pd.getWriteMethod() == null) |
| || (this.setter != null) && (this.setter.equals(pd.getWriteMethod())); |
| boolean propertyTypesAreEqual = this.getPropertyType() == pd.getPropertyType(); |
| boolean propertyEditorClassesAreEqual = this.getPropertyEditorClass() == pd |
| .getPropertyEditorClass(); |
| boolean boundPropertyAreEqual = this.isBound() == pd.isBound(); |
| boolean constrainedPropertyAreEqual = this.isConstrained() == pd.isConstrained(); |
| result = gettersAreEqual && settersAreEqual && propertyTypesAreEqual |
| && propertyEditorClassesAreEqual && boundPropertyAreEqual |
| && constrainedPropertyAreEqual; |
| } |
| return result; |
| } |
| |
| public void setPropertyEditorClass(Class<?> propertyEditorClass) { |
| this.propertyEditorClass = propertyEditorClass; |
| } |
| |
| public Class<?> getPropertyType() { |
| Class<?> result = null; |
| if (getter != null) { |
| result = getter.getReturnType(); |
| } else if (setter != null) { |
| Class<?>[] parameterTypes = setter.getParameterTypes(); |
| result = parameterTypes[0]; |
| } |
| return result; |
| } |
| |
| public Class<?> getPropertyEditorClass() { |
| return propertyEditorClass; |
| } |
| |
| public void setConstrained(boolean constrained) { |
| this.constrained = constrained; |
| } |
| |
| public void setBound(boolean bound) { |
| this.bound = bound; |
| } |
| |
| public boolean isConstrained() { |
| return constrained; |
| } |
| |
| public boolean isBound() { |
| return bound; |
| } |
| |
| boolean hasMethod(Class<?> beanClass, String methodName) { |
| Method[] methods = findMethods(beanClass, methodName); |
| return (methods.length > 0); |
| } |
| |
| String createDefaultMethodName(String propertyName, String prefix) { |
| String result = null; |
| if (propertyName != null) { |
| String bos = propertyName.substring(0, 1).toUpperCase(); |
| String eos = propertyName.substring(1, propertyName.length()); |
| result = prefix + bos + eos; |
| } |
| return result; |
| } |
| |
| Method[] findMethods(Class<?> aClass, String methodName) { |
| Method[] allMethods = aClass.getMethods(); |
| Vector<Method> matchedMethods = new Vector<Method>(); |
| Method[] result; |
| for (Method method : allMethods) { |
| if (method.getName().equals(methodName)) { |
| matchedMethods.add(method); |
| } |
| } |
| result = new Method[matchedMethods.size()]; |
| for (int j = 0; j < matchedMethods.size(); ++j) { |
| result[j] = matchedMethods.elementAt(j); |
| } |
| return result; |
| } |
| |
| void setReadMethod(Class<?> beanClass, String getterName) { |
| boolean result = false; |
| Method[] getters = findMethods(beanClass, getterName); |
| for (Method element : getters) { |
| try { |
| setReadMethod(element); |
| result = true; |
| } catch (IntrospectionException ie) { |
| } |
| if (result) { |
| break; |
| } |
| } |
| } |
| |
| void setWriteMethod(Class<?> beanClass, String setterName) throws IntrospectionException { |
| boolean result = false; |
| Method[] setters = findMethods(beanClass, setterName); |
| for (Method element : setters) { |
| try { |
| setWriteMethod(element); |
| result = true; |
| } catch (IntrospectionException ie) { |
| } |
| if (result) { |
| break; |
| } |
| } |
| } |
| |
| public PropertyEditor createPropertyEditor(Object bean) { |
| PropertyEditor editor; |
| if (propertyEditorClass == null) { |
| return null; |
| } |
| if (!PropertyEditor.class.isAssignableFrom(propertyEditorClass)) { |
| // beans.48=Property editor is not assignable from the |
| // PropertyEditor interface |
| throw new ClassCastException(Messages.getString("beans.48")); //$NON-NLS-1$ |
| } |
| try { |
| Constructor<?> constr; |
| try { |
| // try to look for the constructor with single Object argument |
| constr = propertyEditorClass.getConstructor(Object.class); |
| editor = (PropertyEditor) constr.newInstance(bean); |
| } catch (NoSuchMethodException e) { |
| // try no-argument constructor |
| constr = propertyEditorClass.getConstructor(); |
| editor = (PropertyEditor) constr.newInstance(); |
| } |
| } catch (Exception e) { |
| // beans.47=Unable to instantiate property editor |
| RuntimeException re = new RuntimeException(Messages.getString("beans.47"), e); //$NON-NLS-1$ |
| throw re; |
| } |
| return editor; |
| } |
| } |