Home | History | Annotate | Download | only in parser
      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 package gov.nist.javax.sip.parser;
     27 import gov.nist.javax.sip.parser.ims.*;
     28 import gov.nist.javax.sip.header.ims.*;
     29 import java.util.Hashtable;
     30 import java.lang.reflect.*;
     31 import javax.sip.header.*;
     32 import java.text.ParseException;
     33 import gov.nist.core.*;
     34 import gov.nist.javax.sip.header.extensions.*;
     35 import gov.nist.javax.sip.header.SIPHeaderNamesCache;
     36 import gov.nist.javax.sip.parser.extensions.*;
     37 
     38 /**
     39  * A factory class that does a name lookup on a registered parser and
     40  * returns a header parser for the given name.
     41  *
     42  * @version 1.2 $Revision: 1.17 $ $Date: 2010/01/12 00:05:25 $
     43  *
     44  * @author M. Ranganathan   <br/>
     45  *
     46  *
     47  *
     48  */
     49 public class ParserFactory {
     50 
     51     private static Hashtable<String,Class<? extends HeaderParser>> parserTable;
     52     private static Class[] constructorArgs;
     53     private static Hashtable parserConstructorCache;
     54 
     55     static {
     56         parserTable = new Hashtable<String,Class<? extends HeaderParser>>();
     57         parserConstructorCache = new Hashtable();
     58         constructorArgs = new Class[1];
     59         constructorArgs[0] = String.class;
     60         parserTable.put(ReplyToHeader.NAME.toLowerCase(), ReplyToParser.class);
     61 
     62         parserTable.put(
     63             InReplyToHeader.NAME.toLowerCase(),
     64             InReplyToParser.class);
     65 
     66         parserTable.put(
     67             AcceptEncodingHeader.NAME.toLowerCase(),
     68             AcceptEncodingParser.class);
     69 
     70         parserTable.put(
     71             AcceptLanguageHeader.NAME.toLowerCase(),
     72             AcceptLanguageParser.class);
     73 
     74         parserTable.put("t", ToParser.class);
     75         parserTable.put(ToHeader.NAME.toLowerCase(), ToParser.class);
     76 
     77         parserTable.put(FromHeader.NAME.toLowerCase(), FromParser.class);
     78         parserTable.put("f", FromParser.class);
     79 
     80         parserTable.put(CSeqHeader.NAME.toLowerCase(), CSeqParser.class);
     81 
     82         parserTable.put(ViaHeader.NAME.toLowerCase(), ViaParser.class);
     83         parserTable.put("v", ViaParser.class);
     84 
     85         parserTable.put(ContactHeader.NAME.toLowerCase(), ContactParser.class);
     86         parserTable.put("m", ContactParser.class);
     87 
     88         parserTable.put(
     89             ContentTypeHeader.NAME.toLowerCase(),
     90             ContentTypeParser.class);
     91         parserTable.put("c", ContentTypeParser.class);
     92 
     93         parserTable.put(
     94             ContentLengthHeader.NAME.toLowerCase(),
     95             ContentLengthParser.class);
     96         parserTable.put("l", ContentLengthParser.class);
     97 
     98         parserTable.put(
     99             AuthorizationHeader.NAME.toLowerCase(),
    100             AuthorizationParser.class);
    101 
    102         parserTable.put(
    103             WWWAuthenticateHeader.NAME.toLowerCase(),
    104             WWWAuthenticateParser.class);
    105 
    106         parserTable.put(CallIdHeader.NAME.toLowerCase(), CallIDParser.class);
    107         parserTable.put("i", CallIDParser.class);
    108 
    109         parserTable.put(RouteHeader.NAME.toLowerCase(), RouteParser.class);
    110 
    111         parserTable.put(
    112             RecordRouteHeader.NAME.toLowerCase(),
    113             RecordRouteParser.class);
    114 
    115         parserTable.put(DateHeader.NAME.toLowerCase(), DateParser.class);
    116 
    117         parserTable.put(
    118             ProxyAuthorizationHeader.NAME.toLowerCase(),
    119             ProxyAuthorizationParser.class);
    120 
    121         parserTable.put(
    122             ProxyAuthenticateHeader.NAME.toLowerCase(),
    123             ProxyAuthenticateParser.class);
    124 
    125         parserTable.put(
    126             RetryAfterHeader.NAME.toLowerCase(),
    127             RetryAfterParser.class);
    128 
    129         parserTable.put(RequireHeader.NAME.toLowerCase(), RequireParser.class);
    130 
    131         parserTable.put(
    132             ProxyRequireHeader.NAME.toLowerCase(),
    133             ProxyRequireParser.class);
    134 
    135         parserTable.put(
    136             TimeStampHeader.NAME.toLowerCase(),
    137             TimeStampParser.class);
    138 
    139         parserTable.put(
    140             UnsupportedHeader.NAME.toLowerCase(),
    141             UnsupportedParser.class);
    142 
    143         parserTable.put(
    144             UserAgentHeader.NAME.toLowerCase(),
    145             UserAgentParser.class);
    146 
    147         parserTable.put(
    148             SupportedHeader.NAME.toLowerCase(),
    149             SupportedParser.class);
    150         // bug fix by Steve Crosley
    151         parserTable.put("k", SupportedParser.class);
    152 
    153         parserTable.put(ServerHeader.NAME.toLowerCase(), ServerParser.class);
    154 
    155         parserTable.put(SubjectHeader.NAME.toLowerCase(), SubjectParser.class);
    156         parserTable.put( "s", SubjectParser.class); // JvB: added
    157 
    158         parserTable.put(
    159             SubscriptionStateHeader.NAME.toLowerCase(),
    160             SubscriptionStateParser.class);
    161 
    162         parserTable.put(
    163             MaxForwardsHeader.NAME.toLowerCase(),
    164             MaxForwardsParser.class);
    165 
    166         parserTable.put(
    167             MimeVersionHeader.NAME.toLowerCase(),
    168             MimeVersionParser.class);
    169 
    170         parserTable.put(
    171             MinExpiresHeader.NAME.toLowerCase(),
    172             MinExpiresParser.class);
    173 
    174         parserTable.put(
    175             OrganizationHeader.NAME.toLowerCase(),
    176             OrganizationParser.class);
    177 
    178         parserTable.put(
    179             PriorityHeader.NAME.toLowerCase(),
    180             PriorityParser.class);
    181 
    182         parserTable.put(RAckHeader.NAME.toLowerCase(), RAckParser.class);
    183 
    184         parserTable.put(RSeqHeader.NAME.toLowerCase(), RSeqParser.class);
    185 
    186         parserTable.put(ReasonHeader.NAME.toLowerCase(), ReasonParser.class);
    187 
    188         parserTable.put(WarningHeader.NAME.toLowerCase(), WarningParser.class);
    189 
    190         parserTable.put(ExpiresHeader.NAME.toLowerCase(), ExpiresParser.class);
    191 
    192         parserTable.put(EventHeader.NAME.toLowerCase(), EventParser.class);
    193         parserTable.put("o", EventParser.class);
    194 
    195         parserTable.put(
    196             ErrorInfoHeader.NAME.toLowerCase(),
    197             ErrorInfoParser.class);
    198 
    199         parserTable.put(
    200             ContentLanguageHeader.NAME.toLowerCase(),
    201             ContentLanguageParser.class);
    202 
    203         parserTable.put(
    204             ContentEncodingHeader.NAME.toLowerCase(),
    205             ContentEncodingParser.class);
    206         parserTable.put("e", ContentEncodingParser.class);
    207 
    208         parserTable.put(
    209             ContentDispositionHeader.NAME.toLowerCase(),
    210             ContentDispositionParser.class);
    211 
    212         parserTable.put(
    213             CallInfoHeader.NAME.toLowerCase(),
    214             CallInfoParser.class);
    215 
    216         parserTable.put(
    217             AuthenticationInfoHeader.NAME.toLowerCase(),
    218             AuthenticationInfoParser.class);
    219 
    220         parserTable.put(AllowHeader.NAME.toLowerCase(), AllowParser.class);
    221 
    222         parserTable.put(
    223             AllowEventsHeader.NAME.toLowerCase(),
    224             AllowEventsParser.class);
    225         parserTable.put("u", AllowEventsParser.class);
    226 
    227         parserTable.put(
    228             AlertInfoHeader.NAME.toLowerCase(),
    229             AlertInfoParser.class);
    230 
    231         parserTable.put(AcceptHeader.NAME.toLowerCase(), AcceptParser.class);
    232 
    233         parserTable.put(ReferToHeader.NAME.toLowerCase(), ReferToParser.class);
    234         // Was missing (bug noticed by Steve Crossley)
    235         parserTable.put("r", ReferToParser.class);
    236 
    237         // JvB: added to support RFC3903 PUBLISH
    238         parserTable.put(SIPETagHeader.NAME.toLowerCase(), SIPETagParser.class);
    239         parserTable.put(SIPIfMatchHeader.NAME.toLowerCase(), SIPIfMatchParser.class);
    240 
    241         //IMS headers
    242         parserTable.put(PAccessNetworkInfoHeader.NAME.toLowerCase(), PAccessNetworkInfoParser.class);
    243         parserTable.put(PAssertedIdentityHeader.NAME.toLowerCase(), PAssertedIdentityParser.class);
    244         parserTable.put(PPreferredIdentityHeader.NAME.toLowerCase(), PPreferredIdentityParser.class);
    245         parserTable.put(PChargingVectorHeader.NAME.toLowerCase(), PChargingVectorParser.class);
    246         parserTable.put(PChargingFunctionAddressesHeader.NAME.toLowerCase(), PChargingFunctionAddressesParser.class);
    247         parserTable.put(PMediaAuthorizationHeader.NAME.toLowerCase(), PMediaAuthorizationParser.class);
    248         parserTable.put(PathHeader.NAME.toLowerCase(), PathParser.class);
    249         parserTable.put(PrivacyHeader.NAME.toLowerCase(), PrivacyParser.class);
    250         parserTable.put(ServiceRouteHeader.NAME.toLowerCase(), ServiceRouteParser.class);
    251         parserTable.put(PVisitedNetworkIDHeader.NAME.toLowerCase(), PVisitedNetworkIDParser.class);
    252 
    253         parserTable.put(PAssociatedURIHeader.NAME.toLowerCase(), PAssociatedURIParser.class);
    254         parserTable.put(PCalledPartyIDHeader.NAME.toLowerCase(), PCalledPartyIDParser.class);
    255 
    256         parserTable.put(SecurityServerHeader.NAME.toLowerCase(), SecurityServerParser.class);
    257         parserTable.put(SecurityClientHeader.NAME.toLowerCase(), SecurityClientParser.class);
    258         parserTable.put(SecurityVerifyHeader.NAME.toLowerCase(), SecurityVerifyParser.class);
    259 
    260 
    261         // Per RFC 3892 (pmusgrave)
    262         parserTable.put(ReferredBy.NAME.toLowerCase(), ReferredByParser.class);
    263         parserTable.put("b", ReferToParser.class);
    264 
    265         // Per RFC4028 Session Timers (pmusgrave)
    266         parserTable.put(SessionExpires.NAME.toLowerCase(), SessionExpiresParser.class);
    267         parserTable.put("x", SessionExpiresParser.class);
    268         parserTable.put(MinSE.NAME.toLowerCase(), MinSEParser.class);
    269         // (RFC4028 does not give a short form header for MinSE)
    270 
    271         // Per RFC3891 (pmusgrave)
    272         parserTable.put(Replaces.NAME.toLowerCase(), ReplacesParser.class);
    273 
    274         // Per RFC3911 (jean deruelle)
    275         parserTable.put(Join.NAME.toLowerCase(), JoinParser.class);
    276 
    277         //http://tools.ietf.org/html/draft-worley-references-05
    278         parserTable.put(References.NAME.toLowerCase(), ReferencesParser.class);
    279     }
    280 
    281     /**
    282      * create a parser for a header. This is the parser factory.
    283      */
    284     public static HeaderParser createParser(String line)
    285         throws ParseException {
    286         String headerName = Lexer.getHeaderName(line);
    287         String headerValue = Lexer.getHeaderValue(line);
    288         if (headerName == null || headerValue == null)
    289             throw new ParseException("The header name or value is null", 0);
    290 
    291         Class parserClass = (Class) parserTable.get(SIPHeaderNamesCache.toLowerCase(headerName));
    292         if (parserClass != null) {
    293             try {
    294                 Constructor cons = (Constructor) parserConstructorCache.get(parserClass);
    295                 if (cons == null) {
    296                     cons = parserClass.getConstructor(constructorArgs);
    297                     parserConstructorCache.put(parserClass, cons);
    298                 }
    299                 Object[] args = new Object[1];
    300                 args[0] = line;
    301                 HeaderParser retval = (HeaderParser) cons.newInstance(args);
    302                 return retval;
    303 
    304             } catch (Exception ex) {
    305                 InternalErrorHandler.handleException(ex);
    306                 return null; // to placate the compiler.
    307             }
    308 
    309         } else {
    310             // Just generate a generic SIPHeader. We define
    311             // parsers only for the above.
    312             return new HeaderParser(line);
    313         }
    314     }
    315 }
    316 /*
    317  * $Log: ParserFactory.java,v $
    318  * Revision 1.17  2010/01/12 00:05:25  mranga
    319  * Add support for References header draft-worley-references-05
    320  *
    321  * Revision 1.16  2009/07/17 18:58:01  emcho
    322  * Converts indentation tabs to spaces so that we have a uniform indentation policy in the whole project.
    323  *
    324  * Revision 1.15  2009/01/22 19:33:48  deruelle_jean
    325  * Add support for JOIN (RFC 3911)
    326  * Issue number:  186
    327  * Obtained from:
    328  * Submitted by:  Jean Deruelle
    329  * Reviewed by:   Ranga, The high priest and grand poobah of Jain-SIP
    330  *
    331  * Revision 1.14  2007/03/07 14:29:46  belangery
    332  * Yet another bunch of improvements in the parsing code.
    333  *
    334  * Revision 1.13  2007/02/23 14:56:06  belangery
    335  * Added performance improvement around header name lowercase conversion.
    336  *
    337  * Revision 1.12  2007/01/08 19:24:21  mranga
    338  * Issue number:
    339  * Obtained from:
    340  * Submitted by:  Miguel Freitas
    341  * Reviewed by:   mranga
    342  *
    343  * Miguel -- please implement a deep clone method for the IMS headers.
    344  *
    345  * CVS: ----------------------------------------------------------------------
    346  * CVS: Issue number:
    347  * CVS:   If this change addresses one or more issues,
    348  * CVS:   then enter the issue number(s) here.
    349  * CVS: Obtained from:
    350  * CVS:   If this change has been taken from another system,
    351  * CVS:   then name the system in this line, otherwise delete it.
    352  * CVS: Submitted by:
    353  * CVS:   If this code has been contributed to the project by someone else; i.e.,
    354  * CVS:   they sent us a patch or a set of diffs, then include their name/email
    355  * CVS:   address here. If this is your work then delete this line.
    356  * CVS: Reviewed by:
    357  * CVS:   If we are doing pre-commit code reviews and someone else has
    358  * CVS:   reviewed your changes, include their name(s) here.
    359  * CVS:   If you have not had it reviewed then delete this line.
    360  *
    361  * Revision 1.11  2006/10/12 11:57:54  pmusgrave
    362  * Issue number:  79, 80
    363  * Submitted by:  pmusgrave (at) newheights.com
    364  * Reviewed by:   mranga
    365  *
    366  * Revision 1.10  2006/09/29 19:40:50  jbemmel
    367  * fixed missing IMS header parsing plumbing
    368  *
    369  * Revision 1.9  2006/09/11 18:41:32  mranga
    370  * Issue number:
    371  * Obtained from:
    372  * Submitted by:  mranga
    373  * Reviewed by:
    374  * Tighter integration of IMS headers.
    375  * CVS: ----------------------------------------------------------------------
    376  * CVS: Issue number:
    377  * CVS:   If this change addresses one or more issues,
    378  * CVS:   then enter the issue number(s) here.
    379  * CVS: Obtained from:
    380  * CVS:   If this change has been taken from another system,
    381  * CVS:   then name the system in this line, otherwise delete it.
    382  * CVS: Submitted by:
    383  * CVS:   If this code has been contributed to the project by someone else; i.e.,
    384  * CVS:   they sent us a patch or a set of diffs, then include their name/email
    385  * CVS:   address here. If this is your work then delete this line.
    386  * CVS: Reviewed by:
    387  * CVS:   If we are doing pre-commit code reviews and someone else has
    388  * CVS:   reviewed your changes, include their name(s) here.
    389  * CVS:   If you have not had it reviewed then delete this line.
    390  *
    391  * Revision 1.8  2006/08/15 21:44:50  mranga
    392  * Issue number:
    393  * Obtained from:
    394  * Submitted by:  mranga
    395  * Reviewed by:   mranga
    396  * Incorporating the latest API changes from Phelim
    397  * CVS: ----------------------------------------------------------------------
    398  * CVS: Issue number:
    399  * CVS:   If this change addresses one or more issues,
    400  * CVS:   then enter the issue number(s) here.
    401  * CVS: Obtained from:
    402  * CVS:   If this change has been taken from another system,
    403  * CVS:   then name the system in this line, otherwise delete it.
    404  * CVS: Submitted by:
    405  * CVS:   If this code has been contributed to the project by someone else; i.e.,
    406  * CVS:   they sent us a patch or a set of diffs, then include their name/email
    407  * CVS:   address here. If this is your work then delete this line.
    408  * CVS: Reviewed by:
    409  * CVS:   If we are doing pre-commit code reviews and someone else has
    410  * CVS:   reviewed your changes, include their name(s) here.
    411  * CVS:   If you have not had it reviewed then delete this line.
    412  *
    413  * Revision 1.7  2006/07/13 09:02:06  mranga
    414  * Issue number:
    415  * Obtained from:
    416  * Submitted by:  jeroen van bemmel
    417  * Reviewed by:   mranga
    418  * Moved some changes from jain-sip-1.2 to java.net
    419  *
    420  * CVS: ----------------------------------------------------------------------
    421  * CVS: Issue number:
    422  * CVS:   If this change addresses one or more issues,
    423  * CVS:   then enter the issue number(s) here.
    424  * CVS: Obtained from:
    425  * CVS:   If this change has been taken from another system,
    426  * CVS:   then name the system in this line, otherwise delete it.
    427  * CVS: Submitted by:
    428  * CVS:   If this code has been contributed to the project by someone else; i.e.,
    429  * CVS:   they sent us a patch or a set of diffs, then include their name/email
    430  * CVS:   address here. If this is your work then delete this line.
    431  * CVS: Reviewed by:
    432  * CVS:   If we are doing pre-commit code reviews and someone else has
    433  * CVS:   reviewed your changes, include their name(s) here.
    434  * CVS:   If you have not had it reviewed then delete this line.
    435  *
    436  * Revision 1.5  2006/06/19 06:47:27  mranga
    437  * javadoc fixups
    438  *
    439  * Revision 1.4  2006/06/16 15:26:28  mranga
    440  * Added NIST disclaimer to all public domain files. Clean up some javadoc. Fixed a leak
    441  *
    442  * Revision 1.3  2005/10/27 20:49:00  jeroen
    443  * added support for RFC3903 PUBLISH
    444  *
    445  * Revision 1.2  2005/10/14 19:59:00  jeroen
    446  * bugfix: missing parser for shortform of Subject (s)
    447  *
    448  * Revision 1.1.1.1  2005/10/04 17:12:35  mranga
    449  *
    450  * Import
    451  *
    452  *
    453  * Revision 1.4  2005/04/04 09:29:03  dmuresan
    454  * Replaced new String().getClass() with String.class.
    455  *
    456  * Revision 1.3  2004/01/22 13:26:31  sverker
    457  * Issue number:
    458  * Obtained from:
    459  * Submitted by:  sverker
    460  * Reviewed by:   mranga
    461  *
    462  * Major reformat of code to conform with style guide. Resolved compiler and javadoc warnings. Added CVS tags.
    463  *
    464  * CVS: ----------------------------------------------------------------------
    465  * CVS: Issue number:
    466  * CVS:   If this change addresses one or more issues,
    467  * CVS:   then enter the issue number(s) here.
    468  * CVS: Obtained from:
    469  * CVS:   If this change has been taken from another system,
    470  * CVS:   then name the system in this line, otherwise delete it.
    471  * CVS: Submitted by:
    472  * CVS:   If this code has been contributed to the project by someone else; i.e.,
    473  * CVS:   they sent us a patch or a set of diffs, then include their name/email
    474  * CVS:   address here. If this is your work then delete this line.
    475  * CVS: Reviewed by:
    476  * CVS:   If we are doing pre-commit code reviews and someone else has
    477  * CVS:   reviewed your changes, include their name(s) here.
    478  * CVS:   If you have not had it reviewed then delete this line.
    479  *
    480  */
    481