KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > corba > se > impl > orbutil > ObjectUtility


1 /*
2  * @(#)ORBUtility.java 1.32 02/08/13
3  *
4  * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.corba.se.impl.orbutil;
9
10 import java.security.PrivilegedAction JavaDoc;
11 import java.security.AccessController JavaDoc;
12 import java.util.ArrayList JavaDoc;
13 import java.util.Arrays JavaDoc;
14 import java.util.Map JavaDoc;
15 import java.util.List JavaDoc;
16 import java.util.ListIterator JavaDoc;
17 import java.util.Set JavaDoc;
18 import java.util.Map.Entry;
19 import java.util.Collection JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.HashSet JavaDoc;
22 import java.util.Hashtable JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.Enumeration JavaDoc;
25 import java.util.Properties JavaDoc;
26 import java.util.IdentityHashMap JavaDoc;
27 import java.lang.reflect.Array JavaDoc;
28 import java.lang.reflect.Field JavaDoc;
29 import java.lang.reflect.Method JavaDoc;
30 import java.lang.reflect.Modifier JavaDoc;
31 import java.math.BigInteger JavaDoc ;
32 import java.math.BigDecimal JavaDoc ;
33
34 public final class ObjectUtility {
35     private boolean useToString ;
36     private boolean isIndenting ;
37     private int initialLevel ;
38     private int increment ;
39     private ClassMap classToPrinter = new ClassMap() ;
40
41     private static ObjectUtility standard = new ObjectUtility( false, true,
42     0, 4 ) ;
43     private static ObjectUtility compact = new ObjectUtility( true, false,
44     0, 4 ) ;
45
46     private ObjectUtility( boolean useToString, boolean isIndenting,
47     int initialLevel, int increment )
48     {
49     this.useToString = useToString ;
50     this.isIndenting = isIndenting ;
51     this.initialLevel = initialLevel ;
52     this.increment = increment ;
53     classToPrinter.put( Properties JavaDoc.class, propertiesPrinter ) ;
54     classToPrinter.put( Collection JavaDoc.class, collectionPrinter ) ;
55     classToPrinter.put( Map JavaDoc.class, mapPrinter ) ;
56     }
57
58     /** Construct an Utility instance with the desired objectToString
59     * behavior.
60     */

61     public static ObjectUtility make( boolean useToString, boolean isIndenting,
62     int initialLevel, int increment )
63     {
64     return new ObjectUtility( useToString, isIndenting, initialLevel,
65         increment ) ;
66     }
67
68     /** Construct an Utility instance with the desired objectToString
69     * behavior.
70     */

71     public static ObjectUtility make( boolean useToString, boolean isIndenting )
72     {
73     return new ObjectUtility( useToString, isIndenting, 0, 4 ) ;
74     }
75
76     /** Get the standard Utility object that supports objectToString with
77     * indented display and no use of toString() methods.
78     */

79     public static ObjectUtility make()
80     {
81     return standard ;
82     }
83     
84     /** A convenience method that gives the default behavior: use indenting
85     * to display the object's structure and do not use built-in toString
86     * methods.
87     */

88     public static String JavaDoc defaultObjectToString( java.lang.Object JavaDoc object )
89     {
90     return standard.objectToString( object ) ;
91     }
92
93     public static String JavaDoc compactObjectToString( java.lang.Object JavaDoc object )
94     {
95     return compact.objectToString( object ) ;
96     }
97
98     /** objectToString handles display of arbitrary objects. It correctly
99     * handles objects whose elements form an arbitrary graph. It uses
100     * reflection to display the contents of any kind of object.
101     * An object's toString() method may optionally be used, but the default
102     * is to ignore all toString() methods except for those defined for
103     * primitive types, primitive type wrappers, and strings.
104     */

105     public String JavaDoc objectToString(java.lang.Object JavaDoc obj)
106     {
107     IdentityHashMap JavaDoc printed = new IdentityHashMap JavaDoc() ;
108     ObjectWriter result = ObjectWriter.make( isIndenting, initialLevel,
109         increment ) ;
110     objectToStringHelper( printed, result, obj ) ;
111     return result.toString() ;
112     }
113
114     // Perform a deep structural equality comparison of the two objects.
115
// This handles all arrays, maps, and sets specially, otherwise
116
// it just calls the object's equals() method.
117
public static boolean equals( java.lang.Object JavaDoc obj1, java.lang.Object JavaDoc obj2 )
118     {
119     // Set of pairs of objects that have been (or are being) considered for
120
// equality. Such pairs are presumed to be equals. If they are not,
121
// this will be detected eventually and the equals method will return
122
// false.
123
Set JavaDoc considered = new HashSet JavaDoc() ;
124
125     // Map that gives the corresponding component of obj2 for a component
126
// of obj1. This is used to check for the same aliasing and use of
127
// equal objects in both objects.
128
Map JavaDoc counterpart = new IdentityHashMap JavaDoc() ;
129
130     return equalsHelper( counterpart, considered, obj1, obj2 ) ;
131     }
132
133     /** If arr1 and arr2 are both arrays of the same component type,
134      * return an array of that component type that consists of the
135      * elements of arr1 followed by the elements of arr2.
136      * Throws IllegalArgumentException otherwise.
137      */

138     public static Object JavaDoc concatenateArrays( Object JavaDoc arr1, Object JavaDoc arr2 )
139     {
140     Class JavaDoc comp1 = arr1.getClass().getComponentType() ;
141     Class JavaDoc comp2 = arr2.getClass().getComponentType() ;
142     int len1 = Array.getLength( arr1 ) ;
143     int len2 = Array.getLength( arr2 ) ;
144
145     if ((comp1 == null) || (comp2 == null))
146         throw new IllegalStateException JavaDoc( "Arguments must be arrays" ) ;
147     if (!comp1.equals( comp2 ))
148         throw new IllegalStateException JavaDoc(
149         "Arguments must be arrays with the same component type" ) ;
150
151     Object JavaDoc result = Array.newInstance( comp1, len1 + len2 ) ;
152
153     int index = 0 ;
154
155     for (int ctr=0; ctr<len1; ctr++)
156         Array.set( result, index++, Array.get( arr1, ctr ) ) ;
157
158     for (int ctr=0; ctr<len2; ctr++)
159         Array.set( result, index++, Array.get( arr2, ctr ) ) ;
160
161     return result ;
162     }
163
164 //===========================================================================
165
// Implementation
166
//===========================================================================
167

168     private void objectToStringHelper( IdentityHashMap JavaDoc printed,
169     ObjectWriter result, java.lang.Object JavaDoc obj)
170     {
171     if (obj==null) {
172         result.append( "null" ) ;
173         result.endElement() ;
174     } else {
175         Class JavaDoc cls = obj.getClass() ;
176         result.startObject( obj ) ;
177
178         if (printed.keySet().contains( obj )) {
179         result.endObject( "*VISITED*" ) ;
180         } else {
181         printed.put( obj, null ) ;
182
183         if (mustUseToString(cls)) {
184             result.endObject( obj.toString() ) ;
185         } else {
186             // First, handle any classes that have special printer
187
// methods defined. This is useful when the class
188
// overrides toString with something that
189
// is not sufficiently detailed.
190
ObjectPrinter printer = (ObjectPrinter)(classToPrinter.get(
191             cls )) ;
192             if (printer != null) {
193             printer.print( printed, result, obj ) ;
194             result.endObject() ;
195             } else {
196             Class JavaDoc compClass = cls.getComponentType() ;
197
198             if (compClass == null)
199                 // handleObject always calls endObject
200
handleObject( printed, result, obj ) ;
201             else {
202                 handleArray( printed, result, obj ) ;
203                 result.endObject() ;
204             }
205             }
206         }
207         }
208     }
209     }
210
211     private static interface ObjectPrinter {
212     void print( IdentityHashMap JavaDoc printed, ObjectWriter buff,
213         java.lang.Object JavaDoc obj ) ;
214     }
215
216     private ObjectPrinter propertiesPrinter = new ObjectPrinter() {
217     public void print( IdentityHashMap JavaDoc printed, ObjectWriter buff,
218         java.lang.Object JavaDoc obj )
219     {
220         if (!(obj instanceof Properties JavaDoc))
221         throw new Error JavaDoc() ;
222
223         Properties JavaDoc props = (Properties JavaDoc)obj ;
224         Enumeration JavaDoc keys = props.propertyNames() ;
225         while (keys.hasMoreElements()) {
226         String JavaDoc key = (String JavaDoc)(keys.nextElement()) ;
227         String JavaDoc value = props.getProperty( key ) ;
228         buff.startElement() ;
229         buff.append( key ) ;
230         buff.append( "=" ) ;
231         buff.append( value ) ;
232         buff.endElement() ;
233         }
234     }
235     } ;
236
237     private ObjectPrinter collectionPrinter = new ObjectPrinter() {
238     public void print( IdentityHashMap JavaDoc printed, ObjectWriter buff,
239         java.lang.Object JavaDoc obj )
240     {
241         if (!(obj instanceof Collection JavaDoc))
242         throw new Error JavaDoc() ;
243         
244         Collection JavaDoc coll = (Collection JavaDoc)obj ;
245         Iterator JavaDoc iter = coll.iterator() ;
246         while (iter.hasNext()) {
247         java.lang.Object JavaDoc element = iter.next() ;
248         buff.startElement() ;
249         objectToStringHelper( printed, buff, element ) ;
250         buff.endElement() ;
251         }
252     }
253     } ;
254
255     private ObjectPrinter mapPrinter = new ObjectPrinter() {
256     public void print( IdentityHashMap JavaDoc printed, ObjectWriter buff,
257         java.lang.Object JavaDoc obj )
258     {
259         if (!(obj instanceof Map JavaDoc))
260         throw new Error JavaDoc() ;
261
262         Map JavaDoc map = (Map JavaDoc)obj ;
263         Iterator JavaDoc iter = map.entrySet().iterator() ;
264         while (iter.hasNext()) {
265         Entry entry = (Entry)(iter.next()) ;
266         buff.startElement() ;
267         objectToStringHelper( printed, buff, entry.getKey() ) ;
268         buff.append( "=>" ) ;
269         objectToStringHelper( printed, buff, entry.getValue() ) ;
270         buff.endElement() ;
271         }
272     }
273     } ;
274
275     private static class ClassMap {
276     ArrayList JavaDoc data ;
277
278     public ClassMap()
279     {
280         data = new ArrayList JavaDoc() ;
281     }
282
283     /** Return the first element of the ClassMap that is assignable to cls.
284     * The order is determined by the order in which the put method was
285     * called. Returns null if there is no match.
286     */

287     public java.lang.Object JavaDoc get( Class JavaDoc cls )
288     {
289         Iterator JavaDoc iter = data.iterator() ;
290         while (iter.hasNext()) {
291         java.lang.Object JavaDoc[] arr = (java.lang.Object JavaDoc[])(iter.next()) ;
292         Class JavaDoc key = (Class JavaDoc)(arr[0]) ;
293         if (key.isAssignableFrom( cls ))
294             return arr[1] ;
295         }
296
297         return null ;
298     }
299
300     /** Add obj to the map with key cls. Note that order matters,
301      * as the first match is returned.
302      */

303     public void put( Class JavaDoc cls, java.lang.Object JavaDoc obj )
304     {
305         java.lang.Object JavaDoc[] pair = { cls, obj } ;
306         data.add( pair ) ;
307     }
308     }
309
310     private boolean mustUseToString( Class JavaDoc cls )
311     {
312     // These probably never occur
313
if (cls.isPrimitive())
314         return true ;
315
316     // We must use toString for all primitive wrappers, since
317
// otherwise the code recurses endlessly (access value field
318
// inside Integer, returns another Integer through reflection).
319
if ((cls == Integer JavaDoc.class) ||
320         (cls == BigInteger JavaDoc.class) ||
321         (cls == BigDecimal JavaDoc.class) ||
322         (cls == String JavaDoc.class) ||
323         (cls == StringBuffer JavaDoc.class) ||
324         (cls == Long JavaDoc.class) ||
325         (cls == Short JavaDoc.class) ||
326         (cls == Byte JavaDoc.class) ||
327         (cls == Character JavaDoc.class) ||
328         (cls == Float JavaDoc.class) ||
329         (cls == Double JavaDoc.class) ||
330         (cls == Boolean JavaDoc.class))
331         return true ;
332
333     if (useToString) {
334         try {
335         cls.getDeclaredMethod( "toString", null ) ;
336         return true ;
337         } catch (Exception JavaDoc exc) {
338         return false ;
339         }
340     }
341
342     return false ;
343     }
344
345     private void handleObject( IdentityHashMap JavaDoc printed, ObjectWriter result,
346     java.lang.Object JavaDoc obj )
347     {
348     Class JavaDoc cls = obj.getClass() ;
349
350     try {
351         Field JavaDoc[] fields;
352         SecurityManager JavaDoc security = System.getSecurityManager();
353         if (security != null && !Modifier.isPublic(cls.getModifiers())) {
354         fields = new Field JavaDoc[0];
355         } else {
356             fields = sun.reflect.misc.FieldUtil.getDeclaredFields(cls);
357         }
358
359         for (int ctr=0; ctr<fields.length; ctr++ ) {
360         final Field JavaDoc fld = fields[ctr] ;
361         int modifiers = fld.getModifiers() ;
362
363         // Do not display field if it is static, since these fields
364
// are always the same for every instances. This could
365
// be made configurable, but I don't think it is
366
// useful to do so.
367
if (!Modifier.isStatic( modifiers )) {
368             if (security != null) {
369                 if (!Modifier.isPublic(modifiers))
370                 continue;
371             }
372             result.startElement() ;
373             result.append( fld.getName() ) ;
374             result.append( ":" ) ;
375
376             try {
377             // Make sure that we can read the field if it is
378
// not public
379
AccessController.doPrivileged( new PrivilegedAction JavaDoc() {
380                 public Object JavaDoc run() {
381                 fld.setAccessible( true ) ;
382                 return null ;
383                 }
384             } ) ;
385
386             java.lang.Object JavaDoc value = fld.get( obj ) ;
387             objectToStringHelper( printed, result, value ) ;
388             } catch (Exception JavaDoc exc2) {
389             result.append( "???" ) ;
390             }
391
392             result.endElement() ;
393         }
394         }
395
396         result.endObject() ;
397     } catch (Exception JavaDoc exc2) {
398         result.endObject( obj.toString() ) ;
399     }
400     }
401
402     private void handleArray( IdentityHashMap JavaDoc printed, ObjectWriter result,
403     java.lang.Object JavaDoc obj )
404     {
405     Class JavaDoc compClass = obj.getClass().getComponentType() ;
406     if (compClass == boolean.class) {
407         boolean[] arr = (boolean[])obj ;
408         for (int ctr=0; ctr<arr.length; ctr++) {
409         result.startElement() ;
410         result.append( arr[ctr] ) ;
411         result.endElement() ;
412         }
413     } else if (compClass == byte.class) {
414         byte[] arr = (byte[])obj ;
415         for (int ctr=0; ctr<arr.length; ctr++) {
416         result.startElement() ;
417         result.append( arr[ctr] ) ;
418         result.endElement() ;
419         }
420     } else if (compClass == short.class) {
421         short[] arr = (short[])obj ;
422         for (int ctr=0; ctr<arr.length; ctr++) {
423         result.startElement() ;
424         result.append( arr[ctr] ) ;
425         result.endElement() ;
426         }
427     } else if (compClass == int.class) {
428         int[] arr = (int[])obj ;
429         for (int ctr=0; ctr<arr.length; ctr++) {
430         result.startElement() ;
431         result.append( arr[ctr] ) ;
432         result.endElement() ;
433         }
434     } else if (compClass == long.class) {
435         long[] arr = (long[])obj ;
436         for (int ctr=0; ctr<arr.length; ctr++) {
437         result.startElement() ;
438         result.append( arr[ctr] ) ;
439         result.endElement() ;
440         }
441     } else if (compClass == char.class) {
442         char[] arr = (char[])obj ;
443         for (int ctr=0; ctr<arr.length; ctr++) {
444         result.startElement() ;
445         result.append( arr[ctr] ) ;
446         result.endElement() ;
447         }
448     } else if (compClass == float.class) {
449         float[] arr = (float[])obj ;
450         for (int ctr=0; ctr<arr.length; ctr++) {
451         result.startElement() ;
452         result.append( arr[ctr] ) ;
453         result.endElement() ;
454         }
455     } else if (compClass == double.class) {
456         double[] arr = (double[])obj ;
457         for (int ctr=0; ctr<arr.length; ctr++) {
458         result.startElement() ;
459         result.append( arr[ctr] ) ;
460         result.endElement() ;
461         }
462     } else { // array of object
463
java.lang.Object JavaDoc[] arr = (java.lang.Object JavaDoc[])obj ;
464         for (int ctr=0; ctr<arr.length; ctr++) {
465         result.startElement() ;
466         objectToStringHelper( printed, result, arr[ctr] ) ;
467         result.endElement() ;
468         }
469     }
470     }
471
472     private static class Pair
473     {
474     private java.lang.Object JavaDoc obj1 ;
475     private java.lang.Object JavaDoc obj2 ;
476
477     Pair( java.lang.Object JavaDoc obj1, java.lang.Object JavaDoc obj2 )
478     {
479         this.obj1 = obj1 ;
480         this.obj2 = obj2 ;
481     }
482
483     public boolean equals( java.lang.Object JavaDoc obj )
484     {
485         if (!(obj instanceof Pair))
486         return false ;
487
488         Pair other = (Pair)obj ;
489         return other.obj1 == obj1 && other.obj2 == obj2 ;
490     }
491
492     public int hashCode()
493     {
494         return System.identityHashCode( obj1 ) ^
495         System.identityHashCode( obj2 ) ;
496     }
497     }
498
499     private static boolean equalsHelper( Map JavaDoc counterpart, Set JavaDoc considered,
500     java.lang.Object JavaDoc obj1, java.lang.Object JavaDoc obj2 )
501     {
502     if ((obj1 == null) || (obj2 == null))
503         return obj1 == obj2 ;
504
505     java.lang.Object JavaDoc other2 = counterpart.get( obj1 ) ;
506     if (other2 == null) {
507         other2 = obj2 ;
508         counterpart.put( obj1, other2 ) ;
509     }
510
511     if (obj1 == other2)
512         return true ;
513
514     if (obj2 != other2)
515         return false ;
516     
517     Pair pair = new Pair( obj1, obj2 ) ;
518     if (considered.contains( pair ))
519         return true ;
520     else
521         considered.add( pair ) ;
522
523     if (obj1 instanceof java.lang.Object JavaDoc[] &&
524         obj2 instanceof java.lang.Object JavaDoc[])
525         return equalArrays( counterpart, considered,
526         (java.lang.Object JavaDoc[])obj1, (java.lang.Object JavaDoc[])obj2 ) ;
527     else if (obj1 instanceof Map JavaDoc && obj2 instanceof Map JavaDoc)
528         return equalMaps( counterpart, considered,
529         (Map JavaDoc)obj1, (Map JavaDoc)obj2 ) ;
530     else if (obj1 instanceof Set JavaDoc && obj2 instanceof Set JavaDoc)
531         return equalSets( counterpart, considered,
532         (Set JavaDoc)obj1, (Set JavaDoc)obj2 ) ;
533     else if (obj1 instanceof List JavaDoc && obj2 instanceof List JavaDoc)
534         return equalLists( counterpart, considered,
535         (List JavaDoc)obj1, (List JavaDoc)obj2 ) ;
536     else if (obj1 instanceof boolean[] && obj2 instanceof boolean[])
537         return Arrays.equals( (boolean[])obj1, (boolean[])obj2 ) ;
538     else if (obj1 instanceof byte[] && obj2 instanceof byte[])
539         return Arrays.equals( (byte[])obj1, (byte[])obj2 ) ;
540     else if (obj1 instanceof char[] && obj2 instanceof char[])
541         return Arrays.equals( (char[])obj1, (char[])obj2 ) ;
542     else if (obj1 instanceof double[] && obj2 instanceof double[])
543         return Arrays.equals( (double[])obj1, (double[])obj2 ) ;
544     else if (obj1 instanceof float[] && obj2 instanceof float[])
545         return Arrays.equals( (float[])obj1, (float[])obj2 ) ;
546     else if (obj1 instanceof int[] && obj2 instanceof int[])
547         return Arrays.equals( (int[])obj1, (int[])obj2 ) ;
548     else if (obj1 instanceof long[] && obj2 instanceof long[])
549         return Arrays.equals( (long[])obj1, (long[])obj2 ) ;
550     else {
551         Class JavaDoc cls = obj1.getClass() ;
552         if (cls != obj2.getClass())
553         return obj1.equals( obj2 ) ;
554         else
555         return equalsObject( counterpart, considered, cls, obj1, obj2 ) ;
556     }
557     }
558
559     private static boolean equalsObject( Map JavaDoc counterpart, Set JavaDoc considered,
560     Class JavaDoc cls, java.lang.Object JavaDoc obj1, java.lang.Object JavaDoc obj2 )
561     {
562     Class JavaDoc objectClass = java.lang.Object JavaDoc.class ;
563     if (cls == objectClass)
564         return true ;
565
566     Class JavaDoc[] equalsTypes = { objectClass } ;
567     try {
568         Method JavaDoc equalsMethod = cls.getDeclaredMethod( "equals",
569         equalsTypes ) ;
570         return obj1.equals( obj2 ) ;
571     } catch (Exception JavaDoc exc) {
572         if (equalsObjectFields( counterpart, considered,
573             cls, obj1, obj2 ))
574         return equalsObject( counterpart, considered,
575             cls.getSuperclass(), obj1, obj2 ) ;
576         else
577         return false ;
578     }
579     }
580
581     private static boolean equalsObjectFields( Map JavaDoc counterpart, Set JavaDoc considered,
582     Class JavaDoc cls, java.lang.Object JavaDoc obj1, java.lang.Object JavaDoc obj2 )
583     {
584     Field JavaDoc[] fields = cls.getDeclaredFields() ;
585     for (int ctr=0; ctr<fields.length; ctr++) {
586         try {
587         final Field JavaDoc field = fields[ctr] ;
588         // Ignore static fields
589
if (!Modifier.isStatic( field.getModifiers())) {
590             AccessController.doPrivileged(new PrivilegedAction JavaDoc() {
591             public Object JavaDoc run() {
592                 field.setAccessible( true ) ;
593                 return null ;
594             }
595             } ) ;
596
597             java.lang.Object JavaDoc value1 = field.get( obj1 ) ;
598             java.lang.Object JavaDoc value2 = field.get( obj2 ) ;
599             if (!equalsHelper( counterpart, considered, value1,
600             value2 ))
601             return false ;
602         }
603         } catch (IllegalAccessException JavaDoc exc) {
604         return false ;
605         }
606     }
607
608     return true ;
609     }
610
611     private static boolean equalArrays( Map JavaDoc counterpart, Set JavaDoc considered,
612     java.lang.Object JavaDoc[] arr1, java.lang.Object JavaDoc[] arr2 )
613     {
614     int len = arr1.length ;
615     if (len != arr2.length)
616         return false ;
617
618     for (int ctr = 0; ctr<len; ctr++ )
619         if (!equalsHelper( counterpart, considered, arr1[ctr], arr2[ctr] ))
620         return false ;
621
622     return true ;
623     }
624
625     private static boolean equalMaps( Map JavaDoc counterpart, Set JavaDoc considered,
626     Map JavaDoc map1, Map JavaDoc map2 )
627     {
628     if (map2.size() != map1.size())
629         return false;
630
631         try {
632             Iterator JavaDoc i = map1.entrySet().iterator();
633             while (i.hasNext()) {
634                 Entry e = (Entry) i.next();
635                 java.lang.Object JavaDoc key = e.getKey();
636                 java.lang.Object JavaDoc value = e.getValue();
637                 if (value == null) {
638                     if (!(map2.get(key)==null && map2.containsKey(key)))
639                         return false;
640                 } else {
641                     if (!equalsHelper( counterpart, considered,
642             value, map2.get(key)))
643                         return false;
644                 }
645             }
646         } catch(ClassCastException JavaDoc unused) {
647             return false;
648         } catch(NullPointerException JavaDoc unused) {
649             return false;
650         }
651
652     return true;
653     }
654
655     // Obviously this is an inefficient quadratic algorithm.
656
// This is taken pretty directly from AbstractSet and AbstractCollection
657
// in the JDK.
658
// For HashSet, an O(n) (with a good hash function) algorithm
659
// is possible, and likewise TreeSet, since it is
660
// ordered, is O(n). But this is not worth the effort here.
661
// Note that the inner loop uses equals, not equalsHelper.
662
// This is needed because of the searching behavior of this test.
663
// However, note that this will NOT correctly handle sets that
664
// contain themselves as members, or that have members that reference
665
// themselves. These cases will cause infinite regress!
666
private static boolean equalSets( Map JavaDoc counterpart, Set JavaDoc considered,
667     Set JavaDoc set1, Set JavaDoc set2 )
668     {
669     if (set1.size() != set2.size())
670         return false ;
671
672     Iterator JavaDoc e1 = set1.iterator() ;
673     while (e1.hasNext()) {
674         java.lang.Object JavaDoc obj1 = e1.next() ;
675
676         boolean found = false ;
677         Iterator JavaDoc e2 = set2.iterator() ;
678         while (e2.hasNext() && !found) {
679         java.lang.Object JavaDoc obj2 = e2.next() ;
680         found = equals( obj1, obj2 ) ;
681         }
682
683         if (!found)
684         return false ;
685     }
686
687     return true ;
688     }
689
690     private static boolean equalLists( Map JavaDoc counterpart, Set JavaDoc considered,
691     List JavaDoc list1, List JavaDoc list2 )
692     {
693     ListIterator JavaDoc e1 = list1.listIterator();
694     ListIterator JavaDoc e2 = list2.listIterator();
695     while(e1.hasNext() && e2.hasNext()) {
696         java.lang.Object JavaDoc o1 = e1.next();
697         java.lang.Object JavaDoc o2 = e2.next();
698         if (!(o1==null ? o2==null : equalsHelper(
699         counterpart, considered, o1, o2)))
700         return false;
701     }
702     return !(e1.hasNext() || e2.hasNext());
703     }
704 }
705
Popular Tags