KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > db4o > test > DeepCompare


1 /* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com
2
3 This file is part of the db4o open source object database.
4
5 db4o is free software; you can redistribute it and/or modify it under
6 the terms of version 2 of the GNU General Public License as published
7 by the Free Software Foundation and as clarified by db4objects' GPL
8 interpretation policy, available at
9 http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
10 Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
11 Suite 350, San Mateo, CA 94403, USA.
12
13 db4o is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

21 package com.db4o.test;
22 /*
23  * Author: Carl Rosenberger
24  *
25  * You may use this code in any way you wish, as
26  * long as you don't remove the following notice:
27  *
28  * Code written for:
29  * http://www.db4o.com
30  * http://sourceforge.net/projects/sodaquery
31  */

32 import java.lang.reflect.*;
33 import java.util.*;
34
35 import com.db4o.*;
36
37 public class DeepCompare {
38
39     public boolean isEqual(Object JavaDoc a_compare, Object JavaDoc a_with) {
40         return isEqual(a_compare, a_with, null, null);
41     }
42
43     public boolean isEqual(Object JavaDoc a_compare, Object JavaDoc a_with, String JavaDoc a_path, Stack a_stack) {
44         if (a_path == null || a_path.length() < 1) {
45             if (a_compare != null) {
46                 a_path = a_compare.getClass().getName() + ":";
47             } else {
48                 if (a_with != null) {
49                     a_path = a_with.getClass().getName() + ":";
50                 }
51             }
52         }
53
54         String JavaDoc path = a_path;
55
56         if (a_compare == null) {
57             return a_with == null;
58         }
59         if (a_with == null) {
60             return false;
61         }
62         Class JavaDoc clazz = a_compare.getClass();
63         if (clazz != a_with.getClass()) {
64             return false;
65         }
66
67         if (isSimple(clazz)) {
68             return a_compare.equals(a_with);
69         }
70
71         if (a_stack == null) {
72             a_stack = new Stack();
73         }
74
75         // takes care of repeating calls to the same object
76
if (a_stack.contains(a_compare)) {
77             return true;
78         }
79         a_stack.push(a_compare);
80
81         Field fields[] = clazz.getDeclaredFields();
82         for (int i = 0; i < fields.length; i++) {
83             if (storeableField(clazz, fields[i])) {
84                 Platform4.setAccessible(fields[i]);
85                 try {
86                     path = a_path + fields[i].getName() + ":";
87                     Object JavaDoc compare = fields[i].get(a_compare);
88                     Object JavaDoc with = fields[i].get(a_with);
89                     if (compare == null) {
90                         if (with != null) {
91                             return false;
92                         }
93                     } else if (with == null) {
94                         return false;
95                     } else {
96                         if (compare.getClass().isArray()) {
97                             if (!with.getClass().isArray()) {
98                                 return false;
99                             } else {
100                                 compare = normalizeNArray(compare);
101                                 with = normalizeNArray(with);
102                                 int len = Array.getLength(compare);
103                                 if (len != Array.getLength(with)) {
104                                     return false;
105                                 } else {
106                                     for (int j = 0; j < len; j++) {
107                                         Object JavaDoc elementCompare = Array.get(compare, j);
108                                         Object JavaDoc elementWith = Array.get(with, j);
109                                         // if (l_persistentArray)
110
if (!isEqual(elementCompare, elementWith, path, a_stack)) {
111                                             return false;
112                                         } else if (elementCompare == null) {
113                                             if (elementWith != null) {
114                                                 return false;
115                                             }
116                                         } else if (elementWith == null) {
117                                             return false;
118                                         } else {
119                                             Class JavaDoc elementCompareClass = elementCompare.getClass();
120                                             if (elementCompareClass != elementWith.getClass()) {
121                                                 return false;
122                                             }
123                                             if (hasPublicConstructor(elementCompareClass)) {
124                                                 if (!isEqual(elementCompare,
125                                                     elementWith,
126                                                     path,
127                                                     a_stack)) {
128                                                     return false;
129
130                                                 }
131                                             } else if (!elementCompare.equals(elementWith)) {
132                                                 return false;
133                                             }
134                                         }
135
136                                     }
137
138                                 }
139                             }
140                         } else if (hasPublicConstructor(fields[i].getType())) {
141                             if (!isEqual(compare, with, path, a_stack)) {
142                                 return false;
143                             }
144                         } else {
145                             if (!compare.equals(with)) {
146                                 return false;
147                             }
148                         }
149                     }
150                 } catch (IllegalAccessException JavaDoc ex) {
151                     // probably JDK 1
152
// never mind this field
153
return true;
154                 } catch (Exception JavaDoc e) {
155                     System.err.println("STCompare failure executing path:" + path);
156                     e.printStackTrace();
157                     return false;
158                 }
159             }
160         }
161         return true;
162     }
163
164     boolean hasPublicConstructor(Class JavaDoc a_class) {
165         if (a_class != String JavaDoc.class) {
166             try {
167                 return a_class.newInstance() != null;
168             } catch (Throwable JavaDoc t) {
169             }
170         }
171         return false;
172     }
173
174     Object JavaDoc normalizeNArray(Object JavaDoc a_object) {
175         if (Array.getLength(a_object) > 0) {
176             Object JavaDoc first = Array.get(a_object, 0);
177             if (first != null && first.getClass().isArray()) {
178                 int dim[] = arrayDimensions(a_object);
179                 Object JavaDoc all = new Object JavaDoc[arrayElementCount(dim)];
180                 normalizeNArray1(a_object, all, 0, dim, 0);
181                 return all;
182             }
183         }
184         return a_object;
185     }
186
187     int normalizeNArray1(Object JavaDoc a_object, Object JavaDoc a_all, int a_next, int a_dim[], int a_index) {
188         if (a_index == a_dim.length - 1) {
189             for (int i = 0; i < a_dim[a_index]; i++) {
190                 Array.set(a_all, a_next++, Array.get(a_object, i));
191             }
192         } else {
193             for (int i = 0; i < a_dim[a_index]; i++) {
194                 a_next =
195                     normalizeNArray1(Array.get(a_object, i), a_all, a_next, a_dim, a_index + 1);
196             }
197
198         }
199         return a_next;
200     }
201
202     int[] arrayDimensions(Object JavaDoc a_object) {
203         int count = 0;
204         for (Class JavaDoc clazz = a_object.getClass();
205             clazz.isArray();
206             clazz = clazz.getComponentType()) {
207             count++;
208         }
209         int dim[] = new int[count];
210         for (int i = 0; i < count; i++) {
211             dim[i] = Array.getLength(a_object);
212             a_object = Array.get(a_object, 0);
213         }
214         return dim;
215     }
216
217     int arrayElementCount(int a_dim[]) {
218         int elements = a_dim[0];
219         for (int i = 1; i < a_dim.length; i++) {
220             elements *= a_dim[i];
221         }
222         return elements;
223     }
224
225     public boolean storeableField(Class JavaDoc a_class, Field a_field) {
226         return (!Modifier.isStatic(a_field.getModifiers()))
227             && (!Modifier.isTransient(a_field.getModifiers())
228                 & !(a_field.getName().indexOf("$") > -1));
229     }
230
231     public static boolean isSimple(Class JavaDoc a_class) {
232         for (int i = 0; i < SIMPLE_CLASSES.length; i++) {
233             if (a_class == SIMPLE_CLASSES[i]) {
234                 return true;
235             }
236         }
237         return false;
238     }
239
240     private static final Class JavaDoc[] SIMPLE_CLASSES =
241         {
242             Integer JavaDoc.class,
243             Long JavaDoc.class,
244             Float JavaDoc.class,
245             Boolean JavaDoc.class,
246             Double JavaDoc.class,
247             Byte JavaDoc.class,
248             Character JavaDoc.class,
249             Short JavaDoc.class,
250             String JavaDoc.class,
251             java.util.Date JavaDoc.class };
252
253 }
254
Popular Tags