• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 
18 package java.beans;
19 
20 import java.lang.reflect.Constructor;
21 import java.lang.reflect.Method;
22 import java.lang.reflect.Modifier;
23 import java.util.Vector;
24 import org.apache.harmony.beans.internal.nls.Messages;
25 
26 public class PropertyDescriptor extends FeatureDescriptor {
27     private Method getter;
28 
29     private Method setter;
30 
31     private Class<?> propertyEditorClass;
32 
33     private boolean constrained;
34 
35     private boolean bound;
36 
PropertyDescriptor(String propertyName, Class<?> beanClass, String getterName, String setterName)37     public PropertyDescriptor(String propertyName, Class<?> beanClass, String getterName,
38             String setterName) throws IntrospectionException {
39         super();
40         if (beanClass == null) {
41             throw new IntrospectionException(Messages.getString("beans.03")); //$NON-NLS-1$
42         }
43         if (propertyName == null || propertyName.length() == 0) {
44             throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$
45         }
46         this.setName(propertyName);
47         this.setDisplayName(propertyName);
48         if (setterName != null) {
49             if (hasMethod(beanClass, setterName)) {
50                 setWriteMethod(beanClass, setterName);
51             } else {
52                 throw new IntrospectionException(Messages.getString("beans.20")); //$NON-NLS-1$
53             }
54         }
55         if (getterName != null) {
56             if (hasMethod(beanClass, getterName)) {
57                 setReadMethod(beanClass, getterName);
58             } else {
59                 throw new IntrospectionException(Messages.getString("beans.1F")); //$NON-NLS-1$
60             }
61         }
62     }
63 
PropertyDescriptor(String propertyName, Method getter, Method setter)64     public PropertyDescriptor(String propertyName, Method getter, Method setter)
65             throws IntrospectionException {
66         super();
67         if (propertyName == null || propertyName.length() == 0) {
68             throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$
69         }
70         this.setName(propertyName);
71         this.setDisplayName(propertyName);
72         setWriteMethod(setter);
73         setReadMethod(getter);
74     }
75 
PropertyDescriptor(String propertyName, Class<?> beanClass)76     public PropertyDescriptor(String propertyName, Class<?> beanClass)
77             throws IntrospectionException {
78         String getterName;
79         String setterName;
80         if (beanClass == null) {
81             throw new IntrospectionException(Messages.getString("beans.03")); //$NON-NLS-1$
82         }
83         if (propertyName == null || propertyName.length() == 0) {
84             throw new IntrospectionException(Messages.getString("beans.04")); //$NON-NLS-1$
85         }
86         this.setName(propertyName);
87         this.setDisplayName(propertyName);
88         getterName = createDefaultMethodName(propertyName, "is"); //$NON-NLS-1$
89         if (hasMethod(beanClass, getterName)) {
90             setReadMethod(beanClass, getterName);
91         } else {
92             getterName = createDefaultMethodName(propertyName, "get"); //$NON-NLS-1$
93             if (hasMethod(beanClass, getterName)) {
94                 setReadMethod(beanClass, getterName);
95             }
96         }
97         setterName = createDefaultMethodName(propertyName, "set"); //$NON-NLS-1$
98         if (hasMethod(beanClass, setterName)) {
99             setWriteMethod(beanClass, setterName);
100         }
101         if (getter == null && setter == null) {
102             throw new IntrospectionException(Messages.getString("beans.01", propertyName)); //$NON-NLS-1$
103         }
104     }
105 
setWriteMethod(Method setter)106     public void setWriteMethod(Method setter) throws IntrospectionException {
107         if (setter != null) {
108             int modifiers = setter.getModifiers();
109             if (!Modifier.isPublic(modifiers)) {
110                 throw new IntrospectionException(Messages.getString("beans.05")); //$NON-NLS-1$
111             }
112             Class<?>[] parameterTypes = setter.getParameterTypes();
113             if (parameterTypes.length != 1) {
114                 throw new IntrospectionException(Messages.getString("beans.06")); //$NON-NLS-1$
115             }
116             Class<?> parameterType = parameterTypes[0];
117             Class<?> propertyType = getPropertyType();
118             if (propertyType != null && !propertyType.equals(parameterType)) {
119                 throw new IntrospectionException(Messages.getString("beans.07")); //$NON-NLS-1$
120             }
121         }
122         this.setter = setter;
123     }
124 
setReadMethod(Method getter)125     public void setReadMethod(Method getter) throws IntrospectionException {
126         if (getter != null) {
127             int modifiers = getter.getModifiers();
128             if (!Modifier.isPublic(modifiers)) {
129                 throw new IntrospectionException(Messages.getString("beans.0A")); //$NON-NLS-1$
130             }
131             Class<?>[] parameterTypes = getter.getParameterTypes();
132             if (parameterTypes.length != 0) {
133                 throw new IntrospectionException(Messages.getString("beans.08")); //$NON-NLS-1$
134             }
135             Class<?> returnType = getter.getReturnType();
136             if (returnType.equals(Void.TYPE)) {
137                 throw new IntrospectionException(Messages.getString("beans.33")); //$NON-NLS-1$
138             }
139             Class<?> propertyType = getPropertyType();
140             if ((propertyType != null) && !returnType.equals(propertyType)) {
141                 throw new IntrospectionException(Messages.getString("beans.09")); //$NON-NLS-1$
142             }
143         }
144         this.getter = getter;
145     }
146 
getWriteMethod()147     public Method getWriteMethod() {
148         return setter;
149     }
150 
getReadMethod()151     public Method getReadMethod() {
152         return getter;
153     }
154 
155     @Override
equals(Object object)156     public boolean equals(Object object) {
157         boolean result = (object != null && object instanceof PropertyDescriptor);
158         if (result) {
159             PropertyDescriptor pd = (PropertyDescriptor) object;
160             boolean gettersAreEqual = (this.getter == null) && (pd.getReadMethod() == null)
161                     || (this.getter != null) && (this.getter.equals(pd.getReadMethod()));
162             boolean settersAreEqual = (this.setter == null) && (pd.getWriteMethod() == null)
163                     || (this.setter != null) && (this.setter.equals(pd.getWriteMethod()));
164             boolean propertyTypesAreEqual = this.getPropertyType() == pd.getPropertyType();
165             boolean propertyEditorClassesAreEqual = this.getPropertyEditorClass() == pd
166                     .getPropertyEditorClass();
167             boolean boundPropertyAreEqual = this.isBound() == pd.isBound();
168             boolean constrainedPropertyAreEqual = this.isConstrained() == pd.isConstrained();
169             result = gettersAreEqual && settersAreEqual && propertyTypesAreEqual
170                     && propertyEditorClassesAreEqual && boundPropertyAreEqual
171                     && constrainedPropertyAreEqual;
172         }
173         return result;
174     }
175 
setPropertyEditorClass(Class<?> propertyEditorClass)176     public void setPropertyEditorClass(Class<?> propertyEditorClass) {
177         this.propertyEditorClass = propertyEditorClass;
178     }
179 
getPropertyType()180     public Class<?> getPropertyType() {
181         Class<?> result = null;
182         if (getter != null) {
183             result = getter.getReturnType();
184         } else if (setter != null) {
185             Class<?>[] parameterTypes = setter.getParameterTypes();
186             result = parameterTypes[0];
187         }
188         return result;
189     }
190 
getPropertyEditorClass()191     public Class<?> getPropertyEditorClass() {
192         return propertyEditorClass;
193     }
194 
setConstrained(boolean constrained)195     public void setConstrained(boolean constrained) {
196         this.constrained = constrained;
197     }
198 
setBound(boolean bound)199     public void setBound(boolean bound) {
200         this.bound = bound;
201     }
202 
isConstrained()203     public boolean isConstrained() {
204         return constrained;
205     }
206 
isBound()207     public boolean isBound() {
208         return bound;
209     }
210 
hasMethod(Class<?> beanClass, String methodName)211     boolean hasMethod(Class<?> beanClass, String methodName) {
212         Method[] methods = findMethods(beanClass, methodName);
213         return (methods.length > 0);
214     }
215 
createDefaultMethodName(String propertyName, String prefix)216     String createDefaultMethodName(String propertyName, String prefix) {
217         String result = null;
218         if (propertyName != null) {
219             String bos = propertyName.substring(0, 1).toUpperCase();
220             String eos = propertyName.substring(1, propertyName.length());
221             result = prefix + bos + eos;
222         }
223         return result;
224     }
225 
findMethods(Class<?> aClass, String methodName)226     Method[] findMethods(Class<?> aClass, String methodName) {
227         Method[] allMethods = aClass.getMethods();
228         Vector<Method> matchedMethods = new Vector<Method>();
229         Method[] result;
230         for (Method method : allMethods) {
231             if (method.getName().equals(methodName)) {
232                 matchedMethods.add(method);
233             }
234         }
235         result = new Method[matchedMethods.size()];
236         for (int j = 0; j < matchedMethods.size(); ++j) {
237             result[j] = matchedMethods.elementAt(j);
238         }
239         return result;
240     }
241 
setReadMethod(Class<?> beanClass, String getterName)242     void setReadMethod(Class<?> beanClass, String getterName) {
243         boolean result = false;
244         Method[] getters = findMethods(beanClass, getterName);
245         for (Method element : getters) {
246             try {
247                 setReadMethod(element);
248                 result = true;
249             } catch (IntrospectionException ie) {
250             }
251             if (result) {
252                 break;
253             }
254         }
255     }
256 
setWriteMethod(Class<?> beanClass, String setterName)257     void setWriteMethod(Class<?> beanClass, String setterName) throws IntrospectionException {
258         boolean result = false;
259         Method[] setters = findMethods(beanClass, setterName);
260         for (Method element : setters) {
261             try {
262                 setWriteMethod(element);
263                 result = true;
264             } catch (IntrospectionException ie) {
265             }
266             if (result) {
267                 break;
268             }
269         }
270     }
271 
createPropertyEditor(Object bean)272     public PropertyEditor createPropertyEditor(Object bean) {
273         PropertyEditor editor;
274         if (propertyEditorClass == null) {
275             return null;
276         }
277         if (!PropertyEditor.class.isAssignableFrom(propertyEditorClass)) {
278             // beans.48=Property editor is not assignable from the
279             // PropertyEditor interface
280             throw new ClassCastException(Messages.getString("beans.48")); //$NON-NLS-1$
281         }
282         try {
283             Constructor<?> constr;
284             try {
285                 // try to look for the constructor with single Object argument
286                 constr = propertyEditorClass.getConstructor(Object.class);
287                 editor = (PropertyEditor) constr.newInstance(bean);
288             } catch (NoSuchMethodException e) {
289                 // try no-argument constructor
290                 constr = propertyEditorClass.getConstructor();
291                 editor = (PropertyEditor) constr.newInstance();
292             }
293         } catch (Exception e) {
294             // beans.47=Unable to instantiate property editor
295             RuntimeException re = new RuntimeException(Messages.getString("beans.47"), e); //$NON-NLS-1$
296             throw re;
297         }
298         return editor;
299     }
300 }
301