| /* |
| * Conditions Of Use |
| * |
| * This software was developed by employees of the National Institute of |
| * Standards and Technology (NIST), an agency of the Federal Government. |
| * Pursuant to title 15 Untied States Code Section 105, works of NIST |
| * employees are not subject to copyright protection in the United States |
| * and are considered to be in the public domain. As a result, a formal |
| * license is not needed to use the software. |
| * |
| * This software is provided by NIST as a service and is expressly |
| * provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED |
| * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT |
| * AND DATA ACCURACY. NIST does not warrant or make any representations |
| * regarding the use of the software or the results thereof, including but |
| * not limited to the correctness, accuracy, reliability or usefulness of |
| * the software. |
| * |
| * Permission to use this software is contingent upon your acceptance |
| * of the terms of this agreement |
| * |
| * . |
| * |
| */ |
| /******************************************************************************* |
| * Product of NIST/ITL Advanced Networking Technologies Division (ANTD). * |
| *******************************************************************************/ |
| package gov.nist.javax.sip.address; |
| |
| import gov.nist.core.*; |
| |
| import java.lang.reflect.*; |
| |
| /** |
| * Root object for all objects in this package. |
| * |
| * @version 1.2 $Revision: 1.10 $ $Date: 2009/07/17 18:57:22 $ |
| * |
| * @author M. Ranganathan <br/> |
| * |
| * |
| */ |
| public abstract class NetObject extends GenericObject { |
| |
| // BEGIN android-added |
| protected static final long serialVersionUID = 6149926203633320729L; |
| // END android-added |
| |
| protected static final String CORE_PACKAGE = PackageNames.CORE_PACKAGE; |
| protected static final String NET_PACKAGE = PackageNames.NET_PACKAGE; |
| protected static final String PARSER_PACKAGE = PackageNames.PARSER_PACKAGE; |
| protected static final String UDP = "udp"; |
| protected static final String TCP = "tcp"; |
| protected static final String TRANSPORT = "transport"; |
| protected static final String METHOD = "method"; |
| protected static final String USER = "user"; |
| protected static final String PHONE = "phone"; |
| protected static final String MADDR = "maddr"; |
| protected static final String TTL = "ttl"; |
| protected static final String LR = "lr"; |
| protected static final String SIP = "sip"; |
| protected static final String SIPS = "sips"; |
| |
| // Added by Daniel J. Martinez Manzano <dani@dif.um.es> |
| protected static final String TLS = "tls"; |
| |
| // Added by Peter Musgrave <pmusgrave@newheights.com> |
| // params for outbound and gruu drafts |
| protected static final String GRUU = "gr"; |
| |
| |
| /** Default constructor |
| */ |
| public NetObject() { |
| super(); |
| } |
| |
| /** |
| * An introspection based equality predicate for SIPObjects. |
| *@param that is the other object to test against. |
| */ |
| public boolean equals(Object that) { |
| if (!this.getClass().equals(that.getClass())) |
| return false; |
| Class<?> myclass = this.getClass(); |
| Class<?> hisclass = that.getClass(); |
| while (true) { |
| Field[] fields = myclass.getDeclaredFields(); |
| Field[] hisfields = hisclass.getDeclaredFields(); |
| for (int i = 0; i < fields.length; i++) { |
| Field f = fields[i]; |
| Field g = hisfields[i]; |
| // Only print protected and public members. |
| int modifier = f.getModifiers(); |
| if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) |
| continue; |
| Class<?> fieldType = f.getType(); |
| String fieldName = f.getName(); |
| if (fieldName.compareTo("stringRepresentation") == 0) { |
| continue; |
| } |
| if (fieldName.compareTo("indentation") == 0) { |
| continue; |
| } |
| try { |
| // Primitive fields are printed with type: value |
| if (fieldType.isPrimitive()) { |
| String fname = fieldType.toString(); |
| if (fname.compareTo("int") == 0) { |
| if (f.getInt(this) != g.getInt(that)) |
| return false; |
| } else if (fname.compareTo("short") == 0) { |
| if (f.getShort(this) != g.getShort(that)) |
| return false; |
| } else if (fname.compareTo("char") == 0) { |
| if (f.getChar(this) != g.getChar(that)) |
| return false; |
| } else if (fname.compareTo("long") == 0) { |
| if (f.getLong(this) != g.getLong(that)) |
| return false; |
| } else if (fname.compareTo("boolean") == 0) { |
| if (f.getBoolean(this) != g.getBoolean(that)) |
| return false; |
| } else if (fname.compareTo("double") == 0) { |
| if (f.getDouble(this) != g.getDouble(that)) |
| return false; |
| } else if (fname.compareTo("float") == 0) { |
| if (f.getFloat(this) != g.getFloat(that)) |
| return false; |
| } |
| } else if (g.get(that) == f.get(this)) |
| continue; |
| else if (f.get(this) == null && g.get(that) != null) |
| return false; |
| else if (g.get(that) == null && f.get(that) != null) |
| return false; |
| else if (!f.get(this).equals(g.get(that))) |
| return false; |
| } catch (IllegalAccessException ex1) { |
| InternalErrorHandler.handleException(ex1); |
| } |
| } |
| if (myclass.equals(NetObject.class)) |
| break; |
| else { |
| myclass = myclass.getSuperclass(); |
| hisclass = hisclass.getSuperclass(); |
| } |
| } |
| return true; |
| } |
| |
| |
| |
| |
| /** An introspection based predicate matching using a template |
| * object. Allows for partial match of two protocl Objects. |
| *@param other the match pattern to test against. The match object |
| * has to be of the same type (class). Primitive types |
| * and non-sip fields that are non null are matched for equality. |
| * Null in any field matches anything. Some book-keeping fields |
| * are ignored when making the comparison. |
| *@return true if match succeeds false otherwise. |
| */ |
| |
| public boolean match(Object other) { |
| if (other == null) |
| return true; |
| if (!this.getClass().equals(other.getClass())) |
| return false; |
| GenericObject that = (GenericObject) other; |
| // System.out.println("Comparing " + that.encode()); |
| // System.out.println("this = " + this.encode()); |
| |
| Class<?> hisclass = other.getClass(); |
| Class<?> myclass = this.getClass(); |
| while (true) { |
| Field[] fields = myclass.getDeclaredFields(); |
| Field[] hisfields = hisclass.getDeclaredFields(); |
| for (int i = 0; i < fields.length; i++) { |
| Field f = fields[i]; |
| Field g = hisfields[i]; |
| // Only print protected and public members. |
| int modifier = f.getModifiers(); |
| if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) |
| continue; |
| Class<?> fieldType = f.getType(); |
| String fieldName = f.getName(); |
| if (fieldName.compareTo("stringRepresentation") == 0) { |
| continue; |
| } |
| if (fieldName.compareTo("indentation") == 0) { |
| continue; |
| } |
| try { |
| // Primitive fields are printed with type: value |
| if (fieldType.isPrimitive()) { |
| String fname = fieldType.toString(); |
| if (fname.compareTo("int") == 0) { |
| if (f.getInt(this) != g.getInt(that)) |
| return false; |
| } else if (fname.compareTo("short") == 0) { |
| if (f.getShort(this) != g.getShort(that)) |
| return false; |
| } else if (fname.compareTo("char") == 0) { |
| if (f.getChar(this) != g.getChar(that)) |
| return false; |
| } else if (fname.compareTo("long") == 0) { |
| if (f.getLong(this) != g.getLong(that)) |
| return false; |
| } else if (fname.compareTo("boolean") == 0) { |
| if (f.getBoolean(this) != g.getBoolean(that)) |
| return false; |
| } else if (fname.compareTo("double") == 0) { |
| if (f.getDouble(this) != g.getDouble(that)) |
| return false; |
| } else if (fname.compareTo("float") == 0) { |
| if (f.getFloat(this) != g.getFloat(that)) |
| return false; |
| } |
| } else { |
| Object myObj = f.get(this); |
| Object hisObj = g.get(that); |
| if (hisObj != null && myObj == null) |
| return false; |
| else if (hisObj == null && myObj != null) |
| continue; |
| else if (hisObj == null && myObj == null) |
| continue; |
| else if ( |
| hisObj instanceof java.lang.String |
| && myObj instanceof java.lang.String) { |
| if (((String) hisObj).equals("")) |
| continue; |
| if (((String) myObj) |
| .compareToIgnoreCase((String) hisObj) |
| != 0) |
| return false; |
| } else if ( |
| GenericObject.isMySubclass(myObj.getClass()) |
| && GenericObject.isMySubclass(hisObj.getClass()) |
| && myObj.getClass().equals(hisObj.getClass()) |
| && ((GenericObject) hisObj).getMatcher() |
| != null) { |
| String myObjEncoded = |
| ((GenericObject) myObj).encode(); |
| boolean retval = |
| ((GenericObject) hisObj).getMatcher().match( |
| myObjEncoded); |
| if (!retval) |
| return false; |
| } else if ( |
| GenericObject.isMySubclass(myObj.getClass()) |
| && !((GenericObject) myObj).match(hisObj)) |
| return false; |
| else if ( |
| GenericObjectList.isMySubclass(myObj.getClass()) |
| && !((GenericObjectList) myObj).match(hisObj)) |
| return false; |
| } |
| } catch (IllegalAccessException ex1) { |
| InternalErrorHandler.handleException(ex1); |
| } |
| } |
| if (myclass.equals(NetObject.class)) |
| break; |
| else { |
| myclass = myclass.getSuperclass(); |
| hisclass = hisclass.getSuperclass(); |
| } |
| } |
| return true; |
| } |
| |
| /** |
| * An introspection based string formatting method. We need this because |
| * in this package (although it is an exact duplicate of the one in |
| * the superclass) because it needs to access the protected members |
| * of the other objects in this class. |
| * @return String |
| */ |
| public String debugDump() { |
| stringRepresentation = ""; |
| Class<?> myclass = getClass(); |
| sprint(myclass.getName()); |
| sprint("{"); |
| Field[] fields = myclass.getDeclaredFields(); |
| for (int i = 0; i < fields.length; i++) { |
| Field f = fields[i]; |
| // Only print protected and public members. |
| int modifier = f.getModifiers(); |
| if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE) |
| continue; |
| Class<?> fieldType = f.getType(); |
| String fieldName = f.getName(); |
| if (fieldName.compareTo("stringRepresentation") == 0) { |
| // avoid nasty recursions... |
| continue; |
| } |
| if (fieldName.compareTo("indentation") == 0) { |
| // formatting stuff - not relevant here. |
| continue; |
| } |
| sprint(fieldName + ":"); |
| try { |
| // Primitive fields are printed with type: value |
| if (fieldType.isPrimitive()) { |
| String fname = fieldType.toString(); |
| sprint(fname + ":"); |
| if (fname.compareTo("int") == 0) { |
| int intfield = f.getInt(this); |
| sprint(intfield); |
| } else if (fname.compareTo("short") == 0) { |
| short shortField = f.getShort(this); |
| sprint(shortField); |
| } else if (fname.compareTo("char") == 0) { |
| char charField = f.getChar(this); |
| sprint(charField); |
| } else if (fname.compareTo("long") == 0) { |
| long longField = f.getLong(this); |
| sprint(longField); |
| } else if (fname.compareTo("boolean") == 0) { |
| boolean booleanField = f.getBoolean(this); |
| sprint(booleanField); |
| } else if (fname.compareTo("double") == 0) { |
| double doubleField = f.getDouble(this); |
| sprint(doubleField); |
| } else if (fname.compareTo("float") == 0) { |
| float floatField = f.getFloat(this); |
| sprint(floatField); |
| } |
| } else if (GenericObject.class.isAssignableFrom(fieldType)) { |
| if (f.get(this) != null) { |
| sprint( |
| ((GenericObject) f.get(this)).debugDump( |
| indentation + 1)); |
| } else { |
| sprint("<null>"); |
| } |
| |
| } else if ( |
| GenericObjectList.class.isAssignableFrom(fieldType)) { |
| if (f.get(this) != null) { |
| sprint( |
| ((GenericObjectList) f.get(this)).debugDump( |
| indentation + 1)); |
| } else { |
| sprint("<null>"); |
| } |
| |
| } else { |
| // Dont do recursion on things that are not |
| // of our header type... |
| if (f.get(this) != null) { |
| sprint(f.get(this).getClass().getName() + ":"); |
| } else { |
| sprint(fieldType.getName() + ":"); |
| } |
| |
| sprint("{"); |
| if (f.get(this) != null) { |
| sprint(f.get(this).toString()); |
| } else { |
| sprint("<null>"); |
| } |
| sprint("}"); |
| } |
| } catch (IllegalAccessException ex1) { |
| continue; // we are accessing a private field... |
| } |
| } |
| sprint("}"); |
| return stringRepresentation; |
| } |
| |
| |
| |
| |
| /** |
| * Formatter with a given starting indentation (for nested structs). |
| * @param indent int to set |
| * @return String |
| */ |
| public String debugDump(int indent) { |
| int save = indentation; |
| indentation = indent; |
| String retval = this.debugDump(); |
| indentation = save; |
| return retval; |
| } |
| |
| /** Encode this to a string. |
| * |
| *@return string representation for this object. |
| */ |
| public String toString() { |
| return this.encode(); |
| } |
| } |