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: */
027: package gov.nist.siplite.address;
028:
029: import java.util.Vector;
030:
031: import com.sun.midp.log.LogChannels;
032: import com.sun.midp.log.Logging;
033:
034: import gov.nist.core.*;
035: import gov.nist.microedition.sip.StackConnector;
036: import gov.nist.siplite.parser.*;
037:
038: /**
039: * Address structure. Imbeds a URI and adds a display name.
040: *
041: *
042: * <a href="{@docRoot}/uncopyright.html">This code is in the public domain.</a>
043: *
044: * @version JAIN-SIP-1.1
045: *
046: */
047: public class Address extends GenericObject {
048:
049: /** Constant field. */
050: public static final int NAME_ADDR = 1;
051:
052: /** Constant field. */
053: public static final int ADDRESS_SPEC = 2;
054:
055: /** Constant field. */
056: public static final int WILD_CARD = 3;
057:
058: /** Address type. */
059: protected int addressType;
060:
061: /** Display name field. */
062: protected String displayName;
063:
064: /** Address field. */
065: protected URI address;
066:
067: /**
068: * Gets the host port portion of the address spec.
069: * @return host:port in a HostPort structure.
070: */
071: public HostPort getHostPort() {
072: // if the address is wildcard ("*"), all properties are null
073: if (this .addressType == WILD_CARD) {
074: return null;
075: }
076: if (address.isSipURI()) {
077: return ((SipURI) address).getHostPort();
078: }
079: if (Logging.REPORT_LEVEL <= Logging.ERROR) {
080: Logging.report(Logging.ERROR, LogChannels.LC_JSR180,
081: "Wrong URI HostPort request");
082: }
083: return null;
084: }
085:
086: /**
087: * Gets the port from the imbedded URI. This assumes that a SIP URL
088: * is encapsulated in this address object.
089: *
090: * @return the port from the address.
091: *
092: */
093: public int getPort() {
094: // if the address is wildcard ("*"), return 0
095: if (this .addressType == WILD_CARD) {
096: return 0;
097: }
098: if (address.isSipURI()) {
099: SipURI uri = (SipURI) address;
100: int port = uri.getPort();
101: if (port < 0) {
102: port = uri.getDefaultPort();
103: }
104: return port;
105: }
106: if (Logging.REPORT_LEVEL <= Logging.ERROR) {
107: Logging.report(Logging.ERROR, LogChannels.LC_JSR180,
108: "getPort() for wrong URI");
109: }
110: // if the port is not set, return the default (5060)
111: return 5060;
112: }
113:
114: /**
115: * Gets the user@host:port for the address field. This assumes
116: * that the encapsulated object is a SipURI.
117: *
118: * @return string containing user@host:port.
119: */
120: public String getUserAtHostPort() {
121: // if the address is wildcard ("*"), all properties are null
122: if (addressType == WILD_CARD) {
123: return null;
124: }
125:
126: if (address.isSipURI()) {
127: SipURI uri = (SipURI) address;
128: return uri.getUserAtHostPort();
129: }
130: if (Logging.REPORT_LEVEL <= Logging.ERROR) {
131: Logging.report(Logging.ERROR, LogChannels.LC_JSR180,
132: "getUserAtHostPort() for wrong URI");
133: }
134: return address.toString();
135:
136: }
137:
138: /**
139: * Gets the host name from the address.
140: *
141: * @return the host name.
142: */
143: public String getHost() {
144: // if the address is wildcard ("*"), all properties are null
145: if (this .addressType == WILD_CARD) {
146: return null;
147: }
148: if (address.isSipURI()) {
149: // IMPL_NOTE: why not SipURI.getHost()?
150: return ((SipURI) address).getHostPort().getHost()
151: .getHostname();
152: }
153: if (Logging.REPORT_LEVEL <= Logging.ERROR) {
154: Logging.report(Logging.ERROR, LogChannels.LC_JSR180,
155: "getHost() for wrong URI");
156: }
157: return null;
158: }
159:
160: /**
161: * Sets the host part of the SIP address.
162: * @param host host part
163: * @throws IllegalArgumentException if the host part is formated wrong way
164: */
165: public void setHost(String host) throws IllegalArgumentException {
166: if (address.isSipURI()) {
167: ((SipURI) address).setHost(host);
168: } else
169: ((TelURL) address).setPostDial(host);
170: }
171:
172: /**
173: * Removes a parameter from the address.
174: *
175: * @param parameterName is the name of the parameter to remove.
176: */
177: public void removeParameter(String parameterName) {
178: // if the address is wildcard ("*"), all properties are null
179: if (this .addressType == WILD_CARD) {
180: return;
181: }
182: if (address.isSipURI()) {
183: ((SipURI) address).removeParameter(parameterName);
184: }
185: }
186:
187: /**
188: * Encodes the address as a string and return it.
189: * @return String canonical encoded version of this address.
190: */
191: public String encode() {
192: if (this .addressType == WILD_CARD) {
193: return "*";
194: }
195:
196: StringBuffer encoding = new StringBuffer();
197:
198: if (displayName != null) {
199: // Now the quotes are added to the displayName in AddressParser
200: // if they presented in the original header
201: encoding.append(displayName).append(Separators.SP);
202: }
203:
204: if (address != null) {
205: if (addressType == NAME_ADDR || displayName != null) {
206: encoding.append(Separators.LESS_THAN);
207: }
208: encoding.append(address.encode());
209: if (addressType == NAME_ADDR || displayName != null) {
210: encoding.append(Separators.GREATER_THAN);
211: }
212: }
213:
214: return encoding.toString();
215: }
216:
217: /**
218: * Creates a string representation of the address object.
219: * @return String canonical encoded version of this address.
220: */
221: public String toString() {
222: return encode();
223: }
224:
225: /**
226: * Default constructor.
227: */
228: public Address() {
229: this .addressType = NAME_ADDR;
230: }
231:
232: /**
233: * Gets the address type.
234: * @return the addres type
235: */
236: public int getAddressType() {
237: return addressType;
238: }
239:
240: /**
241: * Sets the address type. The address can be NAME_ADDR, ADDR_SPEC or
242: * WILD_CARD.
243: *
244: * @param atype int to set
245: *
246: */
247: public void setAddressType(int atype) {
248: addressType = atype;
249: }
250:
251: /**
252: * Gets the display name.
253: *
254: * @return the display name
255: *
256: */
257: public String getDisplayName() {
258: return displayName;
259: }
260:
261: /**
262: * Sets the display name member.
263: *
264: * @param dn String to set
265: * @throws IllegalArgumentException if the name contains invalid
266: * characters
267: */
268: public void setDisplayName(String dn)
269: throws IllegalArgumentException {
270:
271: if (null == dn) {
272: throw new IllegalArgumentException("Null pointer argument");
273: }
274:
275: if (dn.equals("")) {
276: // JSR180: Empty string "" removes the display name.
277: // getDisplayName() returns null if
278: // the display name is not available.
279: displayName = null;
280: } else {
281: if (false == Lexer.isValidDisplayName(dn)) {
282: throw new IllegalArgumentException(
283: "Invalid display name " + dn);
284: }
285: displayName = dn;
286: addressType = NAME_ADDR;
287: }
288: }
289:
290: /**
291: * Sets the address field.
292: *
293: * @param addr SipURI to set
294: *
295: */
296: public void setURI(URI addr) {
297: address = (URI) addr;
298: }
299:
300: /**
301: * Parses and creates the URI field.
302: *
303: * @param URI SipURI to set
304: *
305: */
306: public void setURI(String URI) {
307: URI uri = null;
308: try {
309: uri = StackConnector.addressFactory.createURI(URI);
310: } catch (ParseException pe) {
311: throw new IllegalArgumentException(pe.getMessage());
312: }
313:
314: if (uri == null)
315: throw new IllegalArgumentException("The URI is invalid");
316:
317: if (uri.isSipURI()) {
318: ((SipURI) uri).clearUriParms();
319:
320: // copy parameters value from old uri
321: if (address.isSipURI()) {
322: SipURI addr = (SipURI) address;
323: Vector names = addr.getParameterNames();
324: String value;
325: String name;
326: for (int i = 0; i < names.size(); i++) {
327: name = (String) names.elementAt(i);
328: value = addr.getParameter(name);
329: try {
330: ((SipURI) uri).setParameter(name, value);
331: } catch (ParseException ex) {
332: // intentionally ignored
333: // parameters were parsed already
334: }
335: }
336:
337: }
338: }
339:
340: setURI(uri);
341: }
342:
343: /**
344: * Compares two address specs for equality.
345: *
346: * @param other Object to compare this this address
347: *
348: * @return true if the objects match
349: *
350: */
351: public boolean equals(Object other) {
352: if (!this .getClass().equals(other.getClass())) {
353: return false;
354: }
355:
356: Address that = (Address) other;
357: if (this .addressType == WILD_CARD
358: && that.addressType != WILD_CARD) {
359: return false;
360: }
361:
362: // Ignore the display name; only compare the address spec.
363: boolean retval = this .address.equals(that.address);
364: return retval;
365: }
366:
367: /**
368: * return true if DisplayName exist.
369: *
370: * @return boolean
371: */
372: public boolean hasDisplayName() {
373: return (displayName != null);
374: }
375:
376: /**
377: * remove the displayName field
378: */
379: public void removeDisplayName() {
380: displayName = null;
381: }
382:
383: /**
384: * Return true if the embedded URI is a sip URI.
385: *
386: * @return true if the embedded URI is a SIP URI.
387: *
388: */
389: public boolean isSIPAddress() {
390: return address.isSipURI();
391: }
392:
393: /**
394: * Returns the URI address of this Address. The type of URI can be
395: * determined by the scheme.
396: *
397: * @return address parmater of the Address object
398: */
399: public URI getURI() {
400: return this .address;
401: }
402:
403: /**
404: * Returns the URI part of the address (without parameters)
405: * i.e. scheme:user@host:port.
406: * @return URI part of the address
407: */
408: public String getPlainURI() {
409: if (addressType == WILD_CARD) {
410: return null;
411: }
412: return address.getPlainURI();
413: }
414:
415: /**
416: * This determines if this address is a wildcard address. That is
417: * <code>Address.getAddress.getUserInfo() == *;</code>
418: *
419: * @return true if this name address is a wildcard, false otherwise.
420: */
421: public boolean isWildcard() {
422: return this .addressType == WILD_CARD;
423: }
424:
425: /**
426: * Sets the user part of the embedded URI.
427: *
428: * @param user user name to set for the embedded URI.
429: * @throws IllegalArgumentException if the user part contains invalid
430: * characters
431: */
432: public void setUser(String user) throws IllegalArgumentException {
433: // if the address is wildcard ("*"), all properties are null
434: if (addressType == WILD_CARD) {
435: return;
436: }
437:
438: if (address.isSipURI()) {
439: SipURI uri = (SipURI) address;
440: int colonPos;
441: if (null != user
442: && (colonPos = user.indexOf(Separators.COLON)) != -1) {
443: uri.setUser(user.substring(0, colonPos));
444: uri.setUserPassword(user.substring(colonPos + 1));
445: } else {
446: uri.setUser(user);
447: uri.clearPassword();
448: }
449: } else if (address.isTelURL()) {
450: // IMPL_NOTE : check if the tel number is valid
451: ((TelURL) address).setPhoneNumber(user);
452: } else {
453: throw new IllegalArgumentException("Can't set a user "
454: + "for this type of address");
455: }
456: }
457:
458: /**
459: * Returns the user part of SIP address.
460: * @return user part of SIP address. Returns null if the
461: * user part is missing or URI has unknown type
462: */
463: public String getUser() {
464: // RFC3261 p.222
465: // SIP-URI = "sip:" [ userinfo ] hostport
466: // uri-parameters [ headers ]
467: // SIPS-URI = "sips:" [ userinfo ] hostport
468: // uri-parameters [ headers ]
469: // userinfo = ( user / telephone-subscriber ) [ ":" password ] "@"
470: //
471: // This function returns user name/telephon number + password if it is
472: // existing
473: //
474: // if the address is wildcard ("*"), all properties are null
475:
476: if (addressType == WILD_CARD) {
477: return null;
478: }
479: if (address.isSipURI()) {
480: SipURI uri = (SipURI) address;
481: String psswd = uri.getUserPassword();
482: if (null != psswd) {
483: return new String(uri.getUser() + Separators.COLON
484: + psswd);
485: } else {
486: return uri.getUser();
487: }
488: } else if (address.isTelURL()) {
489: // IMPL_NOTE: Do we have TelURL only?
490: return ((TelURL) address).getPhoneNumber();
491: } else {
492: return null;
493: }
494: }
495:
496: /**
497: * Returns a String array of all parameter names.
498: * @return String array of parameter names. Returns null if
499: * the address does not have any parameters.
500: */
501: public String[] getParameterNames() {
502: if (addressType == WILD_CARD) {
503: return null;
504: }
505: Vector parameterNameList;
506: if (address.isSipURI()) {
507: parameterNameList = ((SipURI) address).getParameterNames();
508:
509: } else if (address.isTelURL()) {
510: parameterNameList = ((TelURL) address).getParameterNames();
511: } else {
512: return null;
513: }
514: if (null == parameterNameList || parameterNameList.size() == 0) {
515: return null;
516: }
517:
518: String parameterNames[] = new String[parameterNameList.size()];
519:
520: for (int i = 0; i < parameterNameList.size(); i++)
521: parameterNames[i] = (String) parameterNameList.elementAt(i);
522:
523: return parameterNames;
524: }
525:
526: /**
527: * Returns the scheme of SIP address.
528: * @return the scheme of this SIP address e.g. sip or sips
529: */
530: public java.lang.String getScheme() {
531: if (addressType == WILD_CARD) {
532: return null;
533: }
534: return address.getScheme();
535: }
536:
537: /**
538: * Sets the named URI parameter to the specified value. If the
539: * value is null
540: * the parameter is interpreted as a parameter without value.
541: * Existing parameter will be overwritten, otherwise the parameter
542: * is added.
543: * @param name - the named URI parameter
544: * @param value - the value
545: * @throws IllegalArgumentException - if the parameter is
546: * invalid RFC 3261,
547: * chapter 19.1.1 SIP and SIPS URI Components "URI parameters" p.149
548: */
549: public void setParameter(java.lang.String name,
550: java.lang.String value) throws IllegalArgumentException {
551: // Validating the name.
552: if (!Lexer.isValidName(name)) {
553: throw new IllegalArgumentException(
554: "Invalid parameter's name.");
555: }
556:
557: // Validating the value.
558: if (!Lexer.isValidParameterValue(value)) {
559: throw new IllegalArgumentException(
560: "Invalid parameter's value.");
561: }
562:
563: URI uri = getURI();
564: if (uri.isSipURI()) {
565: try {
566: ((SipURI) uri).setParameter(name, value);
567: } catch (ParseException pe) {
568: throw new IllegalArgumentException(pe.getMessage());
569: }
570: }
571: // IMPL_NOTE : do something for the tel URL
572: }
573:
574: /**
575: * Returns the value associated with the named URI parameter.
576: * @param name - the name of the parameter
577: * @return the value of the named parameter,
578: * or empty string for parameters
579: * without value and null if the parameter is not defined
580: */
581: public java.lang.String getParameter(java.lang.String name) {
582: URI uri = getURI();
583: if (uri.isSipURI()) {
584: return ((SipURI) uri).getParameter(name);
585: }
586: // IMPL_NOTE : return something for the tel URL
587: return null;
588: }
589:
590: /**
591: * Clone this structure.
592: * @return Object Address
593: */
594: public Object clone() {
595: Address retval = new Address();
596: retval.addressType = this .addressType;
597: if (displayName != null) {
598: retval.displayName = new String(displayName);
599: }
600: if (address != null) {
601: retval.address = (URI) address.clone();
602: }
603: return (Object) retval;
604:
605: }
606:
607: }
|