001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package com.db4o.test;
022:
023: import java.lang.reflect.*;
024:
025: import com.db4o.foundation.*;
026: import com.db4o.internal.*;
027:
028: public class Compare {
029:
030: static boolean hasPublicConstructor(Class a_class) {
031: if (a_class == null || a_class == String.class) {
032: return false;
033: }
034: try {
035: Object o = a_class.newInstance();
036: if (o != null)
037: return true;
038: } catch (Throwable t) {
039: }
040: return false;
041: }
042:
043: static boolean isPrimitiveOrPrimitiveWrapper(Class clazz) {
044: if (clazz.isPrimitive()) {
045: return true;
046: }
047: return Platform4.isSimple(clazz);
048: }
049:
050: static Object normalizeNArray(Object a_object) {
051: if (Array.getLength(a_object) > 0) {
052: Object first = Array.get(a_object, 0);
053: if (first != null && first.getClass().isArray()) {
054: int dim[] = arrayDimensions(a_object);
055: Object all = new Object[arrayElementCount(dim)];
056: normalizeNArray1(a_object, all, 0, dim, 0);
057: return all;
058: }
059: }
060: return a_object;
061: }
062:
063: public static void compare(com.db4o.ObjectContainer a_con,
064: Object a_Compare, Object a_With, String a_path,
065: Collection4 a_list) {
066: if (!Regression.DEACTIVATE) {
067: a_con.activate(a_With, 1);
068: }
069:
070: if (a_list == null) {
071: a_list = new Collection4();
072: }
073: // takes care of repeating calls to the same object
074: if (a_list.containsByIdentity(a_Compare)) {
075: return;
076: }
077:
078: a_list.add(a_Compare);
079:
080: if (a_path == null || a_path.length() < 1)
081: if (a_Compare != null) {
082: a_path = a_Compare.getClass().getName() + ":";
083: } else {
084: if (a_With != null)
085: a_path = a_With.getClass().getName() + ":";
086: }
087: String path = a_path;
088: if (a_Compare == null) {
089: if (a_With == null) {
090: return;
091: }
092: Regression.addError("1==null:" + path);
093: return;
094: }
095: if (a_With == null) {
096: Regression.addError("2==null:" + path);
097: return;
098: }
099: Class compareClass = a_Compare.getClass();
100: if (!compareClass.isInstance(a_With)) {
101: Regression.addError("class!=:" + path
102: + compareClass.getName() + ":"
103: + a_With.getClass().getName());
104: return;
105: }
106: if (isPrimitiveOrPrimitiveWrapper(compareClass)) {
107: if (a_Compare.equals(a_With)) {
108: return;
109: }
110: Regression.addError("class!=:" + path
111: + compareClass.getName() + ":"
112: + a_With.getClass().getName());
113: return;
114: }
115:
116: Field l_Fields[] = compareClass.getDeclaredFields();
117: for (int i = 0; i < l_Fields.length; i++) {
118: if (storeableField(compareClass, l_Fields[i])) {
119: Platform4.setAccessible(l_Fields[i]);
120: try {
121: path = a_path + l_Fields[i].getName() + ":";
122: Object l_Compare = l_Fields[i].get(a_Compare);
123: Object l_With = l_Fields[i].get(a_With);
124: if (l_Compare == null) {
125: if (l_With != null) {
126: Regression.addError("f1==null:" + path);
127: }
128: } else if (l_With == null)
129: Regression.addError("f2==null:" + path);
130: else if (l_Compare.getClass().isArray()) {
131: if (!l_With.getClass().isArray()) {
132: Regression.addError("f2!=array:" + path);
133: } else {
134: l_Compare = normalizeNArray(l_Compare);
135: l_With = normalizeNArray(l_With);
136: int l_len = Array.getLength(l_Compare);
137: if (l_len != Array.getLength(l_With)) {
138: Regression.addError("arraylen!=:"
139: + path);
140: } else {
141: Class fieldClass = l_Fields[i]
142: .getType().getComponentType();
143: boolean l_persistentArray = hasPublicConstructor(fieldClass)
144: || isPrimitiveOrPrimitiveWrapper(fieldClass);
145: for (int j = 0; j < l_len; j++) {
146: Object l_ElementCompare = Array
147: .get(l_Compare, j);
148: Object l_ElementWith = Array.get(
149: l_With, j);
150: if (l_persistentArray) {
151: compare(a_con,
152: l_ElementCompare,
153: l_ElementWith, path,
154: a_list);
155: } else if (l_ElementCompare == null) {
156: if (l_ElementWith != null) {
157: Regression.addError("1e"
158: + j + "==null:"
159: + path);
160: }
161: } else if (l_ElementWith == null) {
162: Regression.addError("2e" + j
163: + "==null:" + path);
164: } else {
165: Class elementCompareClass = l_ElementCompare
166: .getClass();
167: if (elementCompareClass != l_ElementWith
168: .getClass()) {
169: Regression
170: .addError("e"
171: + j
172: + "!=class:"
173: + path
174: + elementCompareClass
175: .toString()
176: + ":"
177: + l_ElementWith
178: .getClass()
179: .toString());
180: } else if (hasPublicConstructor(elementCompareClass)) {
181: compare(a_con,
182: l_ElementCompare,
183: l_ElementWith,
184: path, a_list);
185: } else {
186: if (!l_ElementCompare
187: .equals(l_ElementWith))
188: Regression
189: .addError("e"
190: + j
191: + "!=:"
192: + path
193: + l_ElementCompare
194: .toString()
195: + ":"
196: + l_ElementWith
197: .toString());
198: }
199: }
200: }
201:
202: }
203: }
204: } else if (hasPublicConstructor(l_Fields[i]
205: .getType()))
206: compare(a_con, l_Compare, l_With, path, a_list);
207: else if (!l_Compare.equals(l_With))
208: Regression.addError("!=:" + path);
209: } catch (Exception e) {
210: Regression.addError("Exception:" + path);
211: }
212: }
213: }
214: }
215:
216: static int[] arrayDimensions(Object a_object) {
217: int count = 0;
218: for (Class clazz = a_object.getClass(); clazz.isArray(); clazz = clazz
219: .getComponentType())
220: count++;
221:
222: int dim[] = new int[count];
223: for (int i = 0; i < count; i++) {
224: dim[i] = Array.getLength(a_object);
225: a_object = Array.get(a_object, 0);
226: }
227:
228: return dim;
229: }
230:
231: static int normalizeNArray1(Object a_object, Object a_all,
232: int a_next, int a_dim[], int a_index) {
233: if (a_index == a_dim.length - 1) {
234: for (int i = 0; i < a_dim[a_index]; i++)
235: Array.set(a_all, a_next++, Array.get(a_object, i));
236:
237: } else {
238: for (int i = 0; i < a_dim[a_index]; i++)
239: a_next = normalizeNArray1(Array.get(a_object, i),
240: a_all, a_next, a_dim, a_index + 1);
241:
242: }
243: return a_next;
244: }
245:
246: static int arrayElementCount(int a_dim[]) {
247: int elements = a_dim[0];
248: for (int i = 1; i < a_dim.length; i++)
249: elements *= a_dim[i];
250:
251: return elements;
252: }
253:
254: static String nl() {
255: return System.getProperty("line.separator");
256: }
257:
258: public static boolean storeableField(Class a_class, Field a_field) {
259: return (!Modifier.isStatic(a_field.getModifiers()))
260: && (!Modifier.isTransient(a_field.getModifiers()) & !(a_field
261: .getName().indexOf("$") > -1));
262: }
263:
264: }
|