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*/ 26package gov.nist.javax.sip.parser; 27import gov.nist.javax.sip.parser.ims.*; 28import gov.nist.javax.sip.header.ims.*; 29import java.util.Hashtable; 30import java.lang.reflect.*; 31import javax.sip.header.*; 32import java.text.ParseException; 33import gov.nist.core.*; 34import gov.nist.javax.sip.header.extensions.*; 35import gov.nist.javax.sip.header.SIPHeaderNamesCache; 36import 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 */ 49public 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@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