1 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 ; 11 import java.lang.reflect.InvocationTargetException ; 12 import java.lang.reflect.Method ; 13 import java.util.ArrayList ; 14 import java.util.List ; 15 16 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 where) throws NotEqualException { 35 Assert.assertNotNull(where); 36 37 if ((one == null) != (two == null)) { 38 throw new NotEqualException(where + ": Objects are not both null or not both non-null."); 40 } 41 42 if (one == null) return; 43 44 Class oneInterface = getBeanInterface(one); 45 Class twoInterface = getBeanInterface(two); 46 47 if (!oneInterface.equals(twoInterface)) { 48 throw new NotEqualException(where + ": Bean interface for " + one + " is " + oneInterface 50 + ", and bean interface for two is " + twoInterface + "."); 51 } 52 53 Method [] methods = fetchAndFilterMethods(oneInterface); 54 Assert.eval(methods.length > 0); 55 56 for (int i = 0; i < methods.length; ++i) { 57 Method method = methods[i]; 58 59 String thisWhere = where + "/" + getPropertyFromMethodName(method.getName()); 60 61 try { 62 Object oneValue = method.invoke(one, null); 63 Object twoValue = method.invoke(two, null); 64 65 compareValues(thisWhere, oneValue, twoValue); 66 } catch (IllegalArgumentException iae) { 67 throw Assert.failure(thisWhere + ": Unable to fetch property from a bean; method " + method + " failed.", iae); 68 } catch (IllegalAccessException iae) { 69 throw Assert.failure(thisWhere + ": Unable to fetch property from a bean; method " + method + " failed.", iae); 70 } catch (InvocationTargetException 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 thisWhere, Object oneValue, Object twoValue) throws NotEqualException { 77 if ((oneValue == null) != (twoValue == null)) { 78 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 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 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 getPropertyFromMethodName(String 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 getBeanInterface(Object value) { 121 Class [] interfaces = value.getClass().getInterfaces(); 122 123 if (interfaces.length != 1) { 124 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 [] fetchAndFilterMethods(Class theClass) { 132 Method [] allMethods = theClass.getDeclaredMethods(); 133 List out = new ArrayList (); 134 135 for (int i = 0; i < allMethods.length; ++i) { 136 Method method = allMethods[i]; 137 138 if (method.getParameterTypes().length == 0 && method.getName().startsWith("get")) out.add(method); 139 } 140 141 return (Method []) out.toArray(new Method [out.size()]); 142 } 143 144 } 145 | Popular Tags |