001: package com.silvermindsoftware.hitch.reflect;
002:
003: import java.lang.reflect.Field;
004: import java.lang.reflect.Method;
005: import java.util.ArrayList;
006: import java.util.List;
007:
008: /**
009: * Copyright 2007 Brandon Goodin
010: * <p/>
011: * Licensed under the Apache License, Version 2.0 (the "License");
012: * you may not use this file except in compliance with the License.
013: * You may obtain a copy of the License at
014: * <p/>
015: * http://www.apache.org/licenses/LICENSE-2.0
016: * <p/>
017: * Unless required by applicable law or agreed to in writing, software
018: * distributed under the License is distributed on an "AS IS" BASIS,
019: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
020: * See the License for the specific language governing permissions and
021: * limitations under the License.
022: */
023:
024: public class ClassInfo {
025:
026: /* Class Hierarchy */
027: public List<Class> classList = new ArrayList<Class>();
028:
029: /* Fields */
030: Field[] fields;
031:
032: /* Methods */
033: Method[] getters;
034: Method[] setters;
035: Method[] methods;
036:
037: public ClassInfo(Class clazz) {
038: collectInfo(clazz);
039: }
040:
041: private void collectInfo(Class clazz) {
042: classList.add(clazz);
043: getSuperClass(clazz);
044: collectFields();
045: collectMethods();
046: }
047:
048: private void collectFields() {
049:
050: List<FieldInfo> fieldInfoList = new ArrayList<FieldInfo>();
051: List<Field> fieldList = new ArrayList<Field>();
052:
053: for (Class clazz : classList) {
054: for (Field field : clazz.getDeclaredFields()) {
055: FieldInfo fieldInfo = new FieldInfo(field);
056: if (!fieldInfoList.contains(fieldInfo)) {
057: fieldInfoList.add(fieldInfo);
058: fieldList.add(fieldInfo.getField());
059: }
060: }
061: }
062:
063: fields = fieldList.toArray(new Field[] {});
064:
065: }
066:
067: private void collectMethods() {
068:
069: List<MethodInfo> setterInfoList = new ArrayList<MethodInfo>();
070: List<MethodInfo> getterInfoList = new ArrayList<MethodInfo>();
071: List<MethodInfo> methodsInfoList = new ArrayList<MethodInfo>();
072:
073: List<Method> setterList = new ArrayList<Method>();
074: List<Method> getterList = new ArrayList<Method>();
075: List<Method> methodList = new ArrayList<Method>();
076:
077: for (Class clazz : classList) {
078: for (Method method : clazz.getDeclaredMethods()) {
079: if (method.getName().startsWith("set")) {
080: MethodInfo methodInfo = new MethodInfo(method);
081: if (!setterInfoList.contains(methodInfo)) {
082: setterInfoList.add(methodInfo);
083: setterList.add(methodInfo.getMethod());
084: }
085: } else if ((method.getName().startsWith("get") || method
086: .getName().startsWith("is"))
087: && !method.getName().equals("getClass")
088: && !method.getName().equals("get")) {
089: MethodInfo methodInfo = new MethodInfo(method);
090: if (!getterInfoList.contains(methodInfo)) {
091: getterInfoList.add(methodInfo);
092: getterList.add(methodInfo.getMethod());
093: }
094: } else {
095: MethodInfo methodInfo = new MethodInfo(method);
096: if (!methodsInfoList.contains(methodInfo)) {
097: methodsInfoList.add(methodInfo);
098: methodList.add(methodInfo.getMethod());
099: }
100: }
101: }
102: }
103:
104: getters = getterList.toArray(new Method[] {});
105: setters = setterList.toArray(new Method[] {});
106: methods = methodList.toArray(new Method[] {});
107:
108: }
109:
110: private void getSuperClass(Class clazz) {
111: Class super Clazz = clazz.getSuperclass();
112: if (super Clazz != null) {
113: classList.add(super Clazz);
114: getSuperClass(super Clazz);
115: }
116: }
117:
118: private static boolean arrayContentsEq(Object[] a1, Object[] a2) {
119: if (a1 == null) {
120: return a2 == null || a2.length == 0;
121: }
122:
123: if (a2 == null) {
124: return a1.length == 0;
125: }
126:
127: if (a1.length != a2.length) {
128: return false;
129: }
130:
131: for (int i = 0; i < a1.length; i++) {
132: if (a1[i] != a2[i]) {
133: return false;
134: }
135: }
136:
137: return true;
138: }
139:
140: /**
141: * Retrieves a single field (public, private, protected or package) from the provided class
142: * or one of its superclasses. The lowest subclass field is collected when there is a duplicate.
143: * A duplicate is defined as having the same field name and type.
144: *
145: * @return
146: */
147: public Field getField(String name) throws NoSuchFieldException {
148:
149: if (name == null || name.trim().equals("")) {
150: throw new IllegalArgumentException(
151: "Name cannot be null or empty");
152: }
153: ;
154:
155: Field retField = null;
156:
157: for (Field field : fields) {
158: if (field.getName().equals(name)) {
159: retField = field;
160: break;
161: }
162: }
163:
164: if (retField == null) {
165: throw new NoSuchFieldException(
166: "No method found for method named " + name);
167: }
168:
169: return retField;
170: }
171:
172: /**
173: * Retrieves a single getter method (public, private, protected or package) from the provided class
174: * or one of its superclasses. The lowest subclass method is collected when there is a duplicate.
175: * A duplicate is defined as having the same method name and parameter types.
176: *
177: * @return
178: */
179: public Method getSetterMethod(String name, Class[] parameterTypes)
180: throws NoSuchMethodException {
181: if (name == null || name.trim().equals(""))
182: throw new IllegalArgumentException(
183: "Name cannot be null or empty");
184:
185: Method retSetter = null;
186:
187: for (Method setter : setters) {
188: if (setter.getName().equals(name)
189: && arrayContentsEq(parameterTypes, setter
190: .getParameterTypes())) {
191: retSetter = setter;
192: break;
193: }
194: }
195:
196: if (retSetter == null)
197: throw new NoSuchMethodException(
198: "No method found for method named " + name);
199:
200: return retSetter;
201: }
202:
203: /**
204: * Retrieves a single setter method (public, private, protected or package) from the provided class
205: * or one of its superclasses. The lowest subclass method is collected when there is a duplicate.
206: * A duplicate is defined as having the same method name and parameter types.
207: *
208: * @return
209: */
210: public Method getGetterMethod(String name)
211: throws NoSuchMethodException {
212: if (name == null || name.trim().equals(""))
213: throw new IllegalArgumentException(
214: "Name cannot be null or empty");
215:
216: Method retGetter = null;
217:
218: for (Method getter : getters) {
219: if (getter.getName().equals(name)
220: && getter.getParameterTypes().length == 0) {
221: retGetter = getter;
222: break;
223: }
224: }
225:
226: if (retGetter == null)
227: throw new NoSuchMethodException(
228: "No method found for method named " + name);
229:
230: return retGetter;
231: }
232:
233: /**
234: * Retrieves a single method that is not a setter or getter (public, private, protected or package)
235: * from the provided class or one of its superclasses. Only the lowest subclass method is collected
236: * when there is a duplicate. A duplicate is defined as having the same method name and parameter
237: * types.
238: *
239: * @return
240: */
241: public Method getMethod(String name, Class[] parameterTypes)
242: throws NoSuchMethodException {
243: if (name == null || name.trim().equals(""))
244: throw new IllegalArgumentException(
245: "Name cannot be null or empty");
246:
247: Method retMethod = null;
248:
249: for (Method method : methods) {
250: if (method.getName().equals(name)
251: && arrayContentsEq(parameterTypes, method
252: .getParameterTypes())) {
253: retMethod = method;
254: break;
255: }
256: }
257:
258: if (retMethod == null)
259: throw new NoSuchMethodException(
260: "No method found for method named " + name);
261:
262: return retMethod;
263: }
264:
265: /**
266: * Array of all fields (public, private, protected or package) for the provided class
267: * and all of its superclasses. The lowest subclass field is collected when there is
268: * a duplicate. A duplicate is defined as having the same field name and type .
269: *
270: * @return
271: */
272: public Field[] getFields() {
273: return fields;
274: }
275:
276: /**
277: * Array of all setter methods (public, private, protected or package) for the provided
278: * class and all of its superclasses. The lowest subclass method is collected when there
279: * is a duplicate. A duplicate is defined as having the same method name and parameter
280: * types.
281: *
282: * @return
283: */
284: public Method[] getSetters() {
285: return setters;
286: }
287:
288: /**
289: * Array of all getter methods (public, private, protected or package) for the provided
290: * class and all of its superclasses. The lowest subclass method is collected when there
291: * is a duplicate. A duplicate is defined as having the same method name and parameter
292: * types.
293: *
294: * @return
295: */
296: public Method[] getGetters() {
297: return getters;
298: }
299:
300: /**
301: * Array of all methods that are not setters or getters (public, private, protected or package)
302: * for the provided class and all of its superclasses. The lowest subclass method is collected
303: * when there is a duplicate. A duplicate is defined as having the same method name and parameter
304: * types.
305: *
306: * @return
307: */
308: public Method[] getMethods() {
309: return getters;
310: }
311: }
|