1.1 --- a/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectUtility.java Fri Sep 24 16:38:05 2010 -0700 1.2 +++ b/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectUtility.java Fri Sep 24 22:42:14 2010 -0700 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -50,103 +50,8 @@ 1.11 import java.math.BigDecimal ; 1.12 1.13 public final class ObjectUtility { 1.14 - private boolean useToString ; 1.15 - private boolean isIndenting ; 1.16 - private int initialLevel ; 1.17 - private int increment ; 1.18 - private ClassMap classToPrinter = new ClassMap() ; 1.19 + private ObjectUtility() {} 1.20 1.21 - private static ObjectUtility standard = new ObjectUtility( false, true, 1.22 - 0, 4 ) ; 1.23 - private static ObjectUtility compact = new ObjectUtility( true, false, 1.24 - 0, 4 ) ; 1.25 - 1.26 - private ObjectUtility( boolean useToString, boolean isIndenting, 1.27 - int initialLevel, int increment ) 1.28 - { 1.29 - this.useToString = useToString ; 1.30 - this.isIndenting = isIndenting ; 1.31 - this.initialLevel = initialLevel ; 1.32 - this.increment = increment ; 1.33 - classToPrinter.put( Properties.class, propertiesPrinter ) ; 1.34 - classToPrinter.put( Collection.class, collectionPrinter ) ; 1.35 - classToPrinter.put( Map.class, mapPrinter ) ; 1.36 - } 1.37 - 1.38 - /** Construct an Utility instance with the desired objectToString 1.39 - * behavior. 1.40 - */ 1.41 - public static ObjectUtility make( boolean useToString, boolean isIndenting, 1.42 - int initialLevel, int increment ) 1.43 - { 1.44 - return new ObjectUtility( useToString, isIndenting, initialLevel, 1.45 - increment ) ; 1.46 - } 1.47 - 1.48 - /** Construct an Utility instance with the desired objectToString 1.49 - * behavior. 1.50 - */ 1.51 - public static ObjectUtility make( boolean useToString, boolean isIndenting ) 1.52 - { 1.53 - return new ObjectUtility( useToString, isIndenting, 0, 4 ) ; 1.54 - } 1.55 - 1.56 - /** Get the standard Utility object that supports objectToString with 1.57 - * indented display and no use of toString() methods. 1.58 - */ 1.59 - public static ObjectUtility make() 1.60 - { 1.61 - return standard ; 1.62 - } 1.63 - 1.64 - /** A convenience method that gives the default behavior: use indenting 1.65 - * to display the object's structure and do not use built-in toString 1.66 - * methods. 1.67 - */ 1.68 - public static String defaultObjectToString( java.lang.Object object ) 1.69 - { 1.70 - return standard.objectToString( object ) ; 1.71 - } 1.72 - 1.73 - public static String compactObjectToString( java.lang.Object object ) 1.74 - { 1.75 - return compact.objectToString( object ) ; 1.76 - } 1.77 - 1.78 - /** objectToString handles display of arbitrary objects. It correctly 1.79 - * handles objects whose elements form an arbitrary graph. It uses 1.80 - * reflection to display the contents of any kind of object. 1.81 - * An object's toString() method may optionally be used, but the default 1.82 - * is to ignore all toString() methods except for those defined for 1.83 - * primitive types, primitive type wrappers, and strings. 1.84 - */ 1.85 - public String objectToString(java.lang.Object obj) 1.86 - { 1.87 - IdentityHashMap printed = new IdentityHashMap() ; 1.88 - ObjectWriter result = ObjectWriter.make( isIndenting, initialLevel, 1.89 - increment ) ; 1.90 - objectToStringHelper( printed, result, obj ) ; 1.91 - return result.toString() ; 1.92 - } 1.93 - 1.94 - // Perform a deep structural equality comparison of the two objects. 1.95 - // This handles all arrays, maps, and sets specially, otherwise 1.96 - // it just calls the object's equals() method. 1.97 - public static boolean equals( java.lang.Object obj1, java.lang.Object obj2 ) 1.98 - { 1.99 - // Set of pairs of objects that have been (or are being) considered for 1.100 - // equality. Such pairs are presumed to be equals. If they are not, 1.101 - // this will be detected eventually and the equals method will return 1.102 - // false. 1.103 - Set considered = new HashSet() ; 1.104 - 1.105 - // Map that gives the corresponding component of obj2 for a component 1.106 - // of obj1. This is used to check for the same aliasing and use of 1.107 - // equal objects in both objects. 1.108 - Map counterpart = new IdentityHashMap() ; 1.109 - 1.110 - return equalsHelper( counterpart, considered, obj1, obj2 ) ; 1.111 - } 1.112 1.113 /** If arr1 and arr2 are both arrays of the same component type, 1.114 * return an array of that component type that consists of the 1.115 @@ -179,544 +84,4 @@ 1.116 return result ; 1.117 } 1.118 1.119 -//=========================================================================== 1.120 -// Implementation 1.121 -//=========================================================================== 1.122 - 1.123 - private void objectToStringHelper( IdentityHashMap printed, 1.124 - ObjectWriter result, java.lang.Object obj) 1.125 - { 1.126 - if (obj==null) { 1.127 - result.append( "null" ) ; 1.128 - result.endElement() ; 1.129 - } else { 1.130 - Class cls = obj.getClass() ; 1.131 - result.startObject( obj ) ; 1.132 - 1.133 - if (printed.keySet().contains( obj )) { 1.134 - result.endObject( "*VISITED*" ) ; 1.135 - } else { 1.136 - printed.put( obj, null ) ; 1.137 - 1.138 - if (mustUseToString(cls)) { 1.139 - result.endObject( obj.toString() ) ; 1.140 - } else { 1.141 - // First, handle any classes that have special printer 1.142 - // methods defined. This is useful when the class 1.143 - // overrides toString with something that 1.144 - // is not sufficiently detailed. 1.145 - ObjectPrinter printer = (ObjectPrinter)(classToPrinter.get( 1.146 - cls )) ; 1.147 - if (printer != null) { 1.148 - printer.print( printed, result, obj ) ; 1.149 - result.endObject() ; 1.150 - } else { 1.151 - Class compClass = cls.getComponentType() ; 1.152 - 1.153 - if (compClass == null) 1.154 - // handleObject always calls endObject 1.155 - handleObject( printed, result, obj ) ; 1.156 - else { 1.157 - handleArray( printed, result, obj ) ; 1.158 - result.endObject() ; 1.159 - } 1.160 - } 1.161 - } 1.162 - } 1.163 - } 1.164 - } 1.165 - 1.166 - private static interface ObjectPrinter { 1.167 - void print( IdentityHashMap printed, ObjectWriter buff, 1.168 - java.lang.Object obj ) ; 1.169 - } 1.170 - 1.171 - private ObjectPrinter propertiesPrinter = new ObjectPrinter() { 1.172 - public void print( IdentityHashMap printed, ObjectWriter buff, 1.173 - java.lang.Object obj ) 1.174 - { 1.175 - if (!(obj instanceof Properties)) 1.176 - throw new Error() ; 1.177 - 1.178 - Properties props = (Properties)obj ; 1.179 - Enumeration keys = props.propertyNames() ; 1.180 - while (keys.hasMoreElements()) { 1.181 - String key = (String)(keys.nextElement()) ; 1.182 - String value = props.getProperty( key ) ; 1.183 - buff.startElement() ; 1.184 - buff.append( key ) ; 1.185 - buff.append( "=" ) ; 1.186 - buff.append( value ) ; 1.187 - buff.endElement() ; 1.188 - } 1.189 - } 1.190 - } ; 1.191 - 1.192 - private ObjectPrinter collectionPrinter = new ObjectPrinter() { 1.193 - public void print( IdentityHashMap printed, ObjectWriter buff, 1.194 - java.lang.Object obj ) 1.195 - { 1.196 - if (!(obj instanceof Collection)) 1.197 - throw new Error() ; 1.198 - 1.199 - Collection coll = (Collection)obj ; 1.200 - Iterator iter = coll.iterator() ; 1.201 - while (iter.hasNext()) { 1.202 - java.lang.Object element = iter.next() ; 1.203 - buff.startElement() ; 1.204 - objectToStringHelper( printed, buff, element ) ; 1.205 - buff.endElement() ; 1.206 - } 1.207 - } 1.208 - } ; 1.209 - 1.210 - private ObjectPrinter mapPrinter = new ObjectPrinter() { 1.211 - public void print( IdentityHashMap printed, ObjectWriter buff, 1.212 - java.lang.Object obj ) 1.213 - { 1.214 - if (!(obj instanceof Map)) 1.215 - throw new Error() ; 1.216 - 1.217 - Map map = (Map)obj ; 1.218 - Iterator iter = map.entrySet().iterator() ; 1.219 - while (iter.hasNext()) { 1.220 - Entry entry = (Entry)(iter.next()) ; 1.221 - buff.startElement() ; 1.222 - objectToStringHelper( printed, buff, entry.getKey() ) ; 1.223 - buff.append( "=>" ) ; 1.224 - objectToStringHelper( printed, buff, entry.getValue() ) ; 1.225 - buff.endElement() ; 1.226 - } 1.227 - } 1.228 - } ; 1.229 - 1.230 - private static class ClassMap { 1.231 - ArrayList data ; 1.232 - 1.233 - public ClassMap() 1.234 - { 1.235 - data = new ArrayList() ; 1.236 - } 1.237 - 1.238 - /** Return the first element of the ClassMap that is assignable to cls. 1.239 - * The order is determined by the order in which the put method was 1.240 - * called. Returns null if there is no match. 1.241 - */ 1.242 - public java.lang.Object get( Class cls ) 1.243 - { 1.244 - Iterator iter = data.iterator() ; 1.245 - while (iter.hasNext()) { 1.246 - java.lang.Object[] arr = (java.lang.Object[])(iter.next()) ; 1.247 - Class key = (Class)(arr[0]) ; 1.248 - if (key.isAssignableFrom( cls )) 1.249 - return arr[1] ; 1.250 - } 1.251 - 1.252 - return null ; 1.253 - } 1.254 - 1.255 - /** Add obj to the map with key cls. Note that order matters, 1.256 - * as the first match is returned. 1.257 - */ 1.258 - public void put( Class cls, java.lang.Object obj ) 1.259 - { 1.260 - java.lang.Object[] pair = { cls, obj } ; 1.261 - data.add( pair ) ; 1.262 - } 1.263 - } 1.264 - 1.265 - private boolean mustUseToString( Class cls ) 1.266 - { 1.267 - // These probably never occur 1.268 - if (cls.isPrimitive()) 1.269 - return true ; 1.270 - 1.271 - // We must use toString for all primitive wrappers, since 1.272 - // otherwise the code recurses endlessly (access value field 1.273 - // inside Integer, returns another Integer through reflection). 1.274 - if ((cls == Integer.class) || 1.275 - (cls == BigInteger.class) || 1.276 - (cls == BigDecimal.class) || 1.277 - (cls == String.class) || 1.278 - (cls == StringBuffer.class) || 1.279 - (cls == Long.class) || 1.280 - (cls == Short.class) || 1.281 - (cls == Byte.class) || 1.282 - (cls == Character.class) || 1.283 - (cls == Float.class) || 1.284 - (cls == Double.class) || 1.285 - (cls == Boolean.class)) 1.286 - return true ; 1.287 - 1.288 - if (useToString) { 1.289 - try { 1.290 - cls.getDeclaredMethod( "toString", (Class[])null ) ; 1.291 - return true ; 1.292 - } catch (Exception exc) { 1.293 - return false ; 1.294 - } 1.295 - } 1.296 - 1.297 - return false ; 1.298 - } 1.299 - 1.300 - private void handleObject( IdentityHashMap printed, ObjectWriter result, 1.301 - java.lang.Object obj ) 1.302 - { 1.303 - Class cls = obj.getClass() ; 1.304 - 1.305 - try { 1.306 - Field[] fields; 1.307 - SecurityManager security = System.getSecurityManager(); 1.308 - if (security != null && !Modifier.isPublic(cls.getModifiers())) { 1.309 - fields = new Field[0]; 1.310 - } else { 1.311 - fields = cls.getDeclaredFields(); 1.312 - } 1.313 - 1.314 - for (int ctr=0; ctr<fields.length; ctr++ ) { 1.315 - final Field fld = fields[ctr] ; 1.316 - int modifiers = fld.getModifiers() ; 1.317 - 1.318 - // Do not display field if it is static, since these fields 1.319 - // are always the same for every instances. This could 1.320 - // be made configurable, but I don't think it is 1.321 - // useful to do so. 1.322 - if (!Modifier.isStatic( modifiers )) { 1.323 - if (security != null) { 1.324 - if (!Modifier.isPublic(modifiers)) 1.325 - continue; 1.326 - } 1.327 - result.startElement() ; 1.328 - result.append( fld.getName() ) ; 1.329 - result.append( ":" ) ; 1.330 - 1.331 - try { 1.332 - // Make sure that we can read the field if it is 1.333 - // not public 1.334 - AccessController.doPrivileged( new PrivilegedAction() { 1.335 - public Object run() { 1.336 - fld.setAccessible( true ) ; 1.337 - return null ; 1.338 - } 1.339 - } ) ; 1.340 - 1.341 - java.lang.Object value = fld.get( obj ) ; 1.342 - objectToStringHelper( printed, result, value ) ; 1.343 - } catch (Exception exc2) { 1.344 - result.append( "???" ) ; 1.345 - } 1.346 - 1.347 - result.endElement() ; 1.348 - } 1.349 - } 1.350 - 1.351 - result.endObject() ; 1.352 - } catch (Exception exc2) { 1.353 - result.endObject( obj.toString() ) ; 1.354 - } 1.355 - } 1.356 - 1.357 - private void handleArray( IdentityHashMap printed, ObjectWriter result, 1.358 - java.lang.Object obj ) 1.359 - { 1.360 - Class compClass = obj.getClass().getComponentType() ; 1.361 - if (compClass == boolean.class) { 1.362 - boolean[] arr = (boolean[])obj ; 1.363 - for (int ctr=0; ctr<arr.length; ctr++) { 1.364 - result.startElement() ; 1.365 - result.append( arr[ctr] ) ; 1.366 - result.endElement() ; 1.367 - } 1.368 - } else if (compClass == byte.class) { 1.369 - byte[] arr = (byte[])obj ; 1.370 - for (int ctr=0; ctr<arr.length; ctr++) { 1.371 - result.startElement() ; 1.372 - result.append( arr[ctr] ) ; 1.373 - result.endElement() ; 1.374 - } 1.375 - } else if (compClass == short.class) { 1.376 - short[] arr = (short[])obj ; 1.377 - for (int ctr=0; ctr<arr.length; ctr++) { 1.378 - result.startElement() ; 1.379 - result.append( arr[ctr] ) ; 1.380 - result.endElement() ; 1.381 - } 1.382 - } else if (compClass == int.class) { 1.383 - int[] arr = (int[])obj ; 1.384 - for (int ctr=0; ctr<arr.length; ctr++) { 1.385 - result.startElement() ; 1.386 - result.append( arr[ctr] ) ; 1.387 - result.endElement() ; 1.388 - } 1.389 - } else if (compClass == long.class) { 1.390 - long[] arr = (long[])obj ; 1.391 - for (int ctr=0; ctr<arr.length; ctr++) { 1.392 - result.startElement() ; 1.393 - result.append( arr[ctr] ) ; 1.394 - result.endElement() ; 1.395 - } 1.396 - } else if (compClass == char.class) { 1.397 - char[] arr = (char[])obj ; 1.398 - for (int ctr=0; ctr<arr.length; ctr++) { 1.399 - result.startElement() ; 1.400 - result.append( arr[ctr] ) ; 1.401 - result.endElement() ; 1.402 - } 1.403 - } else if (compClass == float.class) { 1.404 - float[] arr = (float[])obj ; 1.405 - for (int ctr=0; ctr<arr.length; ctr++) { 1.406 - result.startElement() ; 1.407 - result.append( arr[ctr] ) ; 1.408 - result.endElement() ; 1.409 - } 1.410 - } else if (compClass == double.class) { 1.411 - double[] arr = (double[])obj ; 1.412 - for (int ctr=0; ctr<arr.length; ctr++) { 1.413 - result.startElement() ; 1.414 - result.append( arr[ctr] ) ; 1.415 - result.endElement() ; 1.416 - } 1.417 - } else { // array of object 1.418 - java.lang.Object[] arr = (java.lang.Object[])obj ; 1.419 - for (int ctr=0; ctr<arr.length; ctr++) { 1.420 - result.startElement() ; 1.421 - objectToStringHelper( printed, result, arr[ctr] ) ; 1.422 - result.endElement() ; 1.423 - } 1.424 - } 1.425 - } 1.426 - 1.427 - private static class Pair 1.428 - { 1.429 - private java.lang.Object obj1 ; 1.430 - private java.lang.Object obj2 ; 1.431 - 1.432 - Pair( java.lang.Object obj1, java.lang.Object obj2 ) 1.433 - { 1.434 - this.obj1 = obj1 ; 1.435 - this.obj2 = obj2 ; 1.436 - } 1.437 - 1.438 - public boolean equals( java.lang.Object obj ) 1.439 - { 1.440 - if (!(obj instanceof Pair)) 1.441 - return false ; 1.442 - 1.443 - Pair other = (Pair)obj ; 1.444 - return other.obj1 == obj1 && other.obj2 == obj2 ; 1.445 - } 1.446 - 1.447 - public int hashCode() 1.448 - { 1.449 - return System.identityHashCode( obj1 ) ^ 1.450 - System.identityHashCode( obj2 ) ; 1.451 - } 1.452 - } 1.453 - 1.454 - private static boolean equalsHelper( Map counterpart, Set considered, 1.455 - java.lang.Object obj1, java.lang.Object obj2 ) 1.456 - { 1.457 - if ((obj1 == null) || (obj2 == null)) 1.458 - return obj1 == obj2 ; 1.459 - 1.460 - java.lang.Object other2 = counterpart.get( obj1 ) ; 1.461 - if (other2 == null) { 1.462 - other2 = obj2 ; 1.463 - counterpart.put( obj1, other2 ) ; 1.464 - } 1.465 - 1.466 - if (obj1 == other2) 1.467 - return true ; 1.468 - 1.469 - if (obj2 != other2) 1.470 - return false ; 1.471 - 1.472 - Pair pair = new Pair( obj1, obj2 ) ; 1.473 - if (considered.contains( pair )) 1.474 - return true ; 1.475 - else 1.476 - considered.add( pair ) ; 1.477 - 1.478 - if (obj1 instanceof java.lang.Object[] && 1.479 - obj2 instanceof java.lang.Object[]) 1.480 - return equalArrays( counterpart, considered, 1.481 - (java.lang.Object[])obj1, (java.lang.Object[])obj2 ) ; 1.482 - else if (obj1 instanceof Map && obj2 instanceof Map) 1.483 - return equalMaps( counterpart, considered, 1.484 - (Map)obj1, (Map)obj2 ) ; 1.485 - else if (obj1 instanceof Set && obj2 instanceof Set) 1.486 - return equalSets( counterpart, considered, 1.487 - (Set)obj1, (Set)obj2 ) ; 1.488 - else if (obj1 instanceof List && obj2 instanceof List) 1.489 - return equalLists( counterpart, considered, 1.490 - (List)obj1, (List)obj2 ) ; 1.491 - else if (obj1 instanceof boolean[] && obj2 instanceof boolean[]) 1.492 - return Arrays.equals( (boolean[])obj1, (boolean[])obj2 ) ; 1.493 - else if (obj1 instanceof byte[] && obj2 instanceof byte[]) 1.494 - return Arrays.equals( (byte[])obj1, (byte[])obj2 ) ; 1.495 - else if (obj1 instanceof char[] && obj2 instanceof char[]) 1.496 - return Arrays.equals( (char[])obj1, (char[])obj2 ) ; 1.497 - else if (obj1 instanceof double[] && obj2 instanceof double[]) 1.498 - return Arrays.equals( (double[])obj1, (double[])obj2 ) ; 1.499 - else if (obj1 instanceof float[] && obj2 instanceof float[]) 1.500 - return Arrays.equals( (float[])obj1, (float[])obj2 ) ; 1.501 - else if (obj1 instanceof int[] && obj2 instanceof int[]) 1.502 - return Arrays.equals( (int[])obj1, (int[])obj2 ) ; 1.503 - else if (obj1 instanceof long[] && obj2 instanceof long[]) 1.504 - return Arrays.equals( (long[])obj1, (long[])obj2 ) ; 1.505 - else { 1.506 - Class cls = obj1.getClass() ; 1.507 - if (cls != obj2.getClass()) 1.508 - return obj1.equals( obj2 ) ; 1.509 - else 1.510 - return equalsObject( counterpart, considered, cls, obj1, obj2 ) ; 1.511 - } 1.512 - } 1.513 - 1.514 - private static boolean equalsObject( Map counterpart, Set considered, 1.515 - Class cls, java.lang.Object obj1, java.lang.Object obj2 ) 1.516 - { 1.517 - Class objectClass = java.lang.Object.class ; 1.518 - if (cls == objectClass) 1.519 - return true ; 1.520 - 1.521 - Class[] equalsTypes = { objectClass } ; 1.522 - try { 1.523 - Method equalsMethod = cls.getDeclaredMethod( "equals", 1.524 - equalsTypes ) ; 1.525 - return obj1.equals( obj2 ) ; 1.526 - } catch (Exception exc) { 1.527 - if (equalsObjectFields( counterpart, considered, 1.528 - cls, obj1, obj2 )) 1.529 - return equalsObject( counterpart, considered, 1.530 - cls.getSuperclass(), obj1, obj2 ) ; 1.531 - else 1.532 - return false ; 1.533 - } 1.534 - } 1.535 - 1.536 - private static boolean equalsObjectFields( Map counterpart, Set considered, 1.537 - Class cls, java.lang.Object obj1, java.lang.Object obj2 ) 1.538 - { 1.539 - Field[] fields = cls.getDeclaredFields() ; 1.540 - for (int ctr=0; ctr<fields.length; ctr++) { 1.541 - try { 1.542 - final Field field = fields[ctr] ; 1.543 - // Ignore static fields 1.544 - if (!Modifier.isStatic( field.getModifiers())) { 1.545 - AccessController.doPrivileged(new PrivilegedAction() { 1.546 - public Object run() { 1.547 - field.setAccessible( true ) ; 1.548 - return null ; 1.549 - } 1.550 - } ) ; 1.551 - 1.552 - java.lang.Object value1 = field.get( obj1 ) ; 1.553 - java.lang.Object value2 = field.get( obj2 ) ; 1.554 - if (!equalsHelper( counterpart, considered, value1, 1.555 - value2 )) 1.556 - return false ; 1.557 - } 1.558 - } catch (IllegalAccessException exc) { 1.559 - return false ; 1.560 - } 1.561 - } 1.562 - 1.563 - return true ; 1.564 - } 1.565 - 1.566 - private static boolean equalArrays( Map counterpart, Set considered, 1.567 - java.lang.Object[] arr1, java.lang.Object[] arr2 ) 1.568 - { 1.569 - int len = arr1.length ; 1.570 - if (len != arr2.length) 1.571 - return false ; 1.572 - 1.573 - for (int ctr = 0; ctr<len; ctr++ ) 1.574 - if (!equalsHelper( counterpart, considered, arr1[ctr], arr2[ctr] )) 1.575 - return false ; 1.576 - 1.577 - return true ; 1.578 - } 1.579 - 1.580 - private static boolean equalMaps( Map counterpart, Set considered, 1.581 - Map map1, Map map2 ) 1.582 - { 1.583 - if (map2.size() != map1.size()) 1.584 - return false; 1.585 - 1.586 - try { 1.587 - Iterator i = map1.entrySet().iterator(); 1.588 - while (i.hasNext()) { 1.589 - Entry e = (Entry) i.next(); 1.590 - java.lang.Object key = e.getKey(); 1.591 - java.lang.Object value = e.getValue(); 1.592 - if (value == null) { 1.593 - if (!(map2.get(key)==null && map2.containsKey(key))) 1.594 - return false; 1.595 - } else { 1.596 - if (!equalsHelper( counterpart, considered, 1.597 - value, map2.get(key))) 1.598 - return false; 1.599 - } 1.600 - } 1.601 - } catch(ClassCastException unused) { 1.602 - return false; 1.603 - } catch(NullPointerException unused) { 1.604 - return false; 1.605 - } 1.606 - 1.607 - return true; 1.608 - } 1.609 - 1.610 - // Obviously this is an inefficient quadratic algorithm. 1.611 - // This is taken pretty directly from AbstractSet and AbstractCollection 1.612 - // in the JDK. 1.613 - // For HashSet, an O(n) (with a good hash function) algorithm 1.614 - // is possible, and likewise TreeSet, since it is 1.615 - // ordered, is O(n). But this is not worth the effort here. 1.616 - // Note that the inner loop uses equals, not equalsHelper. 1.617 - // This is needed because of the searching behavior of this test. 1.618 - // However, note that this will NOT correctly handle sets that 1.619 - // contain themselves as members, or that have members that reference 1.620 - // themselves. These cases will cause infinite regress! 1.621 - private static boolean equalSets( Map counterpart, Set considered, 1.622 - Set set1, Set set2 ) 1.623 - { 1.624 - if (set1.size() != set2.size()) 1.625 - return false ; 1.626 - 1.627 - Iterator e1 = set1.iterator() ; 1.628 - while (e1.hasNext()) { 1.629 - java.lang.Object obj1 = e1.next() ; 1.630 - 1.631 - boolean found = false ; 1.632 - Iterator e2 = set2.iterator() ; 1.633 - while (e2.hasNext() && !found) { 1.634 - java.lang.Object obj2 = e2.next() ; 1.635 - found = equals( obj1, obj2 ) ; 1.636 - } 1.637 - 1.638 - if (!found) 1.639 - return false ; 1.640 - } 1.641 - 1.642 - return true ; 1.643 - } 1.644 - 1.645 - private static boolean equalLists( Map counterpart, Set considered, 1.646 - List list1, List list2 ) 1.647 - { 1.648 - ListIterator e1 = list1.listIterator(); 1.649 - ListIterator e2 = list2.listIterator(); 1.650 - while(e1.hasNext() && e2.hasNext()) { 1.651 - java.lang.Object o1 = e1.next(); 1.652 - java.lang.Object o2 = e2.next(); 1.653 - if (!(o1==null ? o2==null : equalsHelper( 1.654 - counterpart, considered, o1, o2))) 1.655 - return false; 1.656 - } 1.657 - return !(e1.hasNext() || e2.hasNext()); 1.658 - } 1.659 }