Home | History | Annotate | Download | only in address
      1 /*
      2 * Conditions Of Use
      3 *
      4 * This software was developed by employees of the National Institute of
      5 * Standards and Technology (NIST), an agency of the Federal Government.
      6 * Pursuant to title 15 Untied States Code Section 105, works of NIST
      7 * employees are not subject to copyright protection in the United States
      8 * and are considered to be in the public domain.  As a result, a formal
      9 * license is not needed to use the software.
     10 *
     11 * This software is provided by NIST as a service and is expressly
     12 * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
     13 * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
     14 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
     15 * AND DATA ACCURACY.  NIST does not warrant or make any representations
     16 * regarding the use of the software or the results thereof, including but
     17 * not limited to the correctness, accuracy, reliability or usefulness of
     18 * the software.
     19 *
     20 * Permission to use this software is contingent upon your acceptance
     21 * of the terms of this agreement
     22 *
     23 * .
     24 *
     25 */
     26 /*******************************************************************************
     27  * Product of NIST/ITL Advanced Networking Technologies Division (ANTD).        *
     28  *******************************************************************************/
     29 package gov.nist.javax.sip.address;
     30 
     31 import gov.nist.core.*;
     32 
     33 import java.lang.reflect.*;
     34 
     35 /**
     36  * Root object for all objects in this package.
     37  *
     38  * @version 1.2 $Revision: 1.10 $ $Date: 2009/07/17 18:57:22 $
     39  *
     40  * @author M. Ranganathan   <br/>
     41  *
     42  *
     43  */
     44 public abstract class NetObject extends GenericObject {
     45 
     46     protected static final String CORE_PACKAGE = PackageNames.CORE_PACKAGE;
     47     protected static final String NET_PACKAGE = PackageNames.NET_PACKAGE;
     48     protected static final String PARSER_PACKAGE = PackageNames.PARSER_PACKAGE;
     49     protected static final String UDP = "udp";
     50     protected static final String TCP = "tcp";
     51     protected static final String TRANSPORT = "transport";
     52     protected static final String METHOD = "method";
     53     protected static final String USER = "user";
     54     protected static final String PHONE = "phone";
     55     protected static final String MADDR = "maddr";
     56     protected static final String TTL = "ttl";
     57     protected static final String LR = "lr";
     58     protected static final String SIP = "sip";
     59     protected static final String SIPS = "sips";
     60 
     61     // Added by Daniel J. Martinez Manzano <dani (at) dif.um.es>
     62     protected static final String TLS = "tls";
     63 
     64     // Added by Peter Musgrave <pmusgrave (at) newheights.com>
     65     // params for outbound and gruu drafts
     66     protected static final String GRUU = "gr";
     67 
     68 
     69     /** Default constructor
     70      */
     71     public NetObject() {
     72         super();
     73     }
     74 
     75     /**
     76      * An introspection based equality predicate for SIPObjects.
     77      *@param that is the other object to test against.
     78      */
     79     public boolean equals(Object that) {
     80         if (!this.getClass().equals(that.getClass()))
     81             return false;
     82         Class<?> myclass = this.getClass();
     83         Class<?> hisclass = that.getClass();
     84         while (true) {
     85             Field[] fields = myclass.getDeclaredFields();
     86             Field[] hisfields = hisclass.getDeclaredFields();
     87             for (int i = 0; i < fields.length; i++) {
     88                 Field f = fields[i];
     89                 Field g = hisfields[i];
     90                 // Only print protected and public members.
     91                 int modifier = f.getModifiers();
     92                 if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE)
     93                     continue;
     94                 Class<?> fieldType = f.getType();
     95                 String fieldName = f.getName();
     96                 if (fieldName.compareTo("stringRepresentation") == 0) {
     97                     continue;
     98                 }
     99                 if (fieldName.compareTo("indentation") == 0) {
    100                     continue;
    101                 }
    102                 try {
    103                     // Primitive fields are printed with type: value
    104                     if (fieldType.isPrimitive()) {
    105                         String fname = fieldType.toString();
    106                         if (fname.compareTo("int") == 0) {
    107                             if (f.getInt(this) != g.getInt(that))
    108                                 return false;
    109                         } else if (fname.compareTo("short") == 0) {
    110                             if (f.getShort(this) != g.getShort(that))
    111                                 return false;
    112                         } else if (fname.compareTo("char") == 0) {
    113                             if (f.getChar(this) != g.getChar(that))
    114                                 return false;
    115                         } else if (fname.compareTo("long") == 0) {
    116                             if (f.getLong(this) != g.getLong(that))
    117                                 return false;
    118                         } else if (fname.compareTo("boolean") == 0) {
    119                             if (f.getBoolean(this) != g.getBoolean(that))
    120                                 return false;
    121                         } else if (fname.compareTo("double") == 0) {
    122                             if (f.getDouble(this) != g.getDouble(that))
    123                                 return false;
    124                         } else if (fname.compareTo("float") == 0) {
    125                             if (f.getFloat(this) != g.getFloat(that))
    126                                 return false;
    127                         }
    128                     } else if (g.get(that) == f.get(this))
    129                         continue;
    130                     else if (f.get(this) == null && g.get(that) != null)
    131                         return false;
    132                     else if (g.get(that) == null && f.get(that) != null)
    133                         return false;
    134                     else if (!f.get(this).equals(g.get(that)))
    135                         return false;
    136                 } catch (IllegalAccessException ex1) {
    137                     InternalErrorHandler.handleException(ex1);
    138                 }
    139             }
    140             if (myclass.equals(NetObject.class))
    141                 break;
    142             else {
    143                 myclass = myclass.getSuperclass();
    144                 hisclass = hisclass.getSuperclass();
    145             }
    146         }
    147         return true;
    148     }
    149 
    150 
    151 
    152 
    153     /** An introspection based predicate matching using a template
    154      * object. Allows for partial match of two protocl Objects.
    155      *@param other the match pattern to test against. The match object
    156      * has to be of the same type (class). Primitive types
    157      * and non-sip fields that are non null are matched for equality.
    158      * Null in any field  matches anything. Some book-keeping fields
    159      * are ignored when making the comparison.
    160      *@return true if match succeeds false otherwise.
    161      */
    162 
    163     public boolean match(Object other) {
    164         if (other == null)
    165             return true;
    166         if (!this.getClass().equals(other.getClass()))
    167             return false;
    168         GenericObject that = (GenericObject) other;
    169         // System.out.println("Comparing " + that.encode());
    170         // System.out.println("this = " + this.encode());
    171 
    172         Class<?> hisclass = other.getClass();
    173         Class<?> myclass = this.getClass();
    174         while (true) {
    175             Field[] fields = myclass.getDeclaredFields();
    176             Field[] hisfields = hisclass.getDeclaredFields();
    177             for (int i = 0; i < fields.length; i++) {
    178                 Field f = fields[i];
    179                 Field g = hisfields[i];
    180                 // Only print protected and public members.
    181                 int modifier = f.getModifiers();
    182                 if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE)
    183                     continue;
    184                 Class<?> fieldType = f.getType();
    185                 String fieldName = f.getName();
    186                 if (fieldName.compareTo("stringRepresentation") == 0) {
    187                     continue;
    188                 }
    189                 if (fieldName.compareTo("indentation") == 0) {
    190                     continue;
    191                 }
    192                 try {
    193                     // Primitive fields are printed with type: value
    194                     if (fieldType.isPrimitive()) {
    195                         String fname = fieldType.toString();
    196                         if (fname.compareTo("int") == 0) {
    197                             if (f.getInt(this) != g.getInt(that))
    198                                 return false;
    199                         } else if (fname.compareTo("short") == 0) {
    200                             if (f.getShort(this) != g.getShort(that))
    201                                 return false;
    202                         } else if (fname.compareTo("char") == 0) {
    203                             if (f.getChar(this) != g.getChar(that))
    204                                 return false;
    205                         } else if (fname.compareTo("long") == 0) {
    206                             if (f.getLong(this) != g.getLong(that))
    207                                 return false;
    208                         } else if (fname.compareTo("boolean") == 0) {
    209                             if (f.getBoolean(this) != g.getBoolean(that))
    210                                 return false;
    211                         } else if (fname.compareTo("double") == 0) {
    212                             if (f.getDouble(this) != g.getDouble(that))
    213                                 return false;
    214                         } else if (fname.compareTo("float") == 0) {
    215                             if (f.getFloat(this) != g.getFloat(that))
    216                                 return false;
    217                         }
    218                     } else {
    219                         Object myObj = f.get(this);
    220                         Object hisObj = g.get(that);
    221                         if (hisObj != null && myObj == null)
    222                             return false;
    223                         else if (hisObj == null && myObj != null)
    224                             continue;
    225                         else if (hisObj == null && myObj == null)
    226                             continue;
    227                         else if (
    228                             hisObj instanceof java.lang.String
    229                                 && myObj instanceof java.lang.String) {
    230                             if (((String) hisObj).equals(""))
    231                                 continue;
    232                             if (((String) myObj)
    233                                 .compareToIgnoreCase((String) hisObj)
    234                                 != 0)
    235                                 return false;
    236                         } else if (
    237                             GenericObject.isMySubclass(myObj.getClass())
    238                                 && GenericObject.isMySubclass(hisObj.getClass())
    239                                 && myObj.getClass().equals(hisObj.getClass())
    240                                 && ((GenericObject) hisObj).getMatcher()
    241                                     != null) {
    242                             String myObjEncoded =
    243                                 ((GenericObject) myObj).encode();
    244                             boolean retval =
    245                                 ((GenericObject) hisObj).getMatcher().match(
    246                                     myObjEncoded);
    247                             if (!retval)
    248                                 return false;
    249                         } else if (
    250                             GenericObject.isMySubclass(myObj.getClass())
    251                                 && !((GenericObject) myObj).match(hisObj))
    252                             return false;
    253                         else if (
    254                             GenericObjectList.isMySubclass(myObj.getClass())
    255                                 && !((GenericObjectList) myObj).match(hisObj))
    256                             return false;
    257                     }
    258                 } catch (IllegalAccessException ex1) {
    259                     InternalErrorHandler.handleException(ex1);
    260                 }
    261             }
    262             if (myclass.equals(NetObject.class))
    263                 break;
    264             else {
    265                 myclass = myclass.getSuperclass();
    266                 hisclass = hisclass.getSuperclass();
    267             }
    268         }
    269         return true;
    270     }
    271 
    272     /**
    273      * An introspection based string formatting method. We need this because
    274      * in this package (although it is an exact duplicate of the one in
    275      * the superclass) because it needs to access the protected members
    276      * of the other objects in this class.
    277      * @return String
    278      */
    279     public String debugDump() {
    280         stringRepresentation = "";
    281         Class<?> myclass = getClass();
    282         sprint(myclass.getName());
    283         sprint("{");
    284         Field[] fields = myclass.getDeclaredFields();
    285         for (int i = 0; i < fields.length; i++) {
    286             Field f = fields[i];
    287             // Only print protected and public members.
    288             int modifier = f.getModifiers();
    289             if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE)
    290                 continue;
    291             Class<?> fieldType = f.getType();
    292             String fieldName = f.getName();
    293             if (fieldName.compareTo("stringRepresentation") == 0) {
    294                 // avoid nasty recursions...
    295                 continue;
    296             }
    297             if (fieldName.compareTo("indentation") == 0) {
    298                 // formatting stuff - not relevant here.
    299                 continue;
    300             }
    301             sprint(fieldName + ":");
    302             try {
    303                 // Primitive fields are printed with type: value
    304                 if (fieldType.isPrimitive()) {
    305                     String fname = fieldType.toString();
    306                     sprint(fname + ":");
    307                     if (fname.compareTo("int") == 0) {
    308                         int intfield = f.getInt(this);
    309                         sprint(intfield);
    310                     } else if (fname.compareTo("short") == 0) {
    311                         short shortField = f.getShort(this);
    312                         sprint(shortField);
    313                     } else if (fname.compareTo("char") == 0) {
    314                         char charField = f.getChar(this);
    315                         sprint(charField);
    316                     } else if (fname.compareTo("long") == 0) {
    317                         long longField = f.getLong(this);
    318                         sprint(longField);
    319                     } else if (fname.compareTo("boolean") == 0) {
    320                         boolean booleanField = f.getBoolean(this);
    321                         sprint(booleanField);
    322                     } else if (fname.compareTo("double") == 0) {
    323                         double doubleField = f.getDouble(this);
    324                         sprint(doubleField);
    325                     } else if (fname.compareTo("float") == 0) {
    326                         float floatField = f.getFloat(this);
    327                         sprint(floatField);
    328                     }
    329                 } else if (GenericObject.class.isAssignableFrom(fieldType)) {
    330                     if (f.get(this) != null) {
    331                         sprint(
    332                             ((GenericObject) f.get(this)).debugDump(
    333                                 indentation + 1));
    334                     } else {
    335                         sprint("<null>");
    336                     }
    337 
    338                 } else if (
    339                     GenericObjectList.class.isAssignableFrom(fieldType)) {
    340                     if (f.get(this) != null) {
    341                         sprint(
    342                             ((GenericObjectList) f.get(this)).debugDump(
    343                                 indentation + 1));
    344                     } else {
    345                         sprint("<null>");
    346                     }
    347 
    348                 } else {
    349                     // Dont do recursion on things that are not
    350                     // of our header type...
    351                     if (f.get(this) != null) {
    352                         sprint(f.get(this).getClass().getName() + ":");
    353                     } else {
    354                         sprint(fieldType.getName() + ":");
    355                     }
    356 
    357                     sprint("{");
    358                     if (f.get(this) != null) {
    359                         sprint(f.get(this).toString());
    360                     } else {
    361                         sprint("<null>");
    362                     }
    363                     sprint("}");
    364                 }
    365             } catch (IllegalAccessException ex1) {
    366                 continue; // we are accessing a private field...
    367             }
    368         }
    369         sprint("}");
    370         return stringRepresentation;
    371     }
    372 
    373 
    374 
    375 
    376     /**
    377      * Formatter with a given starting indentation (for nested structs).
    378      * @param indent int to set
    379      * @return String
    380      */
    381     public String debugDump(int indent) {
    382         int save = indentation;
    383         indentation = indent;
    384         String retval = this.debugDump();
    385         indentation = save;
    386         return retval;
    387     }
    388 
    389     /** Encode this to a string.
    390      *
    391      *@return string representation for this object.
    392      */
    393     public String toString() {
    394         return this.encode();
    395     }
    396 }
    397