1 7 8 package com.sun.corba.se.impl.orbutil; 9 10 import java.security.PrivilegedAction ; 11 import java.security.AccessController ; 12 import java.util.ArrayList ; 13 import java.util.Arrays ; 14 import java.util.Map ; 15 import java.util.List ; 16 import java.util.ListIterator ; 17 import java.util.Set ; 18 import java.util.Map.Entry; 19 import java.util.Collection ; 20 import java.util.HashMap ; 21 import java.util.HashSet ; 22 import java.util.Hashtable ; 23 import java.util.Iterator ; 24 import java.util.Enumeration ; 25 import java.util.Properties ; 26 import java.util.IdentityHashMap ; 27 import java.lang.reflect.Array ; 28 import java.lang.reflect.Field ; 29 import java.lang.reflect.Method ; 30 import java.lang.reflect.Modifier ; 31 import java.math.BigInteger ; 32 import java.math.BigDecimal ; 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 .class, propertiesPrinter ) ; 54 classToPrinter.put( Collection .class, collectionPrinter ) ; 55 classToPrinter.put( Map .class, mapPrinter ) ; 56 } 57 58 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 71 public static ObjectUtility make( boolean useToString, boolean isIndenting ) 72 { 73 return new ObjectUtility( useToString, isIndenting, 0, 4 ) ; 74 } 75 76 79 public static ObjectUtility make() 80 { 81 return standard ; 82 } 83 84 88 public static String defaultObjectToString( java.lang.Object object ) 89 { 90 return standard.objectToString( object ) ; 91 } 92 93 public static String compactObjectToString( java.lang.Object object ) 94 { 95 return compact.objectToString( object ) ; 96 } 97 98 105 public String objectToString(java.lang.Object obj) 106 { 107 IdentityHashMap printed = new IdentityHashMap () ; 108 ObjectWriter result = ObjectWriter.make( isIndenting, initialLevel, 109 increment ) ; 110 objectToStringHelper( printed, result, obj ) ; 111 return result.toString() ; 112 } 113 114 public static boolean equals( java.lang.Object obj1, java.lang.Object obj2 ) 118 { 119 Set considered = new HashSet () ; 124 125 Map counterpart = new IdentityHashMap () ; 129 130 return equalsHelper( counterpart, considered, obj1, obj2 ) ; 131 } 132 133 138 public static Object concatenateArrays( Object arr1, Object arr2 ) 139 { 140 Class comp1 = arr1.getClass().getComponentType() ; 141 Class 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 ( "Arguments must be arrays" ) ; 147 if (!comp1.equals( comp2 )) 148 throw new IllegalStateException ( 149 "Arguments must be arrays with the same component type" ) ; 150 151 Object 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 168 private void objectToStringHelper( IdentityHashMap printed, 169 ObjectWriter result, java.lang.Object obj) 170 { 171 if (obj==null) { 172 result.append( "null" ) ; 173 result.endElement() ; 174 } else { 175 Class 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 ObjectPrinter printer = (ObjectPrinter)(classToPrinter.get( 191 cls )) ; 192 if (printer != null) { 193 printer.print( printed, result, obj ) ; 194 result.endObject() ; 195 } else { 196 Class compClass = cls.getComponentType() ; 197 198 if (compClass == null) 199 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 printed, ObjectWriter buff, 213 java.lang.Object obj ) ; 214 } 215 216 private ObjectPrinter propertiesPrinter = new ObjectPrinter() { 217 public void print( IdentityHashMap printed, ObjectWriter buff, 218 java.lang.Object obj ) 219 { 220 if (!(obj instanceof Properties )) 221 throw new Error () ; 222 223 Properties props = (Properties )obj ; 224 Enumeration keys = props.propertyNames() ; 225 while (keys.hasMoreElements()) { 226 String key = (String )(keys.nextElement()) ; 227 String 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 printed, ObjectWriter buff, 239 java.lang.Object obj ) 240 { 241 if (!(obj instanceof Collection )) 242 throw new Error () ; 243 244 Collection coll = (Collection )obj ; 245 Iterator iter = coll.iterator() ; 246 while (iter.hasNext()) { 247 java.lang.Object 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 printed, ObjectWriter buff, 257 java.lang.Object obj ) 258 { 259 if (!(obj instanceof Map )) 260 throw new Error () ; 261 262 Map map = (Map )obj ; 263 Iterator 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 data ; 277 278 public ClassMap() 279 { 280 data = new ArrayList () ; 281 } 282 283 287 public java.lang.Object get( Class cls ) 288 { 289 Iterator iter = data.iterator() ; 290 while (iter.hasNext()) { 291 java.lang.Object [] arr = (java.lang.Object [])(iter.next()) ; 292 Class key = (Class )(arr[0]) ; 293 if (key.isAssignableFrom( cls )) 294 return arr[1] ; 295 } 296 297 return null ; 298 } 299 300 303 public void put( Class cls, java.lang.Object obj ) 304 { 305 java.lang.Object [] pair = { cls, obj } ; 306 data.add( pair ) ; 307 } 308 } 309 310 private boolean mustUseToString( Class cls ) 311 { 312 if (cls.isPrimitive()) 314 return true ; 315 316 if ((cls == Integer .class) || 320 (cls == BigInteger .class) || 321 (cls == BigDecimal .class) || 322 (cls == String .class) || 323 (cls == StringBuffer .class) || 324 (cls == Long .class) || 325 (cls == Short .class) || 326 (cls == Byte .class) || 327 (cls == Character .class) || 328 (cls == Float .class) || 329 (cls == Double .class) || 330 (cls == Boolean .class)) 331 return true ; 332 333 if (useToString) { 334 try { 335 cls.getDeclaredMethod( "toString", null ) ; 336 return true ; 337 } catch (Exception exc) { 338 return false ; 339 } 340 } 341 342 return false ; 343 } 344 345 private void handleObject( IdentityHashMap printed, ObjectWriter result, 346 java.lang.Object obj ) 347 { 348 Class cls = obj.getClass() ; 349 350 try { 351 Field [] fields; 352 SecurityManager security = System.getSecurityManager(); 353 if (security != null && !Modifier.isPublic(cls.getModifiers())) { 354 fields = new Field [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 fld = fields[ctr] ; 361 int modifiers = fld.getModifiers() ; 362 363 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 AccessController.doPrivileged( new PrivilegedAction () { 380 public Object run() { 381 fld.setAccessible( true ) ; 382 return null ; 383 } 384 } ) ; 385 386 java.lang.Object value = fld.get( obj ) ; 387 objectToStringHelper( printed, result, value ) ; 388 } catch (Exception exc2) { 389 result.append( "???" ) ; 390 } 391 392 result.endElement() ; 393 } 394 } 395 396 result.endObject() ; 397 } catch (Exception exc2) { 398 result.endObject( obj.toString() ) ; 399 } 400 } 401 402 private void handleArray( IdentityHashMap printed, ObjectWriter result, 403 java.lang.Object obj ) 404 { 405 Class 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 { java.lang.Object [] arr = (java.lang.Object [])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 obj1 ; 475 private java.lang.Object obj2 ; 476 477 Pair( java.lang.Object obj1, java.lang.Object obj2 ) 478 { 479 this.obj1 = obj1 ; 480 this.obj2 = obj2 ; 481 } 482 483 public boolean equals( java.lang.Object 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 counterpart, Set considered, 500 java.lang.Object obj1, java.lang.Object obj2 ) 501 { 502 if ((obj1 == null) || (obj2 == null)) 503 return obj1 == obj2 ; 504 505 java.lang.Object 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 [] && 524 obj2 instanceof java.lang.Object []) 525 return equalArrays( counterpart, considered, 526 (java.lang.Object [])obj1, (java.lang.Object [])obj2 ) ; 527 else if (obj1 instanceof Map && obj2 instanceof Map ) 528 return equalMaps( counterpart, considered, 529 (Map )obj1, (Map )obj2 ) ; 530 else if (obj1 instanceof Set && obj2 instanceof Set ) 531 return equalSets( counterpart, considered, 532 (Set )obj1, (Set )obj2 ) ; 533 else if (obj1 instanceof List && obj2 instanceof List ) 534 return equalLists( counterpart, considered, 535 (List )obj1, (List )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 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 counterpart, Set considered, 560 Class cls, java.lang.Object obj1, java.lang.Object obj2 ) 561 { 562 Class objectClass = java.lang.Object .class ; 563 if (cls == objectClass) 564 return true ; 565 566 Class [] equalsTypes = { objectClass } ; 567 try { 568 Method equalsMethod = cls.getDeclaredMethod( "equals", 569 equalsTypes ) ; 570 return obj1.equals( obj2 ) ; 571 } catch (Exception 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 counterpart, Set considered, 582 Class cls, java.lang.Object obj1, java.lang.Object obj2 ) 583 { 584 Field [] fields = cls.getDeclaredFields() ; 585 for (int ctr=0; ctr<fields.length; ctr++) { 586 try { 587 final Field field = fields[ctr] ; 588 if (!Modifier.isStatic( field.getModifiers())) { 590 AccessController.doPrivileged(new PrivilegedAction () { 591 public Object run() { 592 field.setAccessible( true ) ; 593 return null ; 594 } 595 } ) ; 596 597 java.lang.Object value1 = field.get( obj1 ) ; 598 java.lang.Object value2 = field.get( obj2 ) ; 599 if (!equalsHelper( counterpart, considered, value1, 600 value2 )) 601 return false ; 602 } 603 } catch (IllegalAccessException exc) { 604 return false ; 605 } 606 } 607 608 return true ; 609 } 610 611 private static boolean equalArrays( Map counterpart, Set considered, 612 java.lang.Object [] arr1, java.lang.Object [] 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 counterpart, Set considered, 626 Map map1, Map map2 ) 627 { 628 if (map2.size() != map1.size()) 629 return false; 630 631 try { 632 Iterator i = map1.entrySet().iterator(); 633 while (i.hasNext()) { 634 Entry e = (Entry) i.next(); 635 java.lang.Object key = e.getKey(); 636 java.lang.Object 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 unused) { 647 return false; 648 } catch(NullPointerException unused) { 649 return false; 650 } 651 652 return true; 653 } 654 655 private static boolean equalSets( Map counterpart, Set considered, 667 Set set1, Set set2 ) 668 { 669 if (set1.size() != set2.size()) 670 return false ; 671 672 Iterator e1 = set1.iterator() ; 673 while (e1.hasNext()) { 674 java.lang.Object obj1 = e1.next() ; 675 676 boolean found = false ; 677 Iterator e2 = set2.iterator() ; 678 while (e2.hasNext() && !found) { 679 java.lang.Object 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 counterpart, Set considered, 691 List list1, List list2 ) 692 { 693 ListIterator e1 = list1.listIterator(); 694 ListIterator e2 = list2.listIterator(); 695 while(e1.hasNext() && e2.hasNext()) { 696 java.lang.Object o1 = e1.next(); 697 java.lang.Object 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 |