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     // BEGIN android-added
     47     protected static final long serialVersionUID = 6149926203633320729L;
     48     // END android-added
     49 
     50     protected static final String CORE_PACKAGE = PackageNames.CORE_PACKAGE;
     51     protected static final String NET_PACKAGE = PackageNames.NET_PACKAGE;
     52     protected static final String PARSER_PACKAGE = PackageNames.PARSER_PACKAGE;
     53     protected static final String UDP = "udp";
     54     protected static final String TCP = "tcp";
     55     protected static final String TRANSPORT = "transport";
     56     protected static final String METHOD = "method";
     57     protected static final String USER = "user";
     58     protected static final String PHONE = "phone";
     59     protected static final String MADDR = "maddr";
     60     protected static final String TTL = "ttl";
     61     protected static final String LR = "lr";
     62     protected static final String SIP = "sip";
     63     protected static final String SIPS = "sips";
     64 
     65     // Added by Daniel J. Martinez Manzano <dani (at) dif.um.es>
     66     protected static final String TLS = "tls";
     67 
     68     // Added by Peter Musgrave <pmusgrave (at) newheights.com>
     69     // params for outbound and gruu drafts
     70     protected static final String GRUU = "gr";
     71 
     72 
     73     /** Default constructor
     74      */
     75     public NetObject() {
     76         super();
     77     }
     78 
     79     /**
     80      * An introspection based equality predicate for SIPObjects.
     81      *@param that is the other object to test against.
     82      */
     83     public boolean equals(Object that) {
     84         if (!this.getClass().equals(that.getClass()))
     85             return false;
     86         Class<?> myclass = this.getClass();
     87         Class<?> hisclass = that.getClass();
     88         while (true) {
     89             Field[] fields = myclass.getDeclaredFields();
     90             Field[] hisfields = hisclass.getDeclaredFields();
     91             for (int i = 0; i < fields.length; i++) {
     92                 Field f = fields[i];
     93                 Field g = hisfields[i];
     94                 // Only print protected and public members.
     95                 int modifier = f.getModifiers();
     96                 if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE)
     97                     continue;
     98                 Class<?> fieldType = f.getType();
     99                 String fieldName = f.getName();
    100                 if (fieldName.compareTo("stringRepresentation") == 0) {
    101                     continue;
    102                 }
    103                 if (fieldName.compareTo("indentation") == 0) {
    104                     continue;
    105                 }
    106                 try {
    107                     // Primitive fields are printed with type: value
    108                     if (fieldType.isPrimitive()) {
    109                         String fname = fieldType.toString();
    110                         if (fname.compareTo("int") == 0) {
    111                             if (f.getInt(this) != g.getInt(that))
    112                                 return false;
    113                         } else if (fname.compareTo("short") == 0) {
    114                             if (f.getShort(this) != g.getShort(that))
    115                                 return false;
    116                         } else if (fname.compareTo("char") == 0) {
    117                             if (f.getChar(this) != g.getChar(that))
    118                                 return false;
    119                         } else if (fname.compareTo("long") == 0) {
    120                             if (f.getLong(this) != g.getLong(that))
    121                                 return false;
    122                         } else if (fname.compareTo("boolean") == 0) {
    123                             if (f.getBoolean(this) != g.getBoolean(that))
    124                                 return false;
    125                         } else if (fname.compareTo("double") == 0) {
    126                             if (f.getDouble(this) != g.getDouble(that))
    127                                 return false;
    128                         } else if (fname.compareTo("float") == 0) {
    129                             if (f.getFloat(this) != g.getFloat(that))
    130                                 return false;
    131                         }
    132                     } else if (g.get(that) == f.get(this))
    133                         continue;
    134                     else if (f.get(this) == null && g.get(that) != null)
    135                         return false;
    136                     else if (g.get(that) == null && f.get(that) != null)
    137                         return false;
    138                     else if (!f.get(this).equals(g.get(that)))
    139                         return false;
    140                 } catch (IllegalAccessException ex1) {
    141                     InternalErrorHandler.handleException(ex1);
    142                 }
    143             }
    144             if (myclass.equals(NetObject.class))
    145                 break;
    146             else {
    147                 myclass = myclass.getSuperclass();
    148                 hisclass = hisclass.getSuperclass();
    149             }
    150         }
    151         return true;
    152     }
    153 
    154 
    155 
    156 
    157     /** An introspection based predicate matching using a template
    158      * object. Allows for partial match of two protocl Objects.
    159      *@param other the match pattern to test against. The match object
    160      * has to be of the same type (class). Primitive types
    161      * and non-sip fields that are non null are matched for equality.
    162      * Null in any field  matches anything. Some book-keeping fields
    163      * are ignored when making the comparison.
    164      *@return true if match succeeds false otherwise.
    165      */
    166 
    167     public boolean match(Object other) {
    168         if (other == null)
    169             return true;
    170         if (!this.getClass().equals(other.getClass()))
    171             return false;
    172         GenericObject that = (GenericObject) other;
    173         // System.out.println("Comparing " + that.encode());
    174         // System.out.println("this = " + this.encode());
    175 
    176         Class<?> hisclass = other.getClass();
    177         Class<?> myclass = this.getClass();
    178         while (true) {
    179             Field[] fields = myclass.getDeclaredFields();
    180             Field[] hisfields = hisclass.getDeclaredFields();
    181             for (int i = 0; i < fields.length; i++) {
    182                 Field f = fields[i];
    183                 Field g = hisfields[i];
    184                 // Only print protected and public members.
    185                 int modifier = f.getModifiers();
    186                 if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE)
    187                     continue;
    188                 Class<?> fieldType = f.getType();
    189                 String fieldName = f.getName();
    190                 if (fieldName.compareTo("stringRepresentation") == 0) {
    191                     continue;
    192                 }
    193                 if (fieldName.compareTo("indentation") == 0) {
    194                     continue;
    195                 }
    196                 try {
    197                     // Primitive fields are printed with type: value
    198                     if (fieldType.isPrimitive()) {
    199                         String fname = fieldType.toString();
    200                         if (fname.compareTo("int") == 0) {
    201                             if (f.getInt(this) != g.getInt(that))
    202                                 return false;
    203                         } else if (fname.compareTo("short") == 0) {
    204                             if (f.getShort(this) != g.getShort(that))
    205                                 return false;
    206                         } else if (fname.compareTo("char") == 0) {
    207                             if (f.getChar(this) != g.getChar(that))
    208                                 return false;
    209                         } else if (fname.compareTo("long") == 0) {
    210                             if (f.getLong(this) != g.getLong(that))
    211                                 return false;
    212                         } else if (fname.compareTo("boolean") == 0) {
    213                             if (f.getBoolean(this) != g.getBoolean(that))
    214                                 return false;
    215                         } else if (fname.compareTo("double") == 0) {
    216                             if (f.getDouble(this) != g.getDouble(that))
    217                                 return false;
    218                         } else if (fname.compareTo("float") == 0) {
    219                             if (f.getFloat(this) != g.getFloat(that))
    220                                 return false;
    221                         }
    222                     } else {
    223                         Object myObj = f.get(this);
    224                         Object hisObj = g.get(that);
    225                         if (hisObj != null && myObj == null)
    226                             return false;
    227                         else if (hisObj == null && myObj != null)
    228                             continue;
    229                         else if (hisObj == null && myObj == null)
    230                             continue;
    231                         else if (
    232                             hisObj instanceof java.lang.String
    233                                 && myObj instanceof java.lang.String) {
    234                             if (((String) hisObj).equals(""))
    235                                 continue;
    236                             if (((String) myObj)
    237                                 .compareToIgnoreCase((String) hisObj)
    238                                 != 0)
    239                                 return false;
    240                         } else if (
    241                             GenericObject.isMySubclass(myObj.getClass())
    242                                 && GenericObject.isMySubclass(hisObj.getClass())
    243                                 && myObj.getClass().equals(hisObj.getClass())
    244                                 && ((GenericObject) hisObj).getMatcher()
    245                                     != null) {
    246                             String myObjEncoded =
    247                                 ((GenericObject) myObj).encode();
    248                             boolean retval =
    249                                 ((GenericObject) hisObj).getMatcher().match(
    250                                     myObjEncoded);
    251                             if (!retval)
    252                                 return false;
    253                         } else if (
    254                             GenericObject.isMySubclass(myObj.getClass())
    255                                 && !((GenericObject) myObj).match(hisObj))
    256                             return false;
    257                         else if (
    258                             GenericObjectList.isMySubclass(myObj.getClass())
    259                                 && !((GenericObjectList) myObj).match(hisObj))
    260                             return false;
    261                     }
    262                 } catch (IllegalAccessException ex1) {
    263                     InternalErrorHandler.handleException(ex1);
    264                 }
    265             }
    266             if (myclass.equals(NetObject.class))
    267                 break;
    268             else {
    269                 myclass = myclass.getSuperclass();
    270                 hisclass = hisclass.getSuperclass();
    271             }
    272         }
    273         return true;
    274     }
    275 
    276     /**
    277      * An introspection based string formatting method. We need this because
    278      * in this package (although it is an exact duplicate of the one in
    279      * the superclass) because it needs to access the protected members
    280      * of the other objects in this class.
    281      * @return String
    282      */
    283     public String debugDump() {
    284         stringRepresentation = "";
    285         Class<?> myclass = getClass();
    286         sprint(myclass.getName());
    287         sprint("{");
    288         Field[] fields = myclass.getDeclaredFields();
    289         for (int i = 0; i < fields.length; i++) {
    290             Field f = fields[i];
    291             // Only print protected and public members.
    292             int modifier = f.getModifiers();
    293             if ((modifier & Modifier.PRIVATE) == Modifier.PRIVATE)
    294                 continue;
    295             Class<?> fieldType = f.getType();
    296             String fieldName = f.getName();
    297             if (fieldName.compareTo("stringRepresentation") == 0) {
    298                 // avoid nasty recursions...
    299                 continue;
    300             }
    301             if (fieldName.compareTo("indentation") == 0) {
    302                 // formatting stuff - not relevant here.
    303                 continue;
    304             }
    305             sprint(fieldName + ":");
    306             try {
    307                 // Primitive fields are printed with type: value
    308                 if (fieldType.isPrimitive()) {
    309                     String fname = fieldType.toString();
    310                     sprint(fname + ":");
    311                     if (fname.compareTo("int") == 0) {
    312                         int intfield = f.getInt(this);
    313                         sprint(intfield);
    314                     } else if (fname.compareTo("short") == 0) {
    315                         short shortField = f.getShort(this);
    316                         sprint(shortField);
    317                     } else if (fname.compareTo("char") == 0) {
    318                         char charField = f.getChar(this);
    319                         sprint(charField);
    320                     } else if (fname.compareTo("long") == 0) {
    321                         long longField = f.getLong(this);
    322                         sprint(longField);
    323                     } else if (fname.compareTo("boolean") == 0) {
    324                         boolean booleanField = f.getBoolean(this);
    325                         sprint(booleanField);
    326                     } else if (fname.compareTo("double") == 0) {
    327                         double doubleField = f.getDouble(this);
    328                         sprint(doubleField);
    329                     } else if (fname.compareTo("float") == 0) {
    330                         float floatField = f.getFloat(this);
    331                         sprint(floatField);
    332                     }
    333                 } else if (GenericObject.class.isAssignableFrom(fieldType)) {
    334                     if (f.get(this) != null) {
    335                         sprint(
    336                             ((GenericObject) f.get(this)).debugDump(
    337                                 indentation + 1));
    338                     } else {
    339                         sprint("<null>");
    340                     }
    341 
    342                 } else if (
    343                     GenericObjectList.class.isAssignableFrom(fieldType)) {
    344                     if (f.get(this) != null) {
    345                         sprint(
    346                             ((GenericObjectList) f.get(this)).debugDump(
    347                                 indentation + 1));
    348                     } else {
    349                         sprint("<null>");
    350                     }
    351 
    352                 } else {
    353                     // Dont do recursion on things that are not
    354                     // of our header type...
    355                     if (f.get(this) != null) {
    356                         sprint(f.get(this).getClass().getName() + ":");
    357                     } else {
    358                         sprint(fieldType.getName() + ":");
    359                     }
    360 
    361                     sprint("{");
    362                     if (f.get(this) != null) {
    363                         sprint(f.get(this).toString());
    364                     } else {
    365                         sprint("<null>");
    366                     }
    367                     sprint("}");
    368                 }
    369             } catch (IllegalAccessException ex1) {
    370                 continue; // we are accessing a private field...
    371             }
    372         }
    373         sprint("}");
    374         return stringRepresentation;
    375     }
    376 
    377 
    378 
    379 
    380     /**
    381      * Formatter with a given starting indentation (for nested structs).
    382      * @param indent int to set
    383      * @return String
    384      */
    385     public String debugDump(int indent) {
    386         int save = indentation;
    387         indentation = indent;
    388         String retval = this.debugDump();
    389         indentation = save;
    390         return retval;
    391     }
    392 
    393     /** Encode this to a string.
    394      *
    395      *@return string representation for this object.
    396      */
    397     public String toString() {
    398         return this.encode();
    399     }
    400 }
    401