1600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang/* 2600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* Conditions Of Use 3600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* 4600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* This software was developed by employees of the National Institute of 5600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* Standards and Technology (NIST), an agency of the Federal Government. 6600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* Pursuant to title 15 Untied States Code Section 105, works of NIST 7600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* employees are not subject to copyright protection in the United States 8600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* and are considered to be in the public domain. As a result, a formal 9600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* license is not needed to use the software. 10600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* 11600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* This software is provided by NIST as a service and is expressly 12600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED 13600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF 14600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 15600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* AND DATA ACCURACY. NIST does not warrant or make any representations 16600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* regarding the use of the software or the results thereof, including but 17600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* not limited to the correctness, accuracy, reliability or usefulness of 18600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* the software. 19600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* 20600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* Permission to use this software is contingent upon your acceptance 21600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* of the terms of this agreement 22600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* 23600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* . 24600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* 25600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang*/ 26600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang/****************************************************************************** 27600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Product of NIST/ITL Advanced Networking Technologies Division (ANTD). * 28600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ******************************************************************************/ 29600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangpackage gov.nist.core; 30600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.lang.reflect.*; 31600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.io.Serializable; 32600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.util.*; 33600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 34600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang/** 35600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* The base class from which all the other classes in the 36600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* sipheader, sdpfields and sipmessage packages are extended. 37600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* Provides a few utility funcitons such as indentation and 38600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* pretty printing that all other classes benifit from. 39600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* 40600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang*@version 1.2 41600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* 42600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang*@author M. Ranganathan <br/> 43600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* 44600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* 45600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* 46600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang*/ 47600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 48600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangpublic abstract class GenericObject implements Serializable, Cloneable { 49600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Useful constants. 50600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String SEMICOLON = Separators.SEMICOLON; 51600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String COLON = Separators.COLON; 52600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String COMMA = Separators.COMMA; 53600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String SLASH = Separators.SLASH; 54600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String SP = Separators.SP; 55600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String EQUALS = Separators.EQUALS; 56600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String STAR = Separators.STAR; 57600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String NEWLINE = Separators.NEWLINE; 58600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String RETURN = Separators.RETURN; 59600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String LESS_THAN = Separators.LESS_THAN; 60600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String GREATER_THAN = Separators.GREATER_THAN; 61600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String AT = Separators.AT; 62600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String DOT = Separators.DOT; 63600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String QUESTION = Separators.QUESTION; 64600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String POUND = Separators.POUND; 65600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String AND = Separators.AND; 66600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String LPAREN = Separators.LPAREN; 67600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String RPAREN = Separators.RPAREN; 68600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String DOUBLE_QUOTE = Separators.DOUBLE_QUOTE; 69600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String QUOTE = Separators.QUOTE; 70600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String HT = Separators.HT; 71600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final String PERCENT = Separators.PERCENT; 72600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 73600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected static final Set<Class<?>> immutableClasses = new HashSet<Class<?>> (10); 74600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang static final String[] immutableClassNames ={ 75600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "String", "Character", 76600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Boolean", "Byte", "Short", "Integer", "Long", 77600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Float", "Double" 78600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang }; 79600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 80600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected int indentation; 81600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected String stringRepresentation; 82600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected Match matchExpression; // Pattern matcher. 83600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 84600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang static { 85600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 86600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang for (int i = 0; i < immutableClassNames.length; i++) 87600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang immutableClasses.add(Class.forName("java.lang." + immutableClassNames [i])); 88600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (ClassNotFoundException e) { 89600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new RuntimeException ("Internal error", e); 90600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 91600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 92600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 93600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** Set the pattern matcher. To match on the 94600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * field of a sip message, set the match expression in the match template 95600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * and invoke the match function. This useful because 96600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * SIP headers and parameters may appear in different orders and are not 97600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * necessarily in canonical form. This makes it hard to write a pattern 98600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * matcher that relies on regular expressions alone. 99600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Thus we rely on the following strategy i.e. To do pattern matching on 100600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * an incoming message, first parse it, and then construct a match template, 101600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * filling in the fields that you want to 102600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * match. The rules for matching are: A null object matches wild card - 103600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * that is a match template of null matches any parsed SIP object. 104600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * To match with any subfield, set the match template on a template object 105600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * of the same type and invoke the match interface. 106600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Regular expressions matching implements the gov.nist.sip.Match interface 107600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * that can be done using the Jakarta regexp package for example. 108600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * package included herein. This can be used to implement the Match interface 109600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * <a href=http://www.apache.org> See the APACHE website for documents </a> 110600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 111600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 112600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public void setMatcher(Match matchExpression) { 113600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (matchExpression == null) 114600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new IllegalArgumentException("null arg!"); 115600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.matchExpression = matchExpression; 116600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 117600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 118600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** Return the match expression. 119600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang *@return the match expression that has previously been set. 120600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 121600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public Match getMatcher() { 122600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return matchExpression; 123600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 124600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 125600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public static Class<?> getClassFromName(String className) { 126600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 127600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return Class.forName(className); 128600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (Exception ex) { 129600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang InternalErrorHandler.handleException(ex); 130600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return null; 131600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 132600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 133600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 134600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public static boolean isMySubclass(Class<?> other) { 135600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 136600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return GenericObject.class.isAssignableFrom(other); 137600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 138600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 139600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 140600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** Clones the given object. 141600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * If the object is a wrapped type, an array, a GenericObject 142600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * or a GenericObjectList, it is cast to the appropriate type 143600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * and the clone() method is invoked. Else if the object implements 144600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Cloneable, reflection is used to discover and invoke 145600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * clone() method. Otherwise, the original object is returned. 146600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 147600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public static Object makeClone(Object obj) { 148600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (obj == null) 149600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new NullPointerException("null obj!"); 150600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Class<?> c = obj.getClass(); 151600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Object clone_obj = obj; 152600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (immutableClasses.contains (c)) 153600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return obj; 154600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (c.isArray ()) { 155600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Class<?> ec = c.getComponentType(); 156600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (! ec.isPrimitive()) 157600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang clone_obj = ((Object []) obj).clone(); 158600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else { 159600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (ec == Character.TYPE) 160600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang clone_obj = ((char []) obj).clone(); 161600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (ec == Boolean.TYPE) 162600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang clone_obj = ((boolean []) obj).clone(); 163600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (ec == Byte.TYPE) 164600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang clone_obj = ((byte []) obj).clone(); 165600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (ec == Short.TYPE) 166600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang clone_obj = ((short []) obj).clone(); 167600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (ec == Integer.TYPE) 168600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang clone_obj = ((int []) obj).clone(); 169600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (ec == Long.TYPE) 170600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang clone_obj = ((long []) obj).clone(); 171600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (ec == Float.TYPE) 172600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang clone_obj = ((float []) obj).clone(); 173600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (ec == Double.TYPE) 174600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang clone_obj = ((double []) obj).clone(); 175600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 176600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (GenericObject.class.isAssignableFrom (c)) 177600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang clone_obj = ((GenericObject) obj).clone(); 178600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (GenericObjectList.class.isAssignableFrom (c)) 179600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang clone_obj = ((GenericObjectList) obj).clone(); 180600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (Cloneable.class.isAssignableFrom (c)) { 181600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // If a clone method exists for the object, then 182600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // invoke it 183600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 184600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Method meth = c.getMethod("clone", (Class[]) null); 185600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang clone_obj = meth.invoke(obj,(Object[]) null); 186600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (SecurityException ex) { 187600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (IllegalArgumentException ex) { 188600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang InternalErrorHandler.handleException(ex); 189600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (IllegalAccessException ex) { 190600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (InvocationTargetException ex) { 191600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (NoSuchMethodException ex) { 192600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 193600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 194600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return clone_obj; 195600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 196600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 197600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** Clones this object. 198600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 199600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public Object clone() { 200600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 201600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return super.clone(); 202600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (CloneNotSupportedException e) { 203600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new RuntimeException("Internal error"); 204600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 205600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 206600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 207600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Recursively override the fields of this object with the fields 208600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * of a new object. This is useful when you want to genrate a template 209600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * and override the fields of an incoming SIPMessage with another 210600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * SIP message that you have already generated. 211600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 212600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @param mergeObject is the replacement object. The override 213600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * obect must be of the same class as this object. 214600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Set any fields that you do not want to override as null in the 215600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * mergeOject object. 216600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 217600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public void merge(Object mergeObject) { 218600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Base case. 219600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (mergeObject == null) 220600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return; 221600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 222600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (!mergeObject.getClass().equals(this.getClass())) 223600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new IllegalArgumentException("Bad override object"); 224600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 225600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Class<?> myclass = this.getClass(); 226600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang while (true) { 227600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Field[] fields = myclass.getDeclaredFields(); 228600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang for (int i = 0; i < fields.length; i++) { 229600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Field f = fields[i]; 230600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang int modifier = f.getModifiers(); 231600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (Modifier.isPrivate(modifier)) { 232600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 233600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (Modifier.isStatic(modifier)) { 234600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 235600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (Modifier.isInterface(modifier)) { 236600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 237600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 238600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Class<?> fieldType = f.getType(); 239600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String fname = fieldType.toString(); 240600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 241600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Primitive fields are printed with type: value 242600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (fieldType.isPrimitive()) { 243600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (fname.compareTo("int") == 0) { 244600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang int intfield = f.getInt(mergeObject); 245600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang f.setInt(this, intfield); 246600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("short") == 0) { 247600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang short shortField = f.getShort(mergeObject); 248600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang f.setShort(this, shortField); 249600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("char") == 0) { 250600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang char charField = f.getChar(mergeObject); 251600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang f.setChar(this, charField); 252600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("long") == 0) { 253600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang long longField = f.getLong(mergeObject); 254600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang f.setLong(this, longField); 255600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("boolean") == 0) { 256600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang boolean booleanField = f.getBoolean(mergeObject); 257600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang f.setBoolean(this, booleanField); 258600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("double") == 0) { 259600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang double doubleField = f.getDouble(mergeObject); 260600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang f.setDouble(this, doubleField); 261600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("float") == 0) { 262600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang float floatField = f.getFloat(mergeObject); 263600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang f.setFloat(this, floatField); 264600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 265600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 266600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Object obj = f.get(this); 267600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Object mobj = f.get(mergeObject); 268600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (mobj == null) 269600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 270600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (obj == null) { 271600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang f.set(this, mobj); 272600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 273600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 274600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (obj instanceof GenericObject) { 275600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang GenericObject gobj = (GenericObject) obj; 276600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang gobj.merge(mobj); 277600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 278600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang f.set(this, mobj); 279600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 280600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 281600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (IllegalAccessException ex1) { 282600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ex1.printStackTrace(); 283600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; // we are accessing a private field... 284600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 285600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 286600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang myclass = myclass.getSuperclass(); 287600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (myclass.equals(GenericObject.class)) 288600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang break; 289600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 290600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 291600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 292600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected GenericObject() { 293600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang indentation = 0; 294600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang stringRepresentation = ""; 295600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 296600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 297600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected String getIndentation() { 298600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang char [] chars = new char [indentation]; 299600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang java.util.Arrays.fill (chars, ' '); 300600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return new String (chars); 301600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 302600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 303600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 304600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Add a new string to the accumulated string representation. 305600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 306600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 307600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected void sprint(String a) { 308600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (a == null) { 309600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang stringRepresentation += getIndentation(); 310600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang stringRepresentation += "<null>\n"; 311600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return; 312600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 313600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (a.compareTo("}") == 0 || a.compareTo("]") == 0) { 314600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang indentation--; 315600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 316600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang stringRepresentation += getIndentation(); 317600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang stringRepresentation += a; 318600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang stringRepresentation += "\n"; 319600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (a.compareTo("{") == 0 || a.compareTo("[") == 0) { 320600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang indentation++; 321600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 322600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 323600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 324600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 325600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 326600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Pretty printing function accumulator for objects. 327600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 328600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 329600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected void sprint(Object o) { 330600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(o.toString()); 331600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 332600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 333600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 334600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Pretty printing accumulator function for ints 335600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 336600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 337600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected void sprint(int intField) { 338600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(String.valueOf(intField)); 339600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 340600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 341600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 342600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Pretty printing accumulator function for shorts 343600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 344600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected void sprint(short shortField) { 345600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(String.valueOf(shortField)); 346600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 347600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 348600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 349600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Pretty printing accumulator function for chars 350600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 351600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 352600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected void sprint(char charField) { 353600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(String.valueOf(charField)); 354600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 355600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 356600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 357600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 358600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Pretty printing accumulator function for longs 359600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 360600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 361600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected void sprint(long longField) { 362600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(String.valueOf(longField)); 363600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 364600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 365600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 366600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Pretty printing accumulator function for booleans 367600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 368600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 369600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected void sprint(boolean booleanField) { 370600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(String.valueOf(booleanField)); 371600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 372600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 373600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 374600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Pretty printing accumulator function for doubles 375600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 376600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 377600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected void sprint(double doubleField) { 378600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(String.valueOf(doubleField)); 379600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 380600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 381600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 382600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Pretty printing accumulator function for floats 383600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 384600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 385600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected void sprint(float floatField) { 386600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(String.valueOf(floatField)); 387600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 388600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 389600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 390600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Debug printing function. 391600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 392600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 393600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected void dbgPrint() { 394600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Debug.println(debugDump()); 395600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 396600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 397600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 398600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Debug printing function. 399600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 400600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected void dbgPrint(String s) { 401600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Debug.println(s); 402600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 403600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 404600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 405600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * An introspection based equality predicate for GenericObjects. 406600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang *@param that is the other object to test against. 407600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang *@return true if the objects are euqal and false otherwise 408600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 409600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public boolean equals(Object that) { 410600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if ( that == null ) return false; 411600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (!this.getClass().equals(that.getClass())) 412600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 413600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Class<?> myclass = this.getClass(); 414600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Class<?> hisclass = that.getClass(); 415600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang while (true) { 416600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Field[] fields = myclass.getDeclaredFields(); 417600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Field[] hisfields = hisclass.getDeclaredFields(); 418600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang for (int i = 0; i < fields.length; i++) { 419600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Field f = fields[i]; 420600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Field g = hisfields[i]; 421600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Only print protected and public members. 422600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang int modifier = f.getModifiers(); 423600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) 424600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 425600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Class<?> fieldType = f.getType(); 426600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String fieldName = f.getName(); 427600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (fieldName.compareTo("stringRepresentation") == 0) { 428600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 429600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 430600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (fieldName.compareTo("indentation") == 0) { 431600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 432600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 433600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 434600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Primitive fields are printed with type: value 435600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (fieldType.isPrimitive()) { 436600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String fname = fieldType.toString(); 437600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (fname.compareTo("int") == 0) { 438600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.getInt(this) != g.getInt(that)) 439600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 440600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("short") == 0) { 441600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.getShort(this) != g.getShort(that)) 442600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 443600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("char") == 0) { 444600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.getChar(this) != g.getChar(that)) 445600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 446600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("long") == 0) { 447600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.getLong(this) != g.getLong(that)) 448600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 449600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("boolean") == 0) { 450600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.getBoolean(this) != g.getBoolean(that)) 451600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 452600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("double") == 0) { 453600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.getDouble(this) != g.getDouble(that)) 454600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 455600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("float") == 0) { 456600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.getFloat(this) != g.getFloat(that)) 457600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 458600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 459600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (g.get(that) == f.get(this)) 460600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return true; 461600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (f.get(this) == null) 462600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 463600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (g.get(that) == null) 464600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 465600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (g.get(that) == null && f.get(this) != null) 466600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 467600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (!f.get(this).equals(g.get(that))) 468600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 469600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (IllegalAccessException ex1) { 470600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang InternalErrorHandler.handleException(ex1); 471600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 472600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 473600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (myclass.equals(GenericObject.class)) 474600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang break; 475600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else { 476600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang myclass = myclass.getSuperclass(); 477600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang hisclass = hisclass.getSuperclass(); 478600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 479600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 480600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 481600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return true; 482600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 483600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 484600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** An introspection based predicate matching using a template 485600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * object. Allows for partial match of two protocl Objects. 486600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang *@param other the match pattern to test against. The match object 487600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * has to be of the same type (class). Primitive types 488600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * and non-sip fields that are non null are matched for equality. 489600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Null in any field matches anything. Some book-keeping fields 490600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * are ignored when making the comparison. 491600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 492600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 493600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public boolean match(Object other) { 494600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (other == null) 495600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return true; 496600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (!this.getClass().equals(other.getClass())) 497600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 498600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang GenericObject that = (GenericObject) other; 499600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Class<?> myclass = this.getClass(); 500600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Field[] fields = myclass.getDeclaredFields(); 501600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Class<?> hisclass = other.getClass(); 502600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Field[] hisfields = hisclass.getDeclaredFields(); 503600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang for (int i = 0; i < fields.length; i++) { 504600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Field f = fields[i]; 505600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Field g = hisfields[i]; 506600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Only print protected and public members. 507600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang int modifier = f.getModifiers(); 508600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) 509600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 510600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Class<?> fieldType = f.getType(); 511600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String fieldName = f.getName(); 512600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (fieldName.compareTo("stringRepresentation") == 0) { 513600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 514600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 515600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (fieldName.compareTo("indentation") == 0) { 516600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 517600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 518600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 519600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Primitive fields are printed with type: value 520600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (fieldType.isPrimitive()) { 521600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String fname = fieldType.toString(); 522600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (fname.compareTo("int") == 0) { 523600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.getInt(this) != g.getInt(that)) 524600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 525600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("short") == 0) { 526600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.getShort(this) != g.getShort(that)) 527600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 528600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("char") == 0) { 529600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.getChar(this) != g.getChar(that)) 530600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 531600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("long") == 0) { 532600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.getLong(this) != g.getLong(that)) 533600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 534600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("boolean") == 0) { 535600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.getBoolean(this) != g.getBoolean(that)) 536600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 537600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("double") == 0) { 538600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.getDouble(this) != g.getDouble(that)) 539600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 540600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("float") == 0) { 541600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.getFloat(this) != g.getFloat(that)) 542600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 543600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 544600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 545600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Object myObj = f.get(this); 546600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Object hisObj = g.get(that); 547600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (hisObj != null && myObj == null) 548600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 549600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (hisObj == null && myObj != null) 550600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 551600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (hisObj == null && myObj == null) 552600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 553600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if ( 554600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang hisObj instanceof java.lang.String 555600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang && myObj instanceof java.lang.String) { 556600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if ((((String) hisObj).trim()).equals("")) 557600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 558600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (((String) myObj) 559600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .compareToIgnoreCase((String) hisObj) 560600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang != 0) 561600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 562600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if ( 563600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang GenericObject.isMySubclass(myObj.getClass()) 564600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang && !((GenericObject) myObj).match(hisObj)) 565600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 566600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if ( 567600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang GenericObjectList.isMySubclass(myObj.getClass()) 568600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang && !((GenericObjectList) myObj).match(hisObj)) 569600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return false; 570600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 571600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 572600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (IllegalAccessException ex1) { 573600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang InternalErrorHandler.handleException(ex1); 574600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 575600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 576600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return true; 577600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 578600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 579600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 580600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Generic print formatting function: 581600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Does depth-first descent of the structure and 582600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * recursively prints all non-private objects pointed to 583600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * by this object. 584600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * <bf> 585600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Warning - the following generic string routine will 586600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * bomb (go into infinite loop) if there are any circularly linked 587600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * structures so if you have these, they had better be private! 588600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * </bf> 589600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * We dont have to worry about such things for our structures 590600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang *(we never use circular linked structures). 591600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 592600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 593600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public String debugDump() { 594600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang stringRepresentation = ""; 595600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Class<?> myclass = getClass(); 596600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(myclass.getName()); 597600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint("{"); 598600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Field[] fields = myclass.getDeclaredFields(); 599600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang for (int i = 0; i < fields.length; i++) { 600600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Field f = fields[i]; 601600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Only print protected and public members. 602600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang int modifier = f.getModifiers(); 603600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) 604600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 605600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Class<?> fieldType = f.getType(); 606600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String fieldName = f.getName(); 607600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (fieldName.compareTo("stringRepresentation") == 0) { 608600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // avoid nasty recursions... 609600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 610600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 611600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (fieldName.compareTo("indentation") == 0) { 612600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // formatting stuff - not relevant here. 613600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; 614600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 615600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(fieldName + ":"); 616600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 617600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Primitive fields are printed with type: value 618600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (fieldType.isPrimitive()) { 619600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String fname = fieldType.toString(); 620600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(fname + ":"); 621600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (fname.compareTo("int") == 0) { 622600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang int intfield = f.getInt(this); 623600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(intfield); 624600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("short") == 0) { 625600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang short shortField = f.getShort(this); 626600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(shortField); 627600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("char") == 0) { 628600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang char charField = f.getChar(this); 629600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(charField); 630600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("long") == 0) { 631600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang long longField = f.getLong(this); 632600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(longField); 633600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("boolean") == 0) { 634600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang boolean booleanField = f.getBoolean(this); 635600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(booleanField); 636600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("double") == 0) { 637600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang double doubleField = f.getDouble(this); 638600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(doubleField); 639600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (fname.compareTo("float") == 0) { 640600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang float floatField = f.getFloat(this); 641600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(floatField); 642600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 643600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (GenericObject.class.isAssignableFrom(fieldType)) { 644600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.get(this) != null) { 645600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint( 646600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ((GenericObject) f.get(this)).debugDump( 647600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang indentation + 1)); 648600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 649600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint("<null>"); 650600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 651600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 652600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if ( 653600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang GenericObjectList.class.isAssignableFrom(fieldType)) { 654600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.get(this) != null) { 655600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint( 656600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ((GenericObjectList) f.get(this)).debugDump( 657600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang indentation + 1)); 658600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 659600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint("<null>"); 660600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 661600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 662600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 663600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Dont do recursion on things that are not 664600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // of our header type... 665600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.get(this) != null) { 666600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(f.get(this).getClass().getName() + ":"); 667600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 668600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(fieldType.getName() + ":"); 669600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 670600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 671600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint("{"); 672600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (f.get(this) != null) { 673600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint(f.get(this).toString()); 674600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 675600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint("<null>"); 676600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 677600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint("}"); 678600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 679600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (IllegalAccessException ex1) { 680600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang continue; // we are accessing a private field... 681600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (Exception ex) { 682600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang InternalErrorHandler.handleException(ex); 683600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 684600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 685600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sprint("}"); 686600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return stringRepresentation; 687600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 688600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 689600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 690600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Formatter with a given starting indentation. 691600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 692600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public String debugDump(int indent) { 693600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang indentation = indent; 694600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String retval = this.debugDump(); 695600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang indentation = 0; 696600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return retval; 697600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 698600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 699600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 700600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 701600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Get the string encoded version of this object 702600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @since v1.0 703600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 704600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public abstract String encode(); 705600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 706600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 707600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Put the encoded version of this object in the given StringBuffer. 708600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 709600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public StringBuffer encode(StringBuffer buffer) { 710600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return buffer.append(encode()); 711600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 712600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang} 713