• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
26 /*******************************************************************************
27 * Product of NIST/ITL Advanced Networking Technologies Division (ANTD).        *
28 *******************************************************************************/
29 package gov.nist.javax.sip.address;
30 
31 /*
32  *Bug fix contributions
33  *Daniel J. Martinez Manzano <dani@dif.um.es>
34  *Stefan Marx.
35  *pmusgrave@newheights.com (Additions for gruu and outbound drafts)
36  *Jeroen van Bemmel ( additions for SCTP transport )
37  */
38 import gov.nist.core.*;
39 import java.util.*;
40 import java.text.ParseException;
41 
42 import javax.sip.PeerUnavailableException;
43 import javax.sip.SipFactory;
44 import javax.sip.address.SipURI;
45 import javax.sip.header.Header;
46 import javax.sip.header.HeaderFactory;
47 
48 
49 /**
50  * Implementation of the SipURI interface.
51  *
52  *
53  * @author M. Ranganathan   <br/>
54  * @version 1.2 $Revision: 1.22 $ $Date: 2009/11/15 19:50:45 $
55  *
56  *
57  *
58  */
59 public class SipUri extends GenericURI implements javax.sip.address.SipURI , SipURIExt{
60 
61 
62     private static final long serialVersionUID = 7749781076218987044L;
63 
64     /** Authority for the uri.
65      */
66 
67     protected Authority authority;
68 
69     /** uriParms list
70      */
71     protected NameValueList uriParms;
72 
73     /** qheaders list
74      */
75     protected NameValueList qheaders;
76 
77     /** telephoneSubscriber field
78      */
79     protected TelephoneNumber telephoneSubscriber;
80 
SipUri()81     public SipUri() {
82         this.scheme = SIP;
83         this.uriParms = new NameValueList();
84         this.qheaders = new NameValueList();
85         this.qheaders.setSeparator("&");
86     }
87 
88     /** Constructor given the scheme.
89     * The scheme must be either Sip or Sips
90     */
setScheme(String scheme)91     public void setScheme(String scheme) {
92         if (scheme.compareToIgnoreCase(SIP) != 0
93             && scheme.compareToIgnoreCase(SIPS) != 0)
94             throw new IllegalArgumentException("bad scheme " + scheme);
95         this.scheme = scheme.toLowerCase();
96     }
97 
98     /** Get the scheme.
99      */
getScheme()100     public String getScheme() {
101         return scheme;
102     }
103 
104     /**
105      * clear all URI Parameters.
106      * @since v1.0
107      */
clearUriParms()108     public void clearUriParms() {
109         uriParms = new NameValueList();
110     }
111     /**
112     *Clear the password from the user part if it exists.
113     */
clearPassword()114     public void clearPassword() {
115         if (this.authority != null) {
116             UserInfo userInfo = authority.getUserInfo();
117             if (userInfo != null)
118                 userInfo.clearPassword();
119         }
120     }
121 
122     /** Get the authority.
123     */
getAuthority()124     public Authority getAuthority() {
125         return this.authority;
126     }
127 
128     /**
129      * Clear all Qheaders.
130      */
clearQheaders()131     public void clearQheaders() {
132         qheaders = new NameValueList();
133     }
134 
135     /**
136      * Compare two URIs and return true if they are equal.
137      * @param that the object to compare to.
138      * @return true if the object is equal to this object.
139      *
140      * JvB: Updated to define equality in terms of API methods, according to the rules
141      * in RFC3261 section 19.1.4
142      *
143      * Jean Deruelle: Updated to define equality of API methods, according to the rules
144      * in RFC3261 section 19.1.4 convert potential ie :
145      *    %HEX HEX encoding parts of the URI before comparing them
146      *    transport param added in comparison
147      *    header equality enforced in comparison
148      *
149      */
150     @SuppressWarnings("unchecked")
151     @Override
equals(Object that)152     public boolean equals(Object that) {
153 
154         // Shortcut for same object
155         if (that==this) return true;
156 
157         if (that instanceof SipURI) {
158             final SipURI a = this;
159             final SipURI b = (SipURI) that;
160 
161             // A SIP and SIPS URI are never equivalent
162             if ( a.isSecure() ^ b.isSecure() ) return false;
163 
164             // For two URIs to be equal, the user, password, host, and port
165             // components must match; comparison of userinfo is case-sensitive
166             if (a.getUser()==null ^ b.getUser()==null) return false;
167             if (a.getUserPassword()==null ^ b.getUserPassword()==null) return false;
168 
169             if (a.getUser()!=null && !RFC2396UrlDecoder.decode(a.getUser()).equals(RFC2396UrlDecoder.decode(b.getUser()))) return false;
170             if (a.getUserPassword()!=null && !RFC2396UrlDecoder.decode(a.getUserPassword()).equals(RFC2396UrlDecoder.decode(b.getUserPassword()))) return false;
171             if (a.getHost() == null ^ b.getHost() == null) return false;
172             if (a.getHost() != null && !a.getHost().equalsIgnoreCase(b.getHost())) return false;
173             if (a.getPort() != b.getPort()) return false;
174 
175             // URI parameters
176             for (Iterator i = a.getParameterNames(); i.hasNext();) {
177                 String pname = (String) i.next();
178 
179                 String p1 = a.getParameter(pname);
180                 String p2 = b.getParameter(pname);
181 
182                 // those present in both must match (case-insensitive)
183                 if (p1!=null && p2!=null && !RFC2396UrlDecoder.decode(p1).equalsIgnoreCase(RFC2396UrlDecoder.decode(p2))) return false;
184             }
185 
186             // transport, user, ttl or method must match when present in either
187             if (a.getTransportParam()==null ^ b.getTransportParam()==null) return false;
188             if (a.getUserParam()==null ^ b.getUserParam()==null) return false;
189             if (a.getTTLParam()==-1 ^ b.getTTLParam()==-1) return false;
190             if (a.getMethodParam()==null ^ b.getMethodParam()==null) return false;
191             if (a.getMAddrParam()==null ^ b.getMAddrParam()==null) return false;
192 
193             // Headers: must match according to their definition.
194             if(a.getHeaderNames().hasNext() && !b.getHeaderNames().hasNext()) return false;
195             if(!a.getHeaderNames().hasNext() && b.getHeaderNames().hasNext()) return false;
196 
197             if(a.getHeaderNames().hasNext() && b.getHeaderNames().hasNext()) {
198                 HeaderFactory headerFactory = null;
199                 try {
200                     headerFactory = SipFactory.getInstance().createHeaderFactory();
201                 } catch (PeerUnavailableException e) {
202                     Debug.logError("Cannot get the header factory to parse the header of the sip uris to compare", e);
203                     return false;
204                 }
205                 for (Iterator i = a.getHeaderNames(); i.hasNext();) {
206                     String hname = (String) i.next();
207 
208                     String h1 = a.getHeader(hname);
209                     String h2 = b.getHeader(hname);
210 
211                     if(h1 == null && h2 != null) return false;
212                     if(h2 == null && h1 != null) return false;
213                     // The following check should not be needed but we add it for findbugs.
214                     if(h1 == null && h2 == null) continue;
215                     try {
216                         Header header1 = headerFactory.createHeader(hname, RFC2396UrlDecoder.decode(h1));
217                         Header header2 = headerFactory.createHeader(hname, RFC2396UrlDecoder.decode(h2));
218                         // those present in both must match according to the equals method of the corresponding header
219                         if (!header1.equals(header2)) return false;
220                     } catch (ParseException e) {
221                         Debug.logError("Cannot parse one of the header of the sip uris to compare " + a + " " + b, e);
222                         return false;
223                     }
224                 }
225             }
226 
227             // Finally, we can conclude that they are indeed equal
228             return true;
229         }
230         return false;
231     }
232 
233     /**
234      * Construct a URL from the parsed structure.
235      * @return String
236      */
encode()237     public String encode() {
238         return encode(new StringBuffer()).toString();
239     }
240 
encode(StringBuffer buffer)241     public StringBuffer encode(StringBuffer buffer) {
242         buffer.append(scheme).append(COLON);
243         if (authority != null)
244             authority.encode(buffer);
245         if (!uriParms.isEmpty()) {
246             buffer.append(SEMICOLON);
247             uriParms.encode(buffer);
248         }
249         if (!qheaders.isEmpty()) {
250             buffer.append(QUESTION);
251             qheaders.encode(buffer);
252         }
253         return buffer;
254     }
255 
256     /** Return a string representation.
257     *
258     *@return the String representation of this URI.
259     *
260     */
toString()261     public String toString() {
262         return this.encode();
263     }
264 
265     /**
266      * getUser@host
267      * @return user@host portion of the uri (null if none exists).
268      *
269      * Peter Musgrave - handle null user
270      */
getUserAtHost()271     public String getUserAtHost() {
272         String user = "";
273         if (authority.getUserInfo() != null)
274             user = authority.getUserInfo().getUser();
275 
276         String host = authority.getHost().encode();
277         StringBuffer s = null;
278         if (user.equals("")) {
279             s = new StringBuffer();
280         } else {
281             s = new StringBuffer(user).append(AT);
282         }
283         return s.append(host).toString();
284     }
285 
286     /**
287      * getUser@host
288      * @return user@host portion of the uri (null if none exists).
289      */
getUserAtHostPort()290     public String getUserAtHostPort() {
291         String user = "";
292         if (authority.getUserInfo() != null)
293             user = authority.getUserInfo().getUser();
294 
295         String host = authority.getHost().encode();
296         int port = authority.getPort();
297         // If port not set assign the default.
298         StringBuffer s = null;
299         if (user.equals("")) {
300             s = new StringBuffer();
301         } else {
302             s = new StringBuffer(user).append(AT);
303         }
304         if (port != -1) {
305             return s.append(host).append(COLON).append(port).toString();
306         } else
307             return s.append(host).toString();
308 
309     }
310 
311     /**
312      * get the parameter (do a name lookup) and return null if none exists.
313      * @param parmname Name of the parameter to get.
314      * @return Parameter of the given name (null if none exists).
315      */
getParm(String parmname)316     public Object getParm(String parmname) {
317         Object obj = uriParms.getValue(parmname);
318         return obj;
319     }
320 
321     /**
322      * Get the method parameter.
323      * @return Method parameter.
324      */
getMethod()325     public String getMethod() {
326         return (String) getParm(METHOD);
327     }
328 
329     /**
330      * Accessor for URI parameters
331      * @return A name-value list containing the parameters.
332      */
getParameters()333     public NameValueList getParameters() {
334         return uriParms;
335     }
336 
337     /** Remove the URI parameters.
338     *
339     */
removeParameters()340     public void removeParameters() {
341         this.uriParms = new NameValueList();
342     }
343 
344     /**
345      * Accessor forSIPObjects
346      * @return Get the query headers (that appear after the ? in
347      * the URL)
348      */
getQheaders()349     public NameValueList getQheaders() {
350         return qheaders;
351     }
352 
353     /**
354      * Get the urse parameter.
355      * @return User parameter (user= phone or user=ip).
356      */
getUserType()357     public String getUserType() {
358         return (String) uriParms.getValue(USER);
359     }
360 
361     /**
362      * Get the password of the user.
363      * @return User password when it embedded as part of the uri
364      * ( a very bad idea).
365      */
getUserPassword()366     public String getUserPassword() {
367         if (authority == null)
368             return null;
369         return authority.getPassword();
370     }
371 
372     /** Set the user password.
373      *@param password - password to set.
374      */
setUserPassword(String password)375     public void setUserPassword(String password) {
376         if (this.authority == null)
377             this.authority = new Authority();
378         authority.setPassword(password);
379     }
380 
381     /**
382      * Returns the stucture corresponding to the telephone number
383      * provided that the user is a telephone subscriber.
384      * @return TelephoneNumber part of the url (only makes sense
385      * when user = phone is specified)
386      */
getTelephoneSubscriber()387     public TelephoneNumber getTelephoneSubscriber() {
388         if (telephoneSubscriber == null) {
389 
390             telephoneSubscriber = new TelephoneNumber();
391         }
392         return telephoneSubscriber;
393     }
394 
395     /**
396      * Get the host and port of the server.
397      * @return get the host:port part of the url parsed into a
398      * structure.
399      */
getHostPort()400     public HostPort getHostPort() {
401 
402         if (authority == null || authority.getHost() == null )
403             return null;
404         else {
405             return authority.getHostPort();
406         }
407     }
408 
409     /** Get the port from the authority field.
410     *
411     *@return the port from the authority field.
412     */
getPort()413     public int getPort() {
414         HostPort hp = this.getHostPort();
415         if (hp == null)
416             return -1;
417         return hp.getPort();
418     }
419 
420     /** Get the host protion of the URI.
421     * @return the host portion of the url.
422     */
getHost()423     public String getHost() {
424         if ( authority == null) return null;
425         else if (authority.getHost() == null ) return null;
426         else return authority.getHost().encode();
427     }
428 
429     /**
430      * returns true if the user is a telephone subscriber.
431      *  If the host is an Internet telephony
432      * gateway, a telephone-subscriber field MAY be used instead
433      * of a user field. The telephone-subscriber field uses the
434      * notation of RFC 2806 [19]. Any characters of the un-escaped
435      * "telephone-subscriber" that are not either in the set
436      * "unreserved" or "user-unreserved" MUST be escaped. The set
437      * of characters not reserved in the RFC 2806 description of
438      * telephone-subscriber contains a number of characters in
439      * various syntax elements that need to be escaped when used
440      * in SIP URLs, for example quotation marks (%22), hash (%23),
441      * colon (%3a), at-sign (%40) and the "unwise" characters,
442      * i.e., punctuation of %5b and above.
443      *
444      * The telephone number is a special case of a user name and
445      * cannot be distinguished by a BNF. Thus, a URL parameter,
446      * user, is added to distinguish telephone numbers from user
447      * names.
448      *
449      * The user parameter value "phone" indicates that the user
450      * part contains a telephone number. Even without this
451      * parameter, recipients of SIP URLs MAY interpret the pre-@
452      * part as a telephone number if local restrictions on the
453      * @return true if the user is a telephone subscriber.
454      */
isUserTelephoneSubscriber()455     public boolean isUserTelephoneSubscriber() {
456         String usrtype = (String) uriParms.getValue(USER);
457         if (usrtype == null)
458             return false;
459         return usrtype.equalsIgnoreCase(PHONE);
460     }
461 
462     /**
463      *remove the ttl value from the parameter list if it exists.
464      */
removeTTL()465     public void removeTTL() {
466         if (uriParms != null)
467             uriParms.delete(TTL);
468     }
469 
470     /**
471      *Remove the maddr param if it exists.
472      */
removeMAddr()473     public void removeMAddr() {
474         if (uriParms != null)
475             uriParms.delete(MADDR);
476     }
477 
478     /**
479      *Delete the transport string.
480      */
removeTransport()481     public void removeTransport() {
482         if (uriParms != null)
483             uriParms.delete(TRANSPORT);
484     }
485 
486     /** Remove a header given its name (provided it exists).
487      * @param name name of the header to remove.
488      */
removeHeader(String name)489     public void removeHeader(String name) {
490         if (qheaders != null)
491             qheaders.delete(name);
492     }
493 
494     /** Remove all headers.
495      */
removeHeaders()496     public void removeHeaders() {
497         qheaders = new NameValueList();
498     }
499 
500     /**
501      * Set the user type.
502      */
removeUserType()503     public void removeUserType() {
504         if (uriParms != null)
505             uriParms.delete(USER);
506     }
507 
508     /**
509      *remove the port setting.
510      */
removePort()511     public void removePort() {
512         authority.removePort();
513     }
514 
515     /**
516      * remove the Method.
517      */
removeMethod()518     public void removeMethod() {
519         if (uriParms != null)
520             uriParms.delete(METHOD);
521     }
522 
523     /** Sets the user of SipURI. The identifier of a particular resource at
524      * the host being addressed. The user and the user password including the
525      * "at" sign make up the user-info.
526      *
527      * @param uname The new String value of the user.
528      * @throws ParseException which signals that an error has been reached
529      * unexpectedly while parsing the user value.
530      */
setUser(String uname)531     public void setUser(String uname) {
532         if (this.authority == null) {
533             this.authority = new Authority();
534         }
535 
536         this.authority.setUser(uname);
537     }
538 
539     /** Remove the user.
540      */
removeUser()541     public void removeUser() {
542         this.authority.removeUserInfo();
543     }
544 
545     /** Set the default parameters for this URI.
546      * Do nothing if the parameter is already set to some value.
547      * Otherwise set it to the given value.
548      * @param name Name of the parameter to set.
549      * @param value value of the parameter to set.
550      */
setDefaultParm(String name, Object value)551     public void setDefaultParm(String name, Object value) {
552         if (uriParms.getValue(name) == null) {
553             NameValue nv = new NameValue(name, value);
554             uriParms.set(nv);
555         }
556     }
557 
558     /** Set the authority member
559      * @param authority Authority to set.
560      */
setAuthority(Authority authority)561     public void setAuthority(Authority authority) {
562         this.authority = authority;
563     }
564 
565     /** Set the host for this URI.
566      * @param h host to set.
567      */
setHost(Host h)568     public void setHost(Host h) {
569         if (this.authority == null)
570             this.authority = new Authority();
571         this.authority.setHost(h);
572     }
573 
574     /** Set the uriParms member
575      * @param parms URI parameters to set.
576      */
setUriParms(NameValueList parms)577     public void setUriParms(NameValueList parms) {
578         uriParms = parms;
579     }
580 
581     /**
582      * Set a given URI parameter. Note - parameter must be properly
583     *  encoded before the function is called.
584      * @param name Name of the parameter to set.
585      * @param value value of the parameter to set.
586      */
setUriParm(String name, Object value)587     public void setUriParm(String name, Object value) {
588         NameValue nv = new NameValue(name, value);
589         uriParms.set(nv);
590     }
591 
592     /** Set the qheaders member
593      * @param parms query headers to set.
594      */
setQheaders(NameValueList parms)595     public void setQheaders(NameValueList parms) {
596         qheaders = parms;
597     }
598 
599     /**
600      * Set the MADDR parameter .
601      * @param mAddr Host Name to set
602      */
setMAddr(String mAddr)603     public void setMAddr(String mAddr) {
604         NameValue nameValue = uriParms.getNameValue(MADDR);
605         Host host = new Host();
606         host.setAddress(mAddr);
607         if (nameValue != null)
608             nameValue.setValueAsObject(host);
609         else {
610             nameValue = new NameValue(MADDR, host);
611             uriParms.set(nameValue);
612         }
613     }
614 
615     /** Sets the value of the user parameter. The user URI parameter exists to
616      * distinguish telephone numbers from user names that happen to look like
617      * telephone numbers.  This is equivalent to setParameter("user", user).
618      *
619      * @param usertype New value String value of the method parameter
620      */
setUserParam(String usertype)621     public void setUserParam(String usertype) {
622         uriParms.set(USER, usertype);
623     }
624 
625     /**
626      * Set the Method
627      * @param method method parameter
628      */
setMethod(String method)629     public void setMethod(String method) {
630         uriParms.set(METHOD, method);
631     }
632 
633     /**
634     * Sets ISDN subaddress of SipURL
635     * @param isdnSubAddress ISDN subaddress
636     */
setIsdnSubAddress(String isdnSubAddress)637     public void setIsdnSubAddress(String isdnSubAddress) {
638         if (telephoneSubscriber == null)
639             telephoneSubscriber = new TelephoneNumber();
640         telephoneSubscriber.setIsdnSubaddress(isdnSubAddress);
641     }
642 
643     /**
644      * Set the telephone subscriber field.
645      * @param tel Telephone subscriber field to set.
646      */
setTelephoneSubscriber(TelephoneNumber tel)647     public void setTelephoneSubscriber(TelephoneNumber tel) {
648         telephoneSubscriber = tel;
649     }
650 
651     /** set the port to a given value.
652      * @param p Port to set.
653      */
setPort(int p)654     public void setPort(int p) {
655         if (authority == null)
656             authority = new Authority();
657         authority.setPort(p);
658     }
659 
660     /**
661      * Boolean to check if a parameter of a given name exists.
662      * @param name Name of the parameter to check on.
663      * @return a boolean indicating whether the parameter exists.
664      */
hasParameter(String name)665     public boolean hasParameter(String name) {
666 
667         return uriParms.getValue(name) != null;
668     }
669 
670     /**
671      * Set the query header when provided as a name-value pair.
672      * @param nameValue qeuery header provided as a name,value pair.
673      */
setQHeader(NameValue nameValue)674     public void setQHeader(NameValue nameValue) {
675         this.qheaders.set(nameValue);
676     }
677 
678     /** Set the parameter as given.
679      *@param nameValue - parameter to set.
680      */
setUriParameter(NameValue nameValue)681     public void setUriParameter(NameValue nameValue) {
682         this.uriParms.set(nameValue);
683     }
684 
685     /** Return true if the transport parameter is defined.
686      * @return true if transport appears as a parameter and false otherwise.
687      */
hasTransport()688     public boolean hasTransport() {
689         return hasParameter(TRANSPORT);
690     }
691 
692     /**
693      * Remove a parameter given its name
694      * @param name -- name of the parameter to remove.
695      */
removeParameter(String name)696     public void removeParameter(String name) {
697         uriParms.delete(name);
698     }
699 
700     /** Set the hostPort field of the imbedded authority field.
701      *@param hostPort is the hostPort to set.
702      */
setHostPort(HostPort hostPort)703     public void setHostPort(HostPort hostPort) {
704         if (this.authority == null) {
705             this.authority = new Authority();
706         }
707         authority.setHostPort(hostPort);
708     }
709 
710     /** clone this.
711      */
clone()712     public Object clone() {
713         SipUri retval = (SipUri) super.clone();
714         if (this.authority != null)
715             retval.authority = (Authority) this.authority.clone();
716         if (this.uriParms != null)
717             retval.uriParms = (NameValueList) this.uriParms.clone();
718         if (this.qheaders != null)
719             retval.qheaders = (NameValueList) this.qheaders.clone();
720         if (this.telephoneSubscriber != null)
721             retval.telephoneSubscriber = (TelephoneNumber) this.telephoneSubscriber.clone();
722         return retval;
723     }
724 
725     /**
726      * Returns the value of the named header, or null if it is not set.
727      * SIP/SIPS URIs may specify headers. As an example, the URI
728      * sip:joe@jcp.org?priority=urgent has a header "priority" whose
729      * value is "urgent".
730      *
731      * @param name name of header to retrieve
732      * @return the value of specified header
733      */
getHeader(String name)734     public String getHeader(String name) {
735         return this.qheaders.getValue(name) != null
736             ? this.qheaders.getValue(name).toString()
737             : null;
738 
739     }
740 
741     /**
742      * Returns an Iterator over the names (Strings) of all headers present
743      * in this SipURI.
744      *
745      * @return an Iterator over all the header names
746      */
getHeaderNames()747     public Iterator<String> getHeaderNames() {
748         return this.qheaders.getNames();
749 
750     }
751 
752     /** Returns the value of the <code>lr</code> parameter, or null if this
753      * is not set. This is equivalent to getParameter("lr").
754      *
755      * @return the value of the <code>lr</code> parameter
756      */
getLrParam()757     public String getLrParam() {
758         boolean haslr = this.hasParameter(LR);
759         return haslr ? "true" : null;
760     }
761 
762     /** Returns the value of the <code>maddr</code> parameter, or null if this
763      * is not set. This is equivalent to getParameter("maddr").
764      *
765      * @return the value of the <code>maddr</code> parameter
766      */
getMAddrParam()767     public String getMAddrParam() {
768         NameValue maddr = uriParms.getNameValue(MADDR);
769         if (maddr == null)
770             return null;
771         String host = (String) maddr.getValueAsObject();
772         return host;
773     }
774 
775     /**
776      * Returns the value of the <code>method</code> parameter, or null if this
777      * is not set. This is equivalent to getParameter("method").
778      *
779      * @return  the value of the <code>method</code> parameter
780      */
getMethodParam()781     public String getMethodParam() {
782         return this.getParameter(METHOD);
783     }
784 
785     /**
786      * Returns the value of the named parameter, or null if it is not set. A
787      * zero-length String indicates flag parameter.
788      *
789      * @param name name of parameter to retrieve
790      * @return the value of specified parameter
791      */
getParameter(String name)792     public String getParameter(String name) {
793         Object val = uriParms.getValue(name);
794         if (val == null)
795             return null;
796         if (val instanceof GenericObject)
797             return ((GenericObject) val).encode();
798         else
799             return val.toString();
800     }
801 
802     /**
803      * Returns an Iterator over the names (Strings) of all parameters present
804      *
805      * in this ParametersHeader.
806      *
807      *
808      *
809      * @return an Iterator over all the parameter names
810      *
811      */
getParameterNames()812     public Iterator<String> getParameterNames() {
813         return this.uriParms.getNames();
814     }
815 
816     /** Returns the value of the "ttl" parameter, or -1 if this is not set.
817      * This method is equivalent to getParameter("ttl").
818      *
819      * @return the value of the <code>ttl</code> parameter
820      */
getTTLParam()821     public int getTTLParam() {
822         Integer ttl = (Integer) uriParms.getValue("ttl");
823         if (ttl != null)
824             return ttl.intValue();
825         else
826             return -1;
827     }
828 
829     /** Returns the value of the "transport" parameter, or null if this is not
830      * set. This is equivalent to getParameter("transport").
831      *
832      * @return the transport paramter of the SipURI
833      */
getTransportParam()834     public String getTransportParam() {
835         if (uriParms != null) {
836             return (String) uriParms.getValue(TRANSPORT);
837         } else
838             return null;
839     }
840 
841     /** Returns the value of the <code>userParam</code>,
842      *or null if this is not set.
843      * <p>
844      * This is equivalent to getParameter("user").
845      *
846      * @return the value of the <code>userParam</code> of the SipURI
847      */
getUser()848     public String getUser() {
849         return authority.getUser();
850     }
851 
852     /** Returns true if this SipURI is secure i.e. if this SipURI represents a
853      * sips URI. A sip URI returns false.
854      *
855      * @return  <code>true</code> if this SipURI represents a sips URI, and
856      * <code>false</code> if it represents a sip URI.
857      */
isSecure()858     public boolean isSecure() {
859         return this.getScheme().equalsIgnoreCase(SIPS);
860     }
861 
862     /** This method determines if this is a URI with a scheme of "sip" or "sips".
863      *
864      * @return true if the scheme is "sip" or "sips", false otherwise.
865      */
isSipURI()866     public boolean isSipURI() {
867         return true;
868     }
869 
870     /** Sets the value of the specified header fields to be included in a
871      * request constructed from the URI. If the header already had a value it
872      * will be overwritten.
873      *
874      * @param name - a String specifying the header name
875      * @param value - a String specifying the header value
876      */
setHeader(String name, String value)877     public void setHeader(String name, String value) {
878         NameValue nv = new NameValue(name, value);
879         qheaders.set(nv);
880 
881     }
882 
883     /**
884      * Set the host portion of the SipURI
885      *
886      * @param host host to set.
887      */
setHost(String host)888     public void setHost(String host) throws ParseException {
889         Host h = new Host(host);
890         this.setHost(h);
891     }
892 
893     /** Sets the value of the <code>lr</code> parameter of this SipURI. The lr
894      * parameter, when present, indicates that the element responsible for
895      * this resource implements the routing mechanisms specified in RFC 3261.
896      * This parameter will be used in the URIs proxies place in the
897      * Record-Route header field values, and may appear in the URIs in a
898      * pre-existing route set.
899      */
setLrParam()900     public void setLrParam() {
901         this.uriParms.set("lr",null);   // JvB: fixed to not add duplicates
902     }
903 
904     /**
905      * Sets the value of the <code>maddr</code> parameter of this SipURI. The
906      * maddr parameter indicates the server address to be contacted for this
907      * user, overriding any address derived from the host field. This is
908      * equivalent to setParameter("maddr", maddr).
909      *
910      * @param  maddr New value of the <code>maddr</code> parameter
911      */
setMAddrParam(String maddr)912     public void setMAddrParam(String maddr) throws ParseException {
913         if (maddr == null)
914             throw new NullPointerException("bad maddr");
915         setParameter("maddr", maddr);
916     }
917 
918     /** Sets the value of the <code>method</code> parameter. This specifies
919      * which SIP method to use in requests directed at this URI. This is
920      * equivalent to setParameter("method", method).
921      *
922      * @param  method - new value String value of the method parameter
923      */
setMethodParam(String method)924     public void setMethodParam(String method) throws ParseException {
925         setParameter("method", method);
926     }
927 
928     /**
929      * Sets the value of the specified parameter. If the parameter already had
930      *
931      * a value it will be overwritten. A zero-length String indicates flag
932      *
933      * parameter.
934      *
935      *
936      *
937      * @param name - a String specifying the parameter name
938      *
939      * @param value - a String specifying the parameter value
940      *
941      * @throws ParseException which signals that an error has been reached
942      *
943      * unexpectedly while parsing the parameter name or value.
944      *
945      */
setParameter(String name, String value)946     public void setParameter(String name, String value) throws ParseException {
947         if (name.equalsIgnoreCase("ttl")) {
948             try {
949                 Integer.parseInt(value);
950             } catch (NumberFormatException ex) {
951                 throw new ParseException("bad parameter " + value, 0);
952             }
953         }
954         uriParms.set(name,value);
955     }
956 
957     /** Sets the scheme of this URI to sip or sips depending on whether the
958      * argument is true or false. The default value is false.
959      *
960      * @param secure - the boolean value indicating if the SipURI is secure.
961      */
setSecure(boolean secure)962     public void setSecure(boolean secure) {
963         if (secure)
964             this.scheme = SIPS;
965         else
966             this.scheme = SIP;
967     }
968 
969     /** Sets the value of the <code>ttl</code> parameter. The ttl parameter
970      * specifies the time-to-live value when packets are sent using UDP
971      * multicast. This is equivalent to setParameter("ttl", ttl).
972      *
973      * @param ttl - new value of the <code>ttl</code> parameter
974      */
setTTLParam(int ttl)975     public void setTTLParam(int ttl) {
976         if (ttl <= 0)
977             throw new IllegalArgumentException("Bad ttl value");
978         if (uriParms != null) {
979             NameValue nv = new NameValue("ttl", Integer.valueOf(ttl));
980             uriParms.set(nv);
981         }
982     }
983 
984     /** Sets the value of the "transport" parameter. This parameter specifies
985      * which transport protocol to use for sending requests and responses to
986      * this entity. The following values are defined: "udp", "tcp", "sctp",
987      * "tls", but other values may be used also. This method is equivalent to
988      * setParameter("transport", transport). Transport parameter constants
989      * are defined in the {@link javax.sip.ListeningPoint}.
990      *
991      * @param transport - new value for the "transport" parameter
992      * @see javax.sip.ListeningPoint
993      */
setTransportParam(String transport)994     public void setTransportParam(String transport) throws ParseException {
995         if (transport == null)
996             throw new NullPointerException("null arg");
997         if (transport.compareToIgnoreCase("UDP") == 0
998             || transport.compareToIgnoreCase("TLS") == 0
999             || transport.compareToIgnoreCase("TCP") == 0
1000             || transport.compareToIgnoreCase("SCTP") == 0) {
1001             NameValue nv = new NameValue(TRANSPORT, transport.toLowerCase());
1002             uriParms.set(nv);
1003         } else
1004             throw new ParseException("bad transport " + transport, 0);
1005     }
1006 
1007     /** Returns the user part of this SipURI, or null if it is not set.
1008      *
1009      * @return  the user part of this SipURI
1010      */
getUserParam()1011     public String getUserParam() {
1012         return getParameter("user");
1013 
1014     }
1015 
1016     /** Returns whether the the <code>lr</code> parameter is set. This is
1017      * equivalent to hasParameter("lr"). This interface has no getLrParam as
1018      * RFC3261 does not specify any values for the "lr" paramater.
1019      *
1020      * @return true if the "lr" parameter is set, false otherwise.
1021      */
hasLrParam()1022     public boolean hasLrParam() {
1023         return uriParms.getNameValue("lr") != null;
1024     }
1025 
1026 
1027     /**
1028      * Returns whether the <code>gr</code> parameter is set.
1029      *
1030      * Not part on the interface since gruu is not part of the base RFC3261.
1031      */
hasGrParam()1032     public boolean hasGrParam() {
1033         return uriParms.getNameValue(GRUU) != null;
1034     }
1035 
1036     /**
1037      * Sets the <code>gr</code> parameter.
1038      *
1039      * Not part on the interface since gruu is not part of the base RFC3261.
1040      */
setGrParam(String value)1041     public void setGrParam(String value) {
1042             this.uriParms.set(GRUU, value); // JvB: fixed to not add duplicates
1043     }
1044 
1045     /**
1046      * Sets the <code>gr</code> parameter.
1047      *
1048      * Not part on the interface since gruu is not part of the base RFC3261.
1049      */
getGrParam()1050     public String getGrParam() {
1051             return (String) this.uriParms.getValue(GRUU);   // JvB: fixed to not add duplicates
1052     }
1053 
1054     /**
1055      *remove the +sip-instance value from the parameter list if it exists.
1056      */
1057 
1058 }
1059