📄 objectutility.java
字号:
/* * @(#)ORBUtility.java 1.32 02/08/13 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.corba.se.impl.orbutil;import java.security.PrivilegedAction;import java.security.AccessController;import java.util.ArrayList;import java.util.Arrays;import java.util.Map;import java.util.List;import java.util.ListIterator;import java.util.Set;import java.util.Map.Entry;import java.util.Collection;import java.util.HashMap;import java.util.HashSet;import java.util.Hashtable;import java.util.Iterator;import java.util.Enumeration;import java.util.Properties;import java.util.IdentityHashMap;import java.lang.reflect.Array;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.math.BigInteger ;import java.math.BigDecimal ;public final class ObjectUtility { private boolean useToString ; private boolean isIndenting ; private int initialLevel ; private int increment ; private ClassMap classToPrinter = new ClassMap() ; private static ObjectUtility standard = new ObjectUtility( false, true, 0, 4 ) ; private static ObjectUtility compact = new ObjectUtility( true, false, 0, 4 ) ; private ObjectUtility( boolean useToString, boolean isIndenting, int initialLevel, int increment ) { this.useToString = useToString ; this.isIndenting = isIndenting ; this.initialLevel = initialLevel ; this.increment = increment ; classToPrinter.put( Properties.class, propertiesPrinter ) ; classToPrinter.put( Collection.class, collectionPrinter ) ; classToPrinter.put( Map.class, mapPrinter ) ; } /** Construct an Utility instance with the desired objectToString * behavior. */ public static ObjectUtility make( boolean useToString, boolean isIndenting, int initialLevel, int increment ) { return new ObjectUtility( useToString, isIndenting, initialLevel, increment ) ; } /** Construct an Utility instance with the desired objectToString * behavior. */ public static ObjectUtility make( boolean useToString, boolean isIndenting ) { return new ObjectUtility( useToString, isIndenting, 0, 4 ) ; } /** Get the standard Utility object that supports objectToString with * indented display and no use of toString() methods. */ public static ObjectUtility make() { return standard ; } /** A convenience method that gives the default behavior: use indenting * to display the object's structure and do not use built-in toString * methods. */ public static String defaultObjectToString( java.lang.Object object ) { return standard.objectToString( object ) ; } public static String compactObjectToString( java.lang.Object object ) { return compact.objectToString( object ) ; } /** objectToString handles display of arbitrary objects. It correctly * handles objects whose elements form an arbitrary graph. It uses * reflection to display the contents of any kind of object. * An object's toString() method may optionally be used, but the default * is to ignore all toString() methods except for those defined for * primitive types, primitive type wrappers, and strings. */ public String objectToString(java.lang.Object obj) { IdentityHashMap printed = new IdentityHashMap() ; ObjectWriter result = ObjectWriter.make( isIndenting, initialLevel, increment ) ; objectToStringHelper( printed, result, obj ) ; return result.toString() ; } // Perform a deep structural equality comparison of the two objects. // This handles all arrays, maps, and sets specially, otherwise // it just calls the object's equals() method. public static boolean equals( java.lang.Object obj1, java.lang.Object obj2 ) { // Set of pairs of objects that have been (or are being) considered for // equality. Such pairs are presumed to be equals. If they are not, // this will be detected eventually and the equals method will return // false. Set considered = new HashSet() ; // Map that gives the corresponding component of obj2 for a component // of obj1. This is used to check for the same aliasing and use of // equal objects in both objects. Map counterpart = new IdentityHashMap() ; return equalsHelper( counterpart, considered, obj1, obj2 ) ; } /** If arr1 and arr2 are both arrays of the same component type, * return an array of that component type that consists of the * elements of arr1 followed by the elements of arr2. * Throws IllegalArgumentException otherwise. */ public static Object concatenateArrays( Object arr1, Object arr2 ) { Class comp1 = arr1.getClass().getComponentType() ; Class comp2 = arr2.getClass().getComponentType() ; int len1 = Array.getLength( arr1 ) ; int len2 = Array.getLength( arr2 ) ; if ((comp1 == null) || (comp2 == null)) throw new IllegalStateException( "Arguments must be arrays" ) ; if (!comp1.equals( comp2 )) throw new IllegalStateException( "Arguments must be arrays with the same component type" ) ; Object result = Array.newInstance( comp1, len1 + len2 ) ; int index = 0 ; for (int ctr=0; ctr<len1; ctr++) Array.set( result, index++, Array.get( arr1, ctr ) ) ; for (int ctr=0; ctr<len2; ctr++) Array.set( result, index++, Array.get( arr2, ctr ) ) ; return result ; }//===========================================================================// Implementation//=========================================================================== private void objectToStringHelper( IdentityHashMap printed, ObjectWriter result, java.lang.Object obj) { if (obj==null) { result.append( "null" ) ; result.endElement() ; } else { Class cls = obj.getClass() ; result.startObject( obj ) ; if (printed.keySet().contains( obj )) { result.endObject( "*VISITED*" ) ; } else { printed.put( obj, null ) ; if (mustUseToString(cls)) { result.endObject( obj.toString() ) ; } else { // First, handle any classes that have special printer // methods defined. This is useful when the class // overrides toString with something that // is not sufficiently detailed. ObjectPrinter printer = (ObjectPrinter)(classToPrinter.get( cls )) ; if (printer != null) { printer.print( printed, result, obj ) ; result.endObject() ; } else { Class compClass = cls.getComponentType() ; if (compClass == null) // handleObject always calls endObject handleObject( printed, result, obj ) ; else { handleArray( printed, result, obj ) ; result.endObject() ; } } } } } } private static interface ObjectPrinter { void print( IdentityHashMap printed, ObjectWriter buff, java.lang.Object obj ) ; } private ObjectPrinter propertiesPrinter = new ObjectPrinter() { public void print( IdentityHashMap printed, ObjectWriter buff, java.lang.Object obj ) { if (!(obj instanceof Properties)) throw new Error() ; Properties props = (Properties)obj ; Enumeration keys = props.propertyNames() ; while (keys.hasMoreElements()) { String key = (String)(keys.nextElement()) ; String value = props.getProperty( key ) ; buff.startElement() ; buff.append( key ) ; buff.append( "=" ) ; buff.append( value ) ; buff.endElement() ; } } } ; private ObjectPrinter collectionPrinter = new ObjectPrinter() { public void print( IdentityHashMap printed, ObjectWriter buff, java.lang.Object obj ) { if (!(obj instanceof Collection)) throw new Error() ; Collection coll = (Collection)obj ; Iterator iter = coll.iterator() ; while (iter.hasNext()) { java.lang.Object element = iter.next() ; buff.startElement() ; objectToStringHelper( printed, buff, element ) ; buff.endElement() ; } } } ; private ObjectPrinter mapPrinter = new ObjectPrinter() { public void print( IdentityHashMap printed, ObjectWriter buff, java.lang.Object obj ) { if (!(obj instanceof Map)) throw new Error() ; Map map = (Map)obj ; Iterator iter = map.entrySet().iterator() ; while (iter.hasNext()) { Entry entry = (Entry)(iter.next()) ; buff.startElement() ; objectToStringHelper( printed, buff, entry.getKey() ) ; buff.append( "=>" ) ; objectToStringHelper( printed, buff, entry.getValue() ) ; buff.endElement() ; } } } ; private static class ClassMap { ArrayList data ; public ClassMap() { data = new ArrayList() ; } /** Return the first element of the ClassMap that is assignable to cls. * The order is determined by the order in which the put method was * called. Returns null if there is no match. */ public java.lang.Object get( Class cls ) { Iterator iter = data.iterator() ; while (iter.hasNext()) { java.lang.Object[] arr = (java.lang.Object[])(iter.next()) ; Class key = (Class)(arr[0]) ; if (key.isAssignableFrom( cls )) return arr[1] ; } return null ; } /** Add obj to the map with key cls. Note that order matters, * as the first match is returned. */ public void put( Class cls, java.lang.Object obj ) { java.lang.Object[] pair = { cls, obj } ; data.add( pair ) ; } } private boolean mustUseToString( Class cls ) { // These probably never occur if (cls.isPrimitive()) return true ; // We must use toString for all primitive wrappers, since // otherwise the code recurses endlessly (access value field // inside Integer, returns another Integer through reflection). if ((cls == Integer.class) || (cls == BigInteger.class) || (cls == BigDecimal.class) || (cls == String.class) || (cls == StringBuffer.class) || (cls == Long.class) || (cls == Short.class) || (cls == Byte.class) || (cls == Character.class) || (cls == Float.class) || (cls == Double.class) || (cls == Boolean.class)) return true ; if (useToString) { try { cls.getDeclaredMethod( "toString", null ) ; return true ; } catch (Exception exc) { return false ; } } return false ; } private void handleObject( IdentityHashMap printed, ObjectWriter result, java.lang.Object obj ) { Class cls = obj.getClass() ; try { Field[] fields; SecurityManager security = System.getSecurityManager(); if (security != null && !Modifier.isPublic(cls.getModifiers())) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -