001: package org.conform.util;
002:
003: import org.apache.commons.logging.LogFactory;
004: import org.conform.Meta;
005:
006: import java.lang.reflect.Array;
007: import java.lang.reflect.Field;
008: import java.lang.reflect.InvocationTargetException;
009: import java.lang.reflect.Method;
010: import java.util.*;
011: import java.lang.reflect.Modifier;
012:
013: public class BeanReflecter {
014: private static org.apache.commons.logging.Log LOG = LogFactory
015: .getLog(BeanReflecter.class);
016:
017: public static String toString(Object bean) {
018: if (bean == null || bean.getClass().equals(Object.class)) {
019: return "";
020: }
021: try {
022: StringBuffer sb = new StringBuffer();
023: sb.append("\n").append(bean.getClass().getName()).append(
024: ":: ");
025: Method[] declaredGetters = retrieveDeclaredGetters(bean
026: .getClass());
027: if (declaredGetters == null || declaredGetters.length <= 0) {
028: return "";
029: }
030: for (int i = 0; i < declaredGetters.length; i++) {
031: sb.append(", ").append(
032: declaredGetters[i].getName().substring(3))
033: .append("=");
034: if (declaredGetters[i].getReturnType().isArray()) {
035: Object[] array = (Object[]) declaredGetters[i]
036: .invoke(bean, new Object[0]);
037: if (array == null) {
038: sb.append("null");
039: } else {
040: sb.append("[");
041: for (int j = 0; j < array.length; j++) {
042: sb.append(array[j]);
043: if (j < array.length - 1) {
044: sb.append(", ");
045: }
046: }
047: sb.append("]");
048: }
049: } else {
050: sb.append(declaredGetters[i].invoke(bean,
051: new Object[0]));
052: }
053: }
054: return sb.toString();
055: } catch (Exception ex) {
056: ex.printStackTrace();
057: return "";
058: }
059: }
060:
061: public static boolean equals(Object bean1, Object bean2) {
062: if (bean1 == null && bean2 == null) {
063: return true;
064: }
065: if ((bean1 != null && bean2 == null)
066: || (bean1 == null && bean2 != null)) {
067: return false;
068: }
069: if (!bean1.getClass().equals(bean2.getClass())) {
070: return false;
071: }
072: try {
073: Method[] declaredGetters = retrieveDeclaredGetters(bean1
074: .getClass());
075: if (declaredGetters == null || declaredGetters.length <= 0) {
076: return true;
077: }
078: for (int i = 0; i < declaredGetters.length; i++) {
079: if (declaredGetters[i].getReturnType().isArray()) {
080: Object[] array1 = (Object[]) declaredGetters[i]
081: .invoke(bean1, new Object[0]);
082: Object[] array2 = (Object[]) declaredGetters[i]
083: .invoke(bean2, new Object[0]);
084: if ((array1 == null && array2 != null)
085: || (array1 != null && array2 == null)
086: || ((array1 != null && array2 != null) && (array1.length != array2.length))) {
087: return false;
088: }
089: if (array1 == null && array2 == null) {
090: continue;
091: }
092: for (int j = 0; j < array1.length; j++) {
093: if ((array1[j] == null && array2[j] != null)
094: || (array1[j] != null && array2[j] == null)
095: || ((array1[j] != null && array2[j] != null) && (!array1[j]
096: .equals(array2[j])))) {
097: return false;
098: }
099: }
100: } else {
101: Object object1 = declaredGetters[i].invoke(bean1,
102: new Object[0]);
103: Object object2 = declaredGetters[i].invoke(bean2,
104: new Object[0]);
105: if ((object1 == null && object2 != null)
106: || (object1 != null && object2 == null)
107: || ((object1 != null && object2 != null) && (!object1
108: .equals(object2)))) {
109: return false;
110: }
111: }
112: }
113: return true;
114: } catch (Exception ex) {
115: ex.printStackTrace();
116: return false;
117: }
118: }
119:
120: public static void copyObject(Object source, Object destination)
121: throws ReflectionException {
122: try {
123: Field[] sourceFields = retrieveFields(source.getClass());
124: Map destinationFieldMap = retrieveFieldMap(destination
125: .getClass());
126: for (int i = 0; i < sourceFields.length; i++) {
127: Field sourceField = sourceFields[i];
128: LOG.trace("source field name: " + sourceField.getName()
129: + " and type: " + sourceField.getType());
130: Field destinationField = (Field) destinationFieldMap
131: .get(sourceField.getName());
132: if (destinationField == null) {
133: LOG
134: .trace("field '"
135: + sourceField.getName()
136: + "' not found in destination class ... continue");
137: continue;
138: }
139: LOG.trace("destination field name: "
140: + destinationField.getName() + " and type: "
141: + destinationField.getType());
142: Object sourceValue = source.getClass().getMethod(
143: retrieveGetterName(sourceField), new Class[0])
144: .invoke(source, new Object[0]);
145: LOG.trace("source value = " + sourceValue);
146: Object destinationValue = null;
147: if (destinationField.getType().isArray()
148: && sourceField.getType().isArray()) { //both are arrays
149: if (destinationField.getType().getComponentType()
150: .equals(
151: sourceField.getType()
152: .getComponentType())) {//same type: just copy
153: destinationValue = sourceValue;
154: } else { //different types: try to call the copy constructor of the setter type
155: Object[] destinationValues = (Object[]) Array
156: .newInstance(destinationField.getType()
157: .getComponentType(),
158: ((Object[]) sourceValue).length);
159: for (int j = 0; j < destinationValues.length; j++) {
160: destinationValues[j] = destinationField
161: .getType()
162: .getComponentType()
163: .getConstructor(
164: new Class[] { sourceField
165: .getType()
166: .getComponentType() })
167: .newInstance(
168: new Object[] { ((Object[]) sourceValue)[j] });
169: }
170: destinationValue = destinationValues;
171: }
172: } else if ((!destinationField.getType().isArray())
173: && (!sourceField.getType().isArray())) { //both are simple objects
174: if (destinationField.getType().equals(
175: sourceFields[i].getType())) { //same type: just copy
176: destinationValue = sourceValue;
177: } else { //different types: try to call the copy constructor of the setter type
178: destinationValue = destinationField.getType()
179: .getConstructor(
180: new Class[] { sourceField
181: .getType() })
182: .newInstance(
183: new Object[] { sourceValue });
184: }
185: } else { //one is an array and the other is a simple object: ERROR
186: throw new ReflectionException(
187: "one is an array and the other is a simple object");
188: }
189: Method destinationSetter = destination.getClass()
190: .getMethod(
191: retrieveSetterName(destinationField),
192: new Class[] { destinationField
193: .getType() });
194: destinationSetter.invoke(destination,
195: new Object[] { destinationValue });
196: }
197: } catch (InvocationTargetException ex) {
198: String msg = "Could not copy source to destination.";
199: LOG.error(msg, ex);
200: throw new ReflectionException(msg, ex);
201: } catch (IllegalAccessException ex) {
202: String msg = "Could not copy source to destination.";
203: LOG.error(msg, ex);
204: throw new ReflectionException(msg, ex);
205: } catch (NoSuchMethodException ex) {
206: String msg = "Could not copy source to destination.";
207: LOG.error(msg, ex);
208: throw new ReflectionException(msg, ex);
209: } catch (InstantiationException ex) {
210: String msg = "Could not copy source to destination.";
211: LOG.error(msg, ex);
212: throw new ReflectionException(msg, ex);
213: }
214: }
215:
216: public static String retrieveFieldName(String getterName) {
217: String fieldName = getterName.substring(3);
218: return fieldName.substring(0, 1).toLowerCase()
219: + fieldName.substring(1);
220: }
221:
222: private static Field[] retrieveFields(Class clazz) {
223: Field[] declaredFields = clazz.getDeclaredFields();
224: List fields = new ArrayList();
225: for (int i = 0; i < declaredFields.length; i++) {
226: Field declaredField = declaredFields[i];
227: int modifier = declaredField.getModifiers();
228: if (Modifier.isStatic(modifier))
229: continue;
230: if (!declaredField.getType().getName().equals(
231: "java.lang.Class")) {
232: fields.add(declaredField);
233: }
234: }
235: if (clazz.getSuperclass().getName().startsWith("org")) {
236: fields.addAll(new ArrayList(Arrays
237: .asList(retrieveFields(clazz.getSuperclass()))));
238: }
239: if (fields.size() == 0) {
240: return new Field[0];
241: }
242: return (Field[]) fields.toArray(new Field[fields.size()]);
243: }
244:
245: private static Map retrieveFieldMap(Class clazz) {
246: Field[] fields = retrieveFields(clazz);
247: Map fieldMap = new HashMap();
248: for (int i = 0; i < fields.length; i++) {
249: fieldMap.put(fields[i].getName(), fields[i]);
250: }
251: return fieldMap;
252: }
253:
254: private static String retrieveGetterName(Field field) {
255: return retrieveGetterName(field.getName());
256: }
257:
258: private static String retrieveGetterName(String fieldName) {
259: return "get" + fieldName.substring(0, 1).toUpperCase()
260: + fieldName.substring(1, fieldName.length());
261: }
262:
263: private static String retrieveSetterName(Field field) {
264: return retrieveSetterName(field.getName());
265: }
266:
267: private static String retrieveSetterName(String fieldName) {
268: return "set" + fieldName.substring(0, 1).toUpperCase()
269: + fieldName.substring(1, fieldName.length());
270: }
271:
272: private static Method[] retrieveDeclaredMethods(Class beanClass) {
273: if (beanClass == null || beanClass.equals(Object.class)) {
274: return new Method[0];
275: }
276: List declaredMethods = new LinkedList();
277: Method[] directDeclaredMethodes = beanClass
278: .getDeclaredMethods();
279: if (directDeclaredMethodes != null
280: && directDeclaredMethodes.length > 0) {
281: for (int i = 0; i < directDeclaredMethodes.length; i++) {
282: declaredMethods.add(directDeclaredMethodes[i]);
283: }
284: }
285: Method[] super ClassMethodes = retrieveDeclaredMethods(beanClass
286: .getSuperclass());
287: if (super ClassMethodes != null && super ClassMethodes.length > 0) {
288: for (int i = 0; i < super ClassMethodes.length; i++) {
289: declaredMethods.add(super ClassMethodes[i]);
290: }
291: }
292: if (declaredMethods.size() <= 0) {
293: return new Method[0];
294: }
295:
296: return (Method[]) declaredMethods
297: .toArray(new Method[declaredMethods.size()]);
298: }
299:
300: private static Method[] retrieveDeclaredGetters(Class beanClass) {
301: Method[] declaredMethodes = retrieveDeclaredMethods(beanClass);
302: if (declaredMethodes == null || declaredMethodes.length <= 0) {
303: return new Method[0];
304: }
305: List declaredGetters = new LinkedList();
306: for (int i = 0; i < declaredMethodes.length; i++) {
307: if ((declaredMethodes[i].getName().startsWith("get"))
308: && (declaredMethodes[i].getParameterTypes().length == 0)) {
309: declaredGetters.add(declaredMethodes[i]);
310: }
311: }
312: if (declaredGetters.size() <= 0) {
313: return new Method[0];
314: }
315:
316: return (Method[]) declaredGetters
317: .toArray(new Method[declaredGetters.size()]);
318: }
319:
320: }
|