001: /*
002: * Portions Copyright 2000-2007 Sun Microsystems, Inc. All Rights
003: * Reserved. Use is subject to license terms.
004: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License version
008: * 2 only, as published by the Free Software Foundation.
009: *
010: * This program is distributed in the hope that it will be useful, but
011: * WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * General Public License version 2 for more details (a copy is
014: * included at /legal/license.txt).
015: *
016: * You should have received a copy of the GNU General Public License
017: * version 2 along with this work; if not, write to the Free Software
018: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
019: * 02110-1301 USA
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
022: * Clara, CA 95054 or visit www.sun.com if you need additional
023: * information or have any questions.
024: */
025: package gov.nist.siplite.parser;
026:
027: import gov.nist.siplite.header.*;
028: import gov.nist.core.*;
029:
030: /**
031: * Parser for via headers.
032: *
033: * @version JAIN-SIP-1.1
034: *
035: *
036: * <a href="{@docRoot}/uncopyright.html">This code is in the public domain.</a>
037: *
038: */
039: public class ViaParser extends HeaderParser {
040: /** Default constructor. */
041: ViaParser() {
042: }
043:
044: /**
045: * Constructor with initial via header string.
046: * @param via initial via header
047: */
048: public ViaParser(String via) {
049: super (via);
050: }
051:
052: /**
053: * Constructor with initial lexer engine.
054: * @param lexer initial lexer engine
055: */
056: public ViaParser(Lexer lexer) {
057: super (lexer);
058: }
059:
060: /**
061: * A parser for the essential part of the via header.
062: * @param v initial via header
063: * @exception ParseException if a parsing error occurs
064: */
065: private void parseVia(ViaHeader v) throws ParseException {
066: // The protocol
067: lexer.match(TokenTypes.ID);
068: Token protocolName = lexer.getNextToken();
069:
070: this .lexer.SPorHT();
071: // consume the "/"
072: lexer.match('/');
073: this .lexer.SPorHT();
074: lexer.match(TokenTypes.ID);
075: this .lexer.SPorHT();
076: Token protocolVersion = lexer.getNextToken();
077:
078: this .lexer.SPorHT();
079:
080: // We consume the "/"
081: lexer.match('/');
082: this .lexer.SPorHT();
083: lexer.match(TokenTypes.ID);
084: this .lexer.SPorHT();
085:
086: Token transport = lexer.getNextToken();
087: this .lexer.SPorHT();
088:
089: Protocol protocol = new Protocol();
090: protocol.setProtocolName(protocolName.getTokenValue());
091: protocol.setProtocolVersion(protocolVersion.getTokenValue());
092: protocol.setTransport(transport.getTokenValue());
093: v.setSentProtocol(protocol);
094:
095: // sent-By
096: HostNameParser hnp = new HostNameParser(this .getLexer());
097: HostPort hostPort = hnp.hostPort();
098: v.setSentBy(hostPort);
099:
100: // Ignore blanks
101: this .lexer.SPorHT();
102:
103: // parameters
104: while (lexer.lookAhead(0) == ';') {
105: this .lexer.match(';');
106: this .lexer.SPorHT();
107: NameValue nameValue = this .nameValue();
108: String name = nameValue.getName();
109: nameValue.setName(name.toLowerCase());
110: v.setParameter(nameValue);
111: this .lexer.SPorHT();
112: }
113:
114: if (lexer.lookAhead(0) == '(') {
115: this .lexer.selectLexer("charLexer");
116: lexer.consume(1);
117: StringBuffer comment = new StringBuffer();
118: boolean cond = true;
119: while (true) {
120: char ch = lexer.lookAhead(0);
121: if (ch == ')') {
122: lexer.consume(1);
123: break;
124: } else if (ch == '\\') {
125: // Escaped character
126: Token tok = lexer.getNextToken();
127: comment.append(tok.getTokenValue());
128: lexer.consume(1);
129: tok = lexer.getNextToken();
130: comment.append(tok.getTokenValue());
131: lexer.consume(1);
132: } else if (ch == '\n') {
133: break;
134: } else {
135: comment.append(ch);
136: lexer.consume(1);
137: }
138: }
139: v.setComment(comment.toString());
140: }
141:
142: }
143:
144: /**
145: * Invokes parser for Via header field.
146: * @return the parsed Via header
147: * @exception ParseException if a parsing error occurs
148: */
149: public Header parse() throws ParseException {
150: if (debug)
151: dbg_enter("parse");
152: try {
153: ViaList viaList = new ViaList();
154: // The first via header.
155: this .lexer.match(TokenTypes.VIA);
156: this .lexer.SPorHT(); // ignore blanks
157: this .lexer.match(':'); // expect a colon.
158: this .lexer.SPorHT(); // ingore blanks.
159:
160: while (true) {
161: ViaHeader v = new ViaHeader();
162: parseVia(v);
163: viaList.add(v);
164: this .lexer.SPorHT(); // eat whitespace.
165: if (this .lexer.lookAhead(0) == ',') {
166: this .lexer.consume(1); // Consume the comma
167: this .lexer.SPorHT(); // Ignore space after.
168: }
169: if (this .lexer.lookAhead(0) == '\n')
170: break;
171: }
172: this .lexer.match('\n');
173: return viaList;
174: } finally {
175: if (debug)
176: dbg_leave("parse");
177: }
178:
179: }
180:
181: }
|