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:
026: package javax.microedition.sip;
027:
028: import java.util.Vector;
029:
030: import gov.nist.core.NameValueList;
031: import gov.nist.core.ParseException;
032: import gov.nist.microedition.sip.StackConnector;
033: import gov.nist.siplite.header.Header;
034: import gov.nist.siplite.header.ParametersHeader;
035: import gov.nist.siplite.header.ExtensionHeader;
036: import gov.nist.siplite.parser.ExtensionParser;
037: import gov.nist.siplite.parser.Lexer;
038:
039: /**
040: * SipHeader provides generic SIP header parser helper. This class can be used
041: * to parse bare String header values that are read from SIP message using e.g.
042: * SipConnection.getHeader() method. It should be noticed that SipHeader
043: * is separate helper class and not mandatory to use for creating SIP
044: * connections.
045: * @see JSR180 spec, v 1.0.1, p 47-51
046: *
047: */
048: public class SipHeader {
049: /**
050: * The nist-siplite corresponding header.
051: */
052: private ExtensionHeader header = null;
053:
054: /**
055: * Constructs a SipHeader from name value pair. For example:
056: * <pre>
057: * name = Contact
058: * value = <sip:UserB@192.168.200.201>;expires=3600
059: * </pre>
060: * @param name name of the header (Contact, Call-ID, ...)
061: * @param value full header value as String
062: * @throws IllegalArgumentException if the header value or
063: * name are invalid
064: */
065: public SipHeader(String name, String value)
066: throws IllegalArgumentException {
067: if (name != null) {
068: // trim() will cut control characters, so at first we have to check
069: // that the header's name doesn't contain them.
070: if ((name.indexOf('\n') != -1)
071: || (name.indexOf('\r') != -1)) {
072: throw new IllegalArgumentException("'" + name
073: + "' contains control character(s).");
074: }
075:
076: name = name.trim();
077: }
078:
079: // Validating the name.
080: if (!Lexer.isValidName(name)) {
081: throw new IllegalArgumentException(
082: "Invalid header's name: '" + name + "'");
083: }
084:
085: // Validating the value.
086: if (value != null) {
087: value = value.trim();
088: }
089:
090: if (value == null || value.equals("")) {
091: throw new IllegalArgumentException(
092: "Header's value must not be null or empty.");
093: }
094:
095: try {
096: if (Header.isAuthorization(name)) {
097: Header h = StackConnector.headerFactory.createHeader(
098: name, value);
099: NameValueList authParamList = h.getParameters();
100: String authVal = h.getValue().toString();
101:
102: header = new ExtensionHeader(name, value, authVal);
103: header.setParameters(authParamList);
104: } else {
105: ExtensionParser ep = new ExtensionParser(name + ":"
106: + value);
107: header = (ExtensionHeader) ep.parse();
108: }
109: } catch (ParseException pe) {
110: throw new IllegalArgumentException(pe.getMessage());
111: } catch (NullPointerException npe) {
112: throw new IllegalArgumentException(npe.getMessage());
113: }
114: }
115:
116: /**
117: * Sets the header name, for example Contact
118: * @param name Header name
119: * @throws IllegalArgumentException if the name is invalid
120: */
121: public void setName(java.lang.String name)
122: throws IllegalArgumentException {
123: if (name != null) {
124: name = name.trim();
125: }
126:
127: // Validating the name.
128: if (!Lexer.isValidName(name)) {
129: throw new IllegalArgumentException("Invalid name: '" + name
130: + "'");
131: }
132:
133: header.setHeaderName(name);
134: }
135:
136: /**
137: * Returns the name of this header
138: * @return the name of this header as String
139: */
140: public java.lang.String getName() {
141: return header.getName();
142: }
143:
144: /**
145: * Returns the header value without header parameters.
146: * For example for header
147: * <sip:UserB@192.168.200.201>;expires=3600 method
148: * returns <sip:UserB@192.168.200.201>
149: * In the case of an authorization or authentication header getValue()
150: * returns only the authentication scheme e.g. Digest.
151: * @return header value without header parameters
152: */
153: public java.lang.String getValue() {
154: String name = header.getName();
155: String value = header.getValue().toString();
156:
157: if (Header.isAuthorization(name)) {
158: value = value.trim();
159: int end = value.indexOf(' ');
160:
161: if (end == -1) {
162: end = value.length();
163: }
164:
165: return value.substring(0, end);
166: } else {
167: return value;
168: }
169: }
170:
171: /**
172: * Returns the full header value including parameters.
173: * For example Alice <sip:alice@atlanta.com>;tag=1928301774
174: * @return full header value including parameters
175: */
176: public java.lang.String getHeaderValue() {
177: return header.getHeaderValue();
178: }
179:
180: /**
181: * Sets the header value as String without parameters.
182: * For example <sip:UserB@192.168.200.201>.
183: * The existing (if any) header parameter values are not modified.
184: * For the authorization and authentication header this method sets
185: * the authentication scheme e.g. Digest.
186: * @param value the header value
187: * @throws IllegalArgumentException if the value is invalid or there is
188: * parameters included.
189: */
190: public void setValue(java.lang.String value)
191: throws IllegalArgumentException {
192: if (value == null || value.equals("")) {
193: throw new IllegalArgumentException(
194: "Value must not be null or empty.");
195: }
196:
197: // Validating the value.
198: if (!Lexer.isValidHeaderValue(value)) {
199: throw new IllegalArgumentException(
200: "Invalid header's value.");
201: }
202:
203: String name = header.getName();
204:
205: if (Header.isAuthorization(name)) {
206: // Authorization headers need additional validation.
207: // An existing parser is used to check the validity of the value.
208: try {
209: Header h = StackConnector.headerFactory.createHeader(
210: name, value);
211: if (((ParametersHeader) h).hasParameters()) {
212: throw new IllegalArgumentException(
213: "Value must not " + "contain parameters.");
214: }
215: } catch (ParseException pe) {
216: throw new IllegalArgumentException(pe.getMessage());
217: }
218: }
219:
220: header.setHeaderValue(value);
221: }
222:
223: /**
224: * Returns the value of one header parameter.
225: * For example, from value <sip:UserB@192.168.200.201>;expires=3600
226: * the method call getParameter(expires) will return 3600.
227: * @param name name of the header parameter
228: * @return value of header parameter. returns empty string for a parameter
229: * without value and null if the parameter does not exist.
230: */
231: public java.lang.String getParameter(java.lang.String name) {
232: NameValueList parameterList = header.getParameters();
233:
234: if (parameterList == null || name == null) {
235: return null;
236: }
237:
238: name = name.trim();
239:
240: return parameterList.getParameter(name);
241: }
242:
243: /**
244: * Returns the names of header parameters. Returns null if there are no
245: * header parameters.
246: * @return names of the header parameters. Returns null if there are
247: * no parameters.
248: */
249: public java.lang.String[] getParameterNames() {
250: NameValueList parameterList = header.getParameters();
251:
252: if (parameterList == null || parameterList.size() == 0) {
253: return null;
254: }
255:
256: Vector parameterNameList = parameterList.getNames();
257: String parameterNames[] = new String[parameterNameList.size()];
258:
259: for (int i = 0; i < parameterList.size(); i++)
260: parameterNames[i] = (String) parameterNameList.elementAt(i);
261:
262: return parameterNames;
263: }
264:
265: /**
266: * Sets value of header parameter. If parameter does not exist it
267: * will be added.
268: * For example, for header value <sip:UserB@192.168.200.201>
269: * calling setParameter(expires, 3600) will construct header value
270: * <sip:UserB@192.168.200.201>;expires=3600.
271: * If the value is null, the parameter is interpreted as a parameter
272: * without value.
273: * @param name name of the header parameter
274: * @param value value of the parameter
275: * @throws IllegalArgumentException if the parameter name or
276: * value are invalid
277: */
278: public void setParameter(java.lang.String name,
279: java.lang.String value) throws IllegalArgumentException {
280: NameValueList parameterList = header.getParameters();
281:
282: // Validating the name.
283: if (name != null) {
284: name = name.trim();
285: }
286:
287: if (!Lexer.isValidName(name)) {
288: throw new IllegalArgumentException(
289: "Invalid parameter's name.");
290: }
291:
292: // Validating the value.
293: if (value != null) {
294: value = value.trim();
295: }
296:
297: if (!Lexer.isValidParameterValue(value)) {
298: throw new IllegalArgumentException(
299: "Invalid parameter's value.");
300: }
301:
302: // If the value is null, the parameter is interpreted as a parameter
303: // without value.
304: if (value == null) {
305: value = "";
306: }
307:
308: header.setParameter(name, value);
309: }
310:
311: /**
312: * Removes the header parameter, if it is found in this header.
313: * @param name name of the header parameter
314: */
315: public void removeParameter(java.lang.String name) {
316: NameValueList parameterList = header.getParameters();
317:
318: if (parameterList != null && name != null) {
319: parameterList.delete(name);
320: }
321: }
322:
323: /**
324: * Returns the String representation of the header according to
325: * header type.
326: * For example:
327: * From: Alice <sip:alice@atlanta.com>;tag=1928301774
328: * WWW-Authenticate: Digest realm=atlanta.com,
329: * domain=sip:boxesbybob.com, qop=auth,
330: * nonce=f84f1cec41e6cbe5aea9c8e88d359,
331: * opaque=, stale=FALSE, algorithm=MD5
332: * @return encoded string of object contents
333: */
334: public java.lang.String toString() {
335: return header.toString();
336: }
337: }
|