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.javax.sip.address;
30600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
31600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.core.*;
32600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
33600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.lang.reflect.*;
34600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
35600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang/**
36600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Root object for all objects in this package.
37600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang *
38600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @version 1.2 $Revision: 1.10 $ $Date: 2009/07/17 18:57:22 $
39600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang *
40600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @author M. Ranganathan   <br/>
41600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang *
42600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang *
43600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */
44600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangpublic abstract class NetObject extends GenericObject {
45600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
46600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    protected static final String CORE_PACKAGE = PackageNames.CORE_PACKAGE;
47600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    protected static final String NET_PACKAGE = PackageNames.NET_PACKAGE;
48600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    protected static final String PARSER_PACKAGE = PackageNames.PARSER_PACKAGE;
49600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    protected static final String UDP = "udp";
50600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    protected static final String TCP = "tcp";
51600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    protected static final String TRANSPORT = "transport";
52600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    protected static final String METHOD = "method";
53600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    protected static final String USER = "user";
54600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    protected static final String PHONE = "phone";
55600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    protected static final String MADDR = "maddr";
56600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    protected static final String TTL = "ttl";
57600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    protected static final String LR = "lr";
58600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    protected static final String SIP = "sip";
59600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    protected static final String SIPS = "sips";
60600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
61600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    // Added by Daniel J. Martinez Manzano <dani@dif.um.es>
62600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    protected static final String TLS = "tls";
63600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
64600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    // Added by Peter Musgrave <pmusgrave@newheights.com>
65600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    // params for outbound and gruu drafts
66600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    protected static final String GRUU = "gr";
67600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
68600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
69600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    /** Default constructor
70600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     */
71600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public NetObject() {
72600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        super();
73600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
74600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
75600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    /**
76600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     * An introspection based equality predicate for SIPObjects.
77600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     *@param that is the other object to test against.
78600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     */
79600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public boolean equals(Object that) {
80600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        if (!this.getClass().equals(that.getClass()))
81600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            return false;
82600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        Class<?> myclass = this.getClass();
83600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        Class<?> hisclass = that.getClass();
84600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        while (true) {
85600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            Field[] fields = myclass.getDeclaredFields();
86600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            Field[] hisfields = hisclass.getDeclaredFields();
87600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            for (int i = 0; i < fields.length; i++) {
88600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                Field f = fields[i];
89600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                Field g = hisfields[i];
90600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                // Only print protected and public members.
91600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                int modifier = f.getModifiers();
92600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE)
93600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    continue;
94600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                Class<?> fieldType = f.getType();
95600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                String fieldName = f.getName();
96600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                if (fieldName.compareTo("stringRepresentation") == 0) {
97600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    continue;
98600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                }
99600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                if (fieldName.compareTo("indentation") == 0) {
100600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    continue;
101600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                }
102600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                try {
103600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    // Primitive fields are printed with type: value
104600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    if (fieldType.isPrimitive()) {
105600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        String fname = fieldType.toString();
106600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        if (fname.compareTo("int") == 0) {
107600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (f.getInt(this) != g.getInt(that))
108600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                return false;
109600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        } else if (fname.compareTo("short") == 0) {
110600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (f.getShort(this) != g.getShort(that))
111600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                return false;
112600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        } else if (fname.compareTo("char") == 0) {
113600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (f.getChar(this) != g.getChar(that))
114600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                return false;
115600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        } else if (fname.compareTo("long") == 0) {
116600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (f.getLong(this) != g.getLong(that))
117600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                return false;
118600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        } else if (fname.compareTo("boolean") == 0) {
119600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (f.getBoolean(this) != g.getBoolean(that))
120600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                return false;
121600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        } else if (fname.compareTo("double") == 0) {
122600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (f.getDouble(this) != g.getDouble(that))
123600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                return false;
124600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        } else if (fname.compareTo("float") == 0) {
125600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (f.getFloat(this) != g.getFloat(that))
126600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                return false;
127600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        }
128600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    } else if (g.get(that) == f.get(this))
129600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        continue;
130600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    else if (f.get(this) == null && g.get(that) != null)
131600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        return false;
132600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    else if (g.get(that) == null && f.get(that) != null)
133600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        return false;
134600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    else if (!f.get(this).equals(g.get(that)))
135600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        return false;
136600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                } catch (IllegalAccessException ex1) {
137600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    InternalErrorHandler.handleException(ex1);
138600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                }
139600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            }
140600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            if (myclass.equals(NetObject.class))
141600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                break;
142600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            else {
143600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                myclass = myclass.getSuperclass();
144600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                hisclass = hisclass.getSuperclass();
145600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            }
146600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        }
147600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return true;
148600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
149600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
150600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
151600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
152600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
153600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    /** An introspection based predicate matching using a template
154600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     * object. Allows for partial match of two protocl Objects.
155600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     *@param other the match pattern to test against. The match object
156600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     * has to be of the same type (class). Primitive types
157600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     * and non-sip fields that are non null are matched for equality.
158600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     * Null in any field  matches anything. Some book-keeping fields
159600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     * are ignored when making the comparison.
160600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     *@return true if match succeeds false otherwise.
161600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     */
162600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
163600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public boolean match(Object other) {
164600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        if (other == null)
165600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            return true;
166600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        if (!this.getClass().equals(other.getClass()))
167600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            return false;
168600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        GenericObject that = (GenericObject) other;
169600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        // System.out.println("Comparing " + that.encode());
170600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        // System.out.println("this = " + this.encode());
171600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
172600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        Class<?> hisclass = other.getClass();
173600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        Class<?> myclass = this.getClass();
174600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        while (true) {
175600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            Field[] fields = myclass.getDeclaredFields();
176600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            Field[] hisfields = hisclass.getDeclaredFields();
177600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            for (int i = 0; i < fields.length; i++) {
178600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                Field f = fields[i];
179600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                Field g = hisfields[i];
180600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                // Only print protected and public members.
181600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                int modifier = f.getModifiers();
182600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE)
183600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    continue;
184600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                Class<?> fieldType = f.getType();
185600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                String fieldName = f.getName();
186600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                if (fieldName.compareTo("stringRepresentation") == 0) {
187600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    continue;
188600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                }
189600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                if (fieldName.compareTo("indentation") == 0) {
190600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    continue;
191600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                }
192600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                try {
193600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    // Primitive fields are printed with type: value
194600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    if (fieldType.isPrimitive()) {
195600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        String fname = fieldType.toString();
196600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        if (fname.compareTo("int") == 0) {
197600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (f.getInt(this) != g.getInt(that))
198600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                return false;
199600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        } else if (fname.compareTo("short") == 0) {
200600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (f.getShort(this) != g.getShort(that))
201600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                return false;
202600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        } else if (fname.compareTo("char") == 0) {
203600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (f.getChar(this) != g.getChar(that))
204600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                return false;
205600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        } else if (fname.compareTo("long") == 0) {
206600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (f.getLong(this) != g.getLong(that))
207600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                return false;
208600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        } else if (fname.compareTo("boolean") == 0) {
209600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (f.getBoolean(this) != g.getBoolean(that))
210600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                return false;
211600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        } else if (fname.compareTo("double") == 0) {
212600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (f.getDouble(this) != g.getDouble(that))
213600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                return false;
214600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        } else if (fname.compareTo("float") == 0) {
215600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (f.getFloat(this) != g.getFloat(that))
216600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                return false;
217600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        }
218600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    } else {
219600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        Object myObj = f.get(this);
220600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        Object hisObj = g.get(that);
221600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        if (hisObj != null && myObj == null)
222600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            return false;
223600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        else if (hisObj == null && myObj != null)
224600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            continue;
225600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        else if (hisObj == null && myObj == null)
226600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            continue;
227600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        else if (
228600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            hisObj instanceof java.lang.String
229600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                && myObj instanceof java.lang.String) {
230600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (((String) hisObj).equals(""))
231600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                continue;
232600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (((String) myObj)
233600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                .compareToIgnoreCase((String) hisObj)
234600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                != 0)
235600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                return false;
236600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        } else if (
237600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            GenericObject.isMySubclass(myObj.getClass())
238600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                && GenericObject.isMySubclass(hisObj.getClass())
239600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                && myObj.getClass().equals(hisObj.getClass())
240600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                && ((GenericObject) hisObj).getMatcher()
241600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                    != null) {
242600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            String myObjEncoded =
243600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                ((GenericObject) myObj).encode();
244600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            boolean retval =
245600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                ((GenericObject) hisObj).getMatcher().match(
246600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                    myObjEncoded);
247600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            if (!retval)
248600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                return false;
249600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        } else if (
250600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            GenericObject.isMySubclass(myObj.getClass())
251600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                && !((GenericObject) myObj).match(hisObj))
252600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            return false;
253600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        else if (
254600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            GenericObjectList.isMySubclass(myObj.getClass())
255600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                && !((GenericObjectList) myObj).match(hisObj))
256600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            return false;
257600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    }
258600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                } catch (IllegalAccessException ex1) {
259600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    InternalErrorHandler.handleException(ex1);
260600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                }
261600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            }
262600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            if (myclass.equals(NetObject.class))
263600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                break;
264600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            else {
265600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                myclass = myclass.getSuperclass();
266600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                hisclass = hisclass.getSuperclass();
267600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            }
268600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        }
269600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return true;
270600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
271600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
272600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    /**
273600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     * An introspection based string formatting method. We need this because
274600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     * in this package (although it is an exact duplicate of the one in
275600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     * the superclass) because it needs to access the protected members
276600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     * of the other objects in this class.
277600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     * @return String
278600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     */
279600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public String debugDump() {
280600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        stringRepresentation = "";
281600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        Class<?> myclass = getClass();
282600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        sprint(myclass.getName());
283600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        sprint("{");
284600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        Field[] fields = myclass.getDeclaredFields();
285600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        for (int i = 0; i < fields.length; i++) {
286600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            Field f = fields[i];
287600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            // Only print protected and public members.
288600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            int modifier = f.getModifiers();
289600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE)
290600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                continue;
291600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            Class<?> fieldType = f.getType();
292600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            String fieldName = f.getName();
293600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            if (fieldName.compareTo("stringRepresentation") == 0) {
294600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                // avoid nasty recursions...
295600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                continue;
296600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            }
297600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            if (fieldName.compareTo("indentation") == 0) {
298600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                // formatting stuff - not relevant here.
299600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                continue;
300600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            }
301600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            sprint(fieldName + ":");
302600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            try {
303600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                // Primitive fields are printed with type: value
304600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                if (fieldType.isPrimitive()) {
305600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    String fname = fieldType.toString();
306600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    sprint(fname + ":");
307600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    if (fname.compareTo("int") == 0) {
308600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        int intfield = f.getInt(this);
309600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        sprint(intfield);
310600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    } else if (fname.compareTo("short") == 0) {
311600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        short shortField = f.getShort(this);
312600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        sprint(shortField);
313600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    } else if (fname.compareTo("char") == 0) {
314600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        char charField = f.getChar(this);
315600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        sprint(charField);
316600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    } else if (fname.compareTo("long") == 0) {
317600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        long longField = f.getLong(this);
318600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        sprint(longField);
319600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    } else if (fname.compareTo("boolean") == 0) {
320600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        boolean booleanField = f.getBoolean(this);
321600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        sprint(booleanField);
322600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    } else if (fname.compareTo("double") == 0) {
323600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        double doubleField = f.getDouble(this);
324600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        sprint(doubleField);
325600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    } else if (fname.compareTo("float") == 0) {
326600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        float floatField = f.getFloat(this);
327600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        sprint(floatField);
328600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    }
329600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                } else if (GenericObject.class.isAssignableFrom(fieldType)) {
330600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    if (f.get(this) != null) {
331600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        sprint(
332600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            ((GenericObject) f.get(this)).debugDump(
333600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                indentation + 1));
334600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    } else {
335600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        sprint("<null>");
336600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    }
337600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
338600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                } else if (
339600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    GenericObjectList.class.isAssignableFrom(fieldType)) {
340600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    if (f.get(this) != null) {
341600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        sprint(
342600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                            ((GenericObjectList) f.get(this)).debugDump(
343600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                                indentation + 1));
344600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    } else {
345600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        sprint("<null>");
346600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    }
347600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
348600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                } else {
349600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    // Dont do recursion on things that are not
350600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    // of our header type...
351600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    if (f.get(this) != null) {
352600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        sprint(f.get(this).getClass().getName() + ":");
353600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    } else {
354600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        sprint(fieldType.getName() + ":");
355600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    }
356600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
357600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    sprint("{");
358600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    if (f.get(this) != null) {
359600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        sprint(f.get(this).toString());
360600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    } else {
361600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                        sprint("<null>");
362600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    }
363600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                    sprint("}");
364600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                }
365600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            } catch (IllegalAccessException ex1) {
366600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang                continue; // we are accessing a private field...
367600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang            }
368600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        }
369600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        sprint("}");
370600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return stringRepresentation;
371600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
372600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
373600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
374600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
375600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
376600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    /**
377600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     * Formatter with a given starting indentation (for nested structs).
378600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     * @param indent int to set
379600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     * @return String
380600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     */
381600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public String debugDump(int indent) {
382600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        int save = indentation;
383600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        indentation = indent;
384600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        String retval = this.debugDump();
385600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        indentation = save;
386600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return retval;
387600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
388600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang
389600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    /** Encode this to a string.
390600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     *
391600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     *@return string representation for this object.
392600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang     */
393600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    public String toString() {
394600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang        return this.encode();
395600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang    }
396600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang}
397