content: /*
  * 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 gov2.nist.javax2.sip.address;
  
  import gov2.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 {
  
      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();
      }
  }
  