1600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang/* 2600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* Conditions Of Use 3600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* 4600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* This software was developed by employees of the National Institute of 5600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* Standards and Technology (NIST), an agency of the Federal Government. 6600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* Pursuant to title 15 Untied States Code Section 105, works of NIST 7600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* employees are not subject to copyright protection in the United States 8600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* and are considered to be in the public domain. As a result, a formal 9600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* license is not needed to use the software. 10600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* 11600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* This software is provided by NIST as a service and is expressly 12600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED 13600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF 14600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 15600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* AND DATA ACCURACY. NIST does not warrant or make any representations 16600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* regarding the use of the software or the results thereof, including but 17600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* not limited to the correctness, accuracy, reliability or usefulness of 18600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* the software. 19600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* 20600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* Permission to use this software is contingent upon your acceptance 21600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* of the terms of this agreement 22600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* 23600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* . 24600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang* 25600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang*/ 26600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangpackage gov.nist.javax.sip.parser; 27600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 28600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.header.*; 29600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.util.*; 30600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.text.ParseException; 31600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 32600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang/** 33600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Generic header parser class. The parsers for various headers extend this 34600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * class. To create a parser for a new header, extend this class and change 35600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * the createParser class. 36600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 37600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @version 1.2 $Revision: 1.9 $ $Date: 2009/07/17 18:58:00 $ 38600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 39600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @author M. Ranganathan <br/> 40600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 41600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 42600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 43600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangpublic class HeaderParser extends Parser { 44600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 45600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 46600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Parse the weekday field 47600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @return an integer with the calendar content for wkday. 48600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 49600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected int wkday() throws ParseException { 50600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dbg_enter("wkday"); 51600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 52600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String tok = lexer.ttoken(); 53600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String id = tok.toLowerCase(); 54600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 55600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (TokenNames.MON.equalsIgnoreCase(id)) 56600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return Calendar.MONDAY; 57600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (TokenNames.TUE.equalsIgnoreCase(id)) 58600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return Calendar.TUESDAY; 59600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (TokenNames.WED.equalsIgnoreCase(id)) 60600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return Calendar.WEDNESDAY; 61600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (TokenNames.THU.equalsIgnoreCase(id)) 62600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return Calendar.THURSDAY; 63600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (TokenNames.FRI.equalsIgnoreCase(id)) 64600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return Calendar.FRIDAY; 65600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (TokenNames.SAT.equalsIgnoreCase(id)) 66600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return Calendar.SATURDAY; 67600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (TokenNames.SUN.equalsIgnoreCase(id)) 68600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return Calendar.SUNDAY; 69600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else 70600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw createParseException("bad wkday"); 71600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } finally { 72600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dbg_leave("wkday"); 73600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 74600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 75600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 76600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 77600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 78600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * parse and return a date field. 79600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @return a date structure with the parsed value. 80600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 81600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected Calendar date() throws ParseException { 82600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 83600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Calendar retval = Calendar.getInstance(TimeZone.getTimeZone("GMT")); 84600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String s1 = lexer.number(); 85600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang int day = Integer.parseInt(s1); 86600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (day <= 0 || day > 31) 87600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw createParseException("Bad day "); 88600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.set(Calendar.DAY_OF_MONTH, day); 89600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang lexer.match(' '); 90600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String month = lexer.ttoken().toLowerCase(); 91600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (month.equals("jan")) { 92600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.set(Calendar.MONTH, Calendar.JANUARY); 93600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (month.equals("feb")) { 94600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.set(Calendar.MONTH, Calendar.FEBRUARY); 95600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (month.equals("mar")) { 96600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.set(Calendar.MONTH, Calendar.MARCH); 97600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (month.equals("apr")) { 98600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.set(Calendar.MONTH, Calendar.APRIL); 99600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (month.equals("may")) { 100600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.set(Calendar.MONTH, Calendar.MAY); 101600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (month.equals("jun")) { 102600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.set(Calendar.MONTH, Calendar.JUNE); 103600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (month.equals("jul")) { 104600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.set(Calendar.MONTH, Calendar.JULY); 105600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (month.equals("aug")) { 106600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.set(Calendar.MONTH, Calendar.AUGUST); 107600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (month.equals("sep")) { 108600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.set(Calendar.MONTH, Calendar.SEPTEMBER); 109600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (month.equals("oct")) { 110600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.set(Calendar.MONTH, Calendar.OCTOBER); 111600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (month.equals("nov")) { 112600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.set(Calendar.MONTH, Calendar.NOVEMBER); 113600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (month.equals("dec")) { 114600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.set(Calendar.MONTH, Calendar.DECEMBER); 115600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 116600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang lexer.match(' '); 117600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String s2 = lexer.number(); 118600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang int yr = Integer.parseInt(s2); 119600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.set(Calendar.YEAR, yr); 120600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return retval; 121600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 122600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (Exception ex) { 123600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw createParseException("bad date field"); 124600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 125600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 126600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 127600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 128600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 129600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Set the time field. This has the format hour:minute:second 130600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 131600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected void time(Calendar calendar) throws ParseException { 132600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 133600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String s = lexer.number(); 134600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang int hour = Integer.parseInt(s); 135600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang calendar.set(Calendar.HOUR_OF_DAY, hour); 136600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang lexer.match(':'); 137600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang s = lexer.number(); 138600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang int min = Integer.parseInt(s); 139600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang calendar.set(Calendar.MINUTE, min); 140600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang lexer.match(':'); 141600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang s = lexer.number(); 142600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang int sec = Integer.parseInt(s); 143600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang calendar.set(Calendar.SECOND, sec); 144600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (Exception ex) { 145600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw createParseException("error processing time "); 146600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 147600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 148600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 149600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 150600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 151600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 152600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Creates new HeaderParser 153600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @param String to parse. 154600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 155600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected HeaderParser(String header) { 156600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.lexer = new Lexer("command_keywordLexer", header); 157600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 158600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 159600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected HeaderParser(Lexer lexer) { 160600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.lexer = lexer; 161600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.lexer.selectLexer("command_keywordLexer"); 162600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 163600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 164600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 165600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Parse the SIP header from the buffer and return a parsed 166600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * structure. 167600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @throws ParseException if there was an error parsing. 168600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 169600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public SIPHeader parse() throws ParseException { 170600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String name = lexer.getNextToken(':'); 171600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang lexer.consume(1); 172600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String body = lexer.getLine().trim(); 173600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // we dont set any fields because the header is 174600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // ok 175600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ExtensionHeaderImpl retval = new ExtensionHeaderImpl(name); 176600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang retval.setValue(body); 177600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return retval; 178600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 179600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 180600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 181600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 182600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Parse the header name until the colon and chew WS after that. 183600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 184600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected void headerName(int tok) throws ParseException { 185600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.lexer.match(tok); 186600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.lexer.SPorHT(); 187600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.lexer.match(':'); 188600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.lexer.SPorHT(); 189600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 190600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang} 191