KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > activemq > tool > properties > ReflectionUtil


1 /**
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one or more
4  * contributor license agreements. See the NOTICE file distributed with
5  * this work for additional information regarding copyright ownership.
6  * The ASF licenses this file to You under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with
8  * the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package org.apache.activemq.tool.properties;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22
23 import java.util.Iterator JavaDoc;
24 import java.util.StringTokenizer JavaDoc;
25 import java.util.Properties JavaDoc;
26 import java.util.List JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.lang.reflect.Method JavaDoc;
29 import java.lang.reflect.InvocationTargetException JavaDoc;
30 import java.lang.reflect.Constructor JavaDoc;
31
32 public final class ReflectionUtil {
33     private static final Log log = LogFactory.getLog(ReflectionUtil.class);
34
35     private ReflectionUtil() {
36     }
37
38     public static void configureClass(Object JavaDoc obj, String JavaDoc key, String JavaDoc val) {
39         try {
40             String JavaDoc debugInfo;
41
42             Object JavaDoc target = obj;
43             Class JavaDoc targetClass = obj.getClass();
44
45             // DEBUG: Debugging Info
46
debugInfo = "Invoking: " + targetClass.getName();
47
48             StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(key, ".");
49             String JavaDoc keySubString = key;
50             int tokenCount = tokenizer.countTokens();
51
52             // For nested settings, get the object first. -1, do not count the last token
53
for (int j=0; j<tokenCount-1; j++) {
54                 // Find getter method first
55
String JavaDoc name = tokenizer.nextToken();
56
57                 // Check if the target object will accept the settings
58
if (target instanceof ReflectionConfigurable && !((ReflectionConfigurable)target).acceptConfig(keySubString, val)) {
59                     return;
60                 } else {
61                     // This will reduce the key, so that it will be recognize by the next object. i.e.
62
// Property name: factory.prefetchPolicy.queuePrefetch
63
// Calling order: this.getFactory().prefetchPolicy().queuePrefetch();
64
// If factory does not accept the config, it should be given prefetchPolicy.queuePrefetch as the key
65
keySubString = keySubString.substring(name.length() + 1); // +1 to account for the '.'
66
}
67
68                 String JavaDoc getMethod = "get" + name.substring(0,1).toUpperCase() + name.substring(1);
69                 Method JavaDoc method = targetClass.getMethod(getMethod, new Class JavaDoc[] {});
70                 target = method.invoke(target, null);
71                 targetClass = target.getClass();
72
73
74                 debugInfo += ("." + getMethod + "()");
75             }
76
77             // Property name
78
String JavaDoc property = tokenizer.nextToken();
79             // Check if the target object will accept the settings
80
if (target instanceof ReflectionConfigurable && !((ReflectionConfigurable)target).acceptConfig(property, val)) {
81                 return;
82             }
83
84             // Find setter method
85
Method JavaDoc setterMethod = findSetterMethod(targetClass, property);
86
87             // Get the first parameter type. This assumes that there is only one parameter.
88
if (setterMethod == null) {
89                 throw new IllegalAccessException JavaDoc("Unable to find appropriate setter method signature for property: " + property);
90             }
91             Class JavaDoc paramType = setterMethod.getParameterTypes()[0];
92
93             // Set primitive type
94
debugInfo += ("." + setterMethod + "(" + paramType.getName() + ": " + val + ")");
95             if (paramType.isPrimitive()) {
96                 if (paramType == Boolean.TYPE) {
97                     setterMethod.invoke(target, new Object JavaDoc[] {Boolean.valueOf(val)});
98                 } else if (paramType == Integer.TYPE) {
99                     setterMethod.invoke(target, new Object JavaDoc[] {Integer.valueOf(val)});
100                 } else if (paramType == Long.TYPE) {
101                     setterMethod.invoke(target, new Object JavaDoc[] {Long.valueOf(val)});
102                 } else if (paramType == Double.TYPE) {
103                     setterMethod.invoke(target, new Object JavaDoc[] {Double.valueOf(val)});
104                 } else if (paramType == Float.TYPE) {
105                     setterMethod.invoke(target, new Object JavaDoc[] {Float.valueOf(val)});
106                 } else if (paramType == Short.TYPE) {
107                     setterMethod.invoke(target, new Object JavaDoc[] {Short.valueOf(val)});
108                 } else if (paramType == Byte.TYPE) {
109                     setterMethod.invoke(target, new Object JavaDoc[] {Byte.valueOf(val)});
110                 } else if (paramType == Character.TYPE) {
111                     setterMethod.invoke(target, new Object JavaDoc[] {new Character JavaDoc(val.charAt(0))});
112                 }
113             } else {
114                 // Set String type
115
if (paramType == String JavaDoc.class) {
116                     setterMethod.invoke(target, new Object JavaDoc[] {val});
117
118                 // For unknown object type, try to create an instance of the object using a String constructor
119
} else {
120                     Constructor JavaDoc c = paramType.getConstructor(new Class JavaDoc[] {String JavaDoc.class});
121                     Object JavaDoc paramObject = c.newInstance(new Object JavaDoc[] {val});
122
123                     setterMethod.invoke(target, new Object JavaDoc[] {paramObject});
124                 }
125             }
126             log.debug(debugInfo);
127
128         } catch (Exception JavaDoc e) {
129             log.warn(e);
130         }
131     }
132
133     public static void configureClass(Object JavaDoc obj, Properties JavaDoc props) {
134         for (Iterator JavaDoc i = props.keySet().iterator(); i.hasNext();) {
135             try {
136                 String JavaDoc key = (String JavaDoc)i.next();
137                 String JavaDoc val = props.getProperty(key);
138
139                 configureClass(obj, key, val);
140             } catch (Throwable JavaDoc t) {
141                 // Let's catch any exception as this could be cause by the foreign class
142
t.printStackTrace();
143             }
144         }
145     }
146
147     public static Properties JavaDoc retrieveObjectProperties(Object JavaDoc obj) {
148         Properties JavaDoc props = new Properties JavaDoc();
149         try {
150             props.putAll(retrieveClassProperties("", obj.getClass(), obj));
151         } catch (Exception JavaDoc e) {
152             log.warn(e);
153         }
154         return props;
155     }
156
157     protected static Properties JavaDoc retrieveClassProperties(String JavaDoc prefix, Class JavaDoc targetClass, Object JavaDoc targetObject) {
158         if (targetClass == null || targetObject == null) {
159             return new Properties JavaDoc();
160         } else {
161             Properties JavaDoc props = new Properties JavaDoc();
162             Method JavaDoc[] getterMethods = findAllGetterMethods(targetClass);
163             for (int i=0; i<getterMethods.length; i++) {
164                 try {
165                     String JavaDoc propertyName = getPropertyName(getterMethods[i].getName());
166                     Class JavaDoc retType = getterMethods[i].getReturnType();
167
168                     // If primitive or string type, return it
169
if (retType.isPrimitive() || retType == String JavaDoc.class) {
170                         // Check for an appropriate setter method to consider it as a property
171
if (findSetterMethod(targetClass, propertyName) != null) {
172                             Object JavaDoc val = null;
173                             try {
174                                 val = getterMethods[i].invoke(targetObject, null);
175                             } catch (InvocationTargetException JavaDoc e) {
176                                 e.printStackTrace();
177                             } catch (IllegalAccessException JavaDoc e) {
178                                 e.printStackTrace();
179                             }
180                             props.setProperty(prefix + propertyName, val + "");
181                         }
182                     } else {
183                         try {
184                             Object JavaDoc val = getterMethods[i].invoke(targetObject, null);
185                             if (val != null) {
186                                 props.putAll(retrieveClassProperties(propertyName + ".", val.getClass(), val));
187                             }
188                         } catch (InvocationTargetException JavaDoc e) {
189                             e.printStackTrace();
190                         } catch (IllegalAccessException JavaDoc e) {
191                             e.printStackTrace();
192                         }
193                     }
194                 } catch (Throwable JavaDoc t) {
195                     // Let's catch any exception, cause this could be cause by the foreign class
196
t.printStackTrace();
197                 }
198             }
199             return props;
200         }
201     }
202
203     private static Method JavaDoc findSetterMethod(Class JavaDoc targetClass, String JavaDoc propertyName) {
204         String JavaDoc methodName = "set" + propertyName.substring(0,1).toUpperCase() + propertyName.substring(1);
205
206         Method JavaDoc[] methods = targetClass.getMethods();
207         for (int i=0; i<methods.length; i++) {
208             if (methods[i].getName().equals(methodName) && isSetterMethod(methods[i])) {
209                 return methods[i];
210             }
211         }
212         return null;
213     }
214
215     private static Method JavaDoc findGetterMethod(Class JavaDoc targetClass, String JavaDoc propertyName) {
216         String JavaDoc methodName1 = "get" + propertyName.substring(0,1).toUpperCase() + propertyName.substring(1);
217         String JavaDoc methodName2 = "is" + propertyName.substring(0,1).toUpperCase() + propertyName.substring(1);
218
219         Method JavaDoc[] methods = targetClass.getMethods();
220         for (int i=0; i<methods.length; i++) {
221             if ((methods[i].getName().equals(methodName1) || methods[i].getName().equals(methodName2)) && isGetterMethod(methods[i])) {
222                 return methods[i];
223             }
224         }
225         return null;
226     }
227
228     private static Method JavaDoc[] findAllGetterMethods(Class JavaDoc targetClass) {
229         List JavaDoc getterMethods = new ArrayList JavaDoc();
230         Method JavaDoc[] methods = targetClass.getMethods();
231
232         for (int i=0; i<methods.length; i++) {
233             if (isGetterMethod(methods[i])) {
234                 getterMethods.add(methods[i]);
235             }
236         }
237
238         return (Method JavaDoc[])getterMethods.toArray(new Method JavaDoc[] {});
239     }
240
241     private static boolean isGetterMethod(Method JavaDoc method) {
242         // Check method signature first
243
// If 'get' method, must return a non-void value
244
// If 'is' method, must return a boolean value
245
// Both must have no parameters
246
// Method must not belong to the Object class to prevent infinite loop
247
return (((method.getName().startsWith("is") && method.getReturnType() == Boolean.TYPE) ||
248                  (method.getName().startsWith("get") && method.getReturnType() != Void.TYPE)) &&
249                 (method.getParameterTypes().length == 0) && method.getDeclaringClass() != Object JavaDoc.class);
250     }
251
252     private static boolean isSetterMethod(Method JavaDoc method) {
253         // Check method signature first
254
if (method.getName().startsWith("set") && method.getReturnType() == Void.TYPE) {
255             Class JavaDoc[] paramType = method.getParameterTypes();
256             // Check that it can only accept one parameter
257
if (paramType.length == 1) {
258                 // Check if parameter is a primitive or can accept a String parameter
259
if (paramType[0].isPrimitive() || paramType[0] == String JavaDoc.class) {
260                     return true;
261                 } else {
262                     // Check if object can accept a string as a constructor
263
try {
264                         if (paramType[0].getConstructor(new Class JavaDoc[] {String JavaDoc.class}) != null) {
265                             return true;
266                         }
267                     } catch (NoSuchMethodException JavaDoc e) {
268                         // Do nothing
269
}
270                 }
271             }
272         }
273         return false;
274     }
275
276     private static String JavaDoc getPropertyName(String JavaDoc methodName) {
277         String JavaDoc name;
278         if (methodName.startsWith("get")) {
279             name = methodName.substring(3);
280         } else if (methodName.startsWith("set")) {
281             name = methodName.substring(3);
282         } else if (methodName.startsWith("is")) {
283             name = methodName.substring(2);
284         } else {
285             name = "";
286         }
287
288         return name.substring(0,1).toLowerCase() + name.substring(1);
289     }
290 }
291
Popular Tags