KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > config > schema > utils > StandardXmlObjectComparator


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.config.schema.utils;
5
6 import org.apache.xmlbeans.XmlObject;
7
8 import com.tc.util.Assert;
9
10 import java.lang.reflect.Array JavaDoc;
11 import java.lang.reflect.InvocationTargetException JavaDoc;
12 import java.lang.reflect.Method JavaDoc;
13 import java.util.ArrayList JavaDoc;
14 import java.util.List JavaDoc;
15
16 /**
17  * The standard implementation of {@link XmlObjectComparator}.
18  */

19 public class StandardXmlObjectComparator implements XmlObjectComparator {
20
21   public boolean equals(XmlObject one, XmlObject two) {
22     try {
23       checkEquals(one, two);
24       return true;
25     } catch (NotEqualException nee) {
26       return false;
27     }
28   }
29
30   public void checkEquals(XmlObject one, XmlObject two) throws NotEqualException {
31     checkEquals(one, two, "");
32   }
33
34   private void checkEquals(XmlObject one, XmlObject two, String JavaDoc where) throws NotEqualException {
35     Assert.assertNotNull(where);
36
37     if ((one == null) != (two == null)) {
38       // formatting
39
throw new NotEqualException(where + ": Objects are not both null or not both non-null.");
40     }
41
42     if (one == null) return;
43
44     Class JavaDoc oneInterface = getBeanInterface(one);
45     Class JavaDoc twoInterface = getBeanInterface(two);
46
47     if (!oneInterface.equals(twoInterface)) {
48       // formatting
49
throw new NotEqualException(where + ": Bean interface for " + one + " is " + oneInterface
50                                   + ", and bean interface for two is " + twoInterface + ".");
51     }
52
53     Method JavaDoc[] methods = fetchAndFilterMethods(oneInterface);
54     Assert.eval(methods.length > 0);
55
56     for (int i = 0; i < methods.length; ++i) {
57       Method JavaDoc method = methods[i];
58
59       String JavaDoc thisWhere = where + "/" + getPropertyFromMethodName(method.getName());
60
61       try {
62         Object JavaDoc oneValue = method.invoke(one, null);
63         Object JavaDoc twoValue = method.invoke(two, null);
64
65         compareValues(thisWhere, oneValue, twoValue);
66       } catch (IllegalArgumentException JavaDoc iae) {
67         throw Assert.failure(thisWhere + ": Unable to fetch property from a bean; method " + method + " failed.", iae);
68       } catch (IllegalAccessException JavaDoc iae) {
69         throw Assert.failure(thisWhere + ": Unable to fetch property from a bean; method " + method + " failed.", iae);
70       } catch (InvocationTargetException JavaDoc ite) {
71         throw Assert.failure(thisWhere + ": Unable to fetch property from a bean; method " + method + " failed.", ite);
72       }
73     }
74   }
75
76   private void compareValues(String JavaDoc thisWhere, Object JavaDoc oneValue, Object JavaDoc twoValue) throws NotEqualException {
77     if ((oneValue == null) != (twoValue == null)) {
78       // formatting
79
throw new NotEqualException(thisWhere + ": First value " + (oneValue == null ? "is" : "isn't") + " null, "
80                                   + "but second value " + (twoValue == null ? "is" : "isn't."));
81     }
82
83     if (oneValue != null) {
84       if ((oneValue instanceof XmlObject) && (twoValue instanceof XmlObject)) {
85         checkEquals((XmlObject) oneValue, (XmlObject) twoValue, thisWhere);
86       } else if ((oneValue instanceof XmlObject) || (twoValue instanceof XmlObject)) {
87         throw new NotEqualException(thisWhere + ": One value is an XmlObject and the other isn't; value one is "
88                                     + oneValue + ", and value two is " + twoValue);
89       } else if (oneValue.getClass().isArray() && twoValue.getClass().isArray()) {
90         if (Array.getLength(oneValue) != Array.getLength(twoValue)) {
91           // formatting
92
throw new NotEqualException(thisWhere + ": Value one is an array of length " + Array.getLength(oneValue)
93                                       + ", and value two " + "is an array of length " + Array.getLength(twoValue));
94         }
95
96         int length = Array.getLength(oneValue);
97         for (int j = 0; j < length; ++j) {
98           compareValues(thisWhere + "[" + j + "]", Array.get(oneValue, j), Array.get(twoValue, j));
99         }
100       } else {
101         if (!oneValue.equals(twoValue)) {
102           // formatting
103
throw new NotEqualException(
104                                       thisWhere
105                                           + ": Neither value is an XmlObject, and Object.equals() didn't return true; value one is '"
106                                           + oneValue + "', and value two is '" + twoValue + "'.");
107         }
108       }
109     }
110   }
111
112   private static String JavaDoc getPropertyFromMethodName(String JavaDoc methodName) {
113     Assert.assertNotBlank(methodName);
114     Assert.eval(methodName.length() >= "get".length());
115
116     return methodName.substring("get".length(), "get".length() + 1).toLowerCase()
117            + methodName.substring("get".length() + 1);
118   }
119
120   private static Class JavaDoc getBeanInterface(Object JavaDoc value) {
121     Class JavaDoc[] interfaces = value.getClass().getInterfaces();
122
123     if (interfaces.length != 1) {
124       // formatting
125
throw Assert.failure("Class " + value.getClass() + ", the class of object " + value + ", implements "
126                            + interfaces.length + " interfaces, not 1. We don't support this yet.");
127     }
128     return interfaces[0];
129   }
130
131   private static Method JavaDoc[] fetchAndFilterMethods(Class JavaDoc theClass) {
132     Method JavaDoc[] allMethods = theClass.getDeclaredMethods();
133     List JavaDoc out = new ArrayList JavaDoc();
134
135     for (int i = 0; i < allMethods.length; ++i) {
136       Method JavaDoc method = allMethods[i];
137
138       if (method.getParameterTypes().length == 0 && method.getName().startsWith("get")) out.add(method);
139     }
140
141     return (Method JavaDoc[]) out.toArray(new Method JavaDoc[out.size()]);
142   }
143
144 }
145
Popular Tags