org.mobicents.servlet.sip.address.AddressImpl Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
* Copyright 2011, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.mobicents.servlet.sip.address;
import gov.nist.javax.sip.header.ParametersExt;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.sip.Address;
import javax.servlet.sip.Parameterable;
import javax.servlet.sip.URI;
import javax.sip.address.SipURI;
import javax.sip.header.ContactHeader;
import javax.sip.header.HeaderAddress;
import javax.sip.header.Parameters;
import org.mobicents.servlet.sip.message.SipFactoryImpl;
import org.mobicents.servlet.sip.message.SipServletMessageImpl;
/**
* Implementation of Servlet Address specification.
*
* @author mranga
* @author bartek
*
*/
public class AddressImpl extends ParameterableImpl implements Address {
private static final long serialVersionUID = 1L;
private static final String Q_PARAM_NAME = "q";
private static final String EXPIRES_PARAM_NAME = "expires";
private static final String PARAM_SEPARATOR = ";";
private static final String PARAM_NAME_VALUE_SEPARATOR = "=";
private javax.sip.address.Address address;
public enum ModifiableRule {
NotModifiable, ProxyRecordRouteNotModifiable, ContactSystem, ContactNotSystem, Modifiable, From, To, Via;
}
public javax.sip.address.Address getAddress() {
return address;
}
public AddressImpl() {}
@SuppressWarnings("unchecked")
public AddressImpl (javax.sip.address.Address address, Map parameters, ModifiableRule isModifiable) {
super();
super.isModifiable = isModifiable;
this.address = address;
if(parameters != null) {
this.parameters = parameters;
}
// this isn't right : we shouldn't copy the uri params as address params
// See Issue 732 : http://code.google.com/p/mobicents/issues/detail?id=732
// duplicate parameters when using sipFactory.createAddress(uri) with a uri having parameters
// if(this.address.getURI() instanceof Parameters) {
// Parameters uri = (Parameters) this.address.getURI();
// Iterator parameterNames = uri.getParameterNames();
// while (parameterNames.hasNext()) {
// String parameterName = (String) parameterNames.next();
// String value = uri.getParameter(parameterName);
// this.parameters.put(parameterName.toLowerCase(), value);
// }
// }
}
/**
* Creates instance of Address object. This object is valid representation
* of SIP AddressHeader, like To, From, Contact. Input to create this object
* HAS to be string that conforms to sip(s) uri schema. Methods exposed by
* this object act on header part of address. Parameter methods modify
* header parameters, not uri parameters.
*
* @param addressString -
* string representing header, it has to conform to rfc 3261
* sip(s) uri scheme, see chapter 19 and specification of To/From
* header.
* Passed values must look like followin:
*
* - <sip:[email protected]>
* - sip:[email protected]
* - <sip:[email protected];somePName=somePValue;someP2Name=V2>headerParam1=Value1;headerParam2=V2
* - <sip:[email protected]>headerParam1=Value1;headerParam2=V2
* - "Kazik Staszewski"
* <sip:[email protected];somePName=somePValue;someP2Name=V2>headerParam1=Value1;headerParam2=V2
* - "Kazik Staszewski"
* <sip:[email protected]>headerParam1=Value1;headerParam2=V2
*
*
* @throws ParseException
*/
public AddressImpl(HeaderAddress header, ModifiableRule modifiable) throws ParseException {
if(header instanceof Parameters) {
super.header = (Parameters) header;
}
this.address = header.getAddress();
if(header instanceof Parameters) {
super.parameters = getParameters((Parameters)header);
} else {
super.parameters = new ConcurrentHashMap();
}
super.isModifiable = modifiable;
}
/*
* (non-Javadoc)
* @see javax.servlet.sip.Address#getDisplayName()
*/
public String getDisplayName() {
return address.getDisplayName();
}
/*
* (non-Javadoc)
* @see javax.servlet.sip.Address#getExpires()
*/
public int getExpires() {
String expires = this.getParameter(EXPIRES_PARAM_NAME);
if(expires != null) { // This is how the TCK expects to parse it. See AddressingServlet in TCK spec tests.
return Integer.parseInt(expires);
} else { // I think this is not needed.
return ((SipURI)address.getURI()).getParameter(EXPIRES_PARAM_NAME) == null ? -1 :
Integer.parseInt(((SipURI)address.getURI()).getParameter(EXPIRES_PARAM_NAME));
}
}
/*
* (non-Javadoc)
* @see javax.servlet.sip.Address#getQ()
*/
public float getQ() {
String q = this.getParameter(Q_PARAM_NAME);
if(q != null) { // This is how the TCK expects to parse it. See AddressingServlet in TCK spec tests.
return Float.parseFloat(q);
} else { // I think this is not needed.
return ((SipURI)address.getURI()).getParameter(Q_PARAM_NAME) == null ? (float) -1.0 :
Float.parseFloat(((SipURI)address.getURI()).getParameter(Q_PARAM_NAME));
}
}
/*
* (non-Javadoc)
* @see javax.servlet.sip.Address#getURI()
*/
public URI getURI() {
final javax.sip.address.URI localUri = getAddress().getURI();
if (localUri instanceof javax.sip.address.SipURI)
return new SipURIImpl((javax.sip.address.SipURI) localUri, isModifiable);
else if (localUri instanceof javax.sip.address.TelURL)
return new TelURLImpl((javax.sip.address.TelURL) localUri);
else if (localUri instanceof javax.sip.address.URI) {
URI uri = new GenericURIImpl((javax.sip.address.URI) localUri);
// setting the value to make sure jain sip runs scheme validation on it
((Parameterable)uri).setValue(localUri.toString());
return uri;
}
else
throw new IllegalArgumentException("unsupported operation - unknown scheme");
}
/*
* (non-Javadoc)
* @see javax.servlet.sip.Address#isWildcard()
*/
public boolean isWildcard() {
return getAddress().isWildcard();
}
/*
* (non-Javadoc)
* @see javax.servlet.sip.Address#setDisplayName(java.lang.String)
*/
public void setDisplayName(String name) {
if(SipServletMessageImpl.isSystemHeader(isModifiable)) {
throw new IllegalStateException("this Address is used in a context where it cannot be modified");
}
try {
getAddress().setDisplayName(name);
} catch (ParseException e) {
throw new IllegalArgumentException("illegal name ", e);
}
}
/*
* (non-Javadoc)
* @see javax.servlet.sip.Address#setExpires(int)
*/
public void setExpires(int seconds) throws IllegalArgumentException {
javax.sip.address.URI uri = this.getAddress().getURI();
if (uri instanceof SipURI) {
/*
SipURI sipUri = (SipURI) uri;
try {
sipUri.setParameter(EXPIRES_PARAM_NAME, Integer.toString(seconds));
} catch (ParseException e) {
throw new IllegalArgumentException("Problem setting parameter",
e);
}*/
if(seconds == -1) {
this.removeParameter(EXPIRES_PARAM_NAME);
return;
}
this.setParameter(EXPIRES_PARAM_NAME, Integer.toString(seconds));
} else {
throw new IllegalArgumentException(
"Can only set parameter for Sip URI");
}
}
/*
* (non-Javadoc)
* @see javax.servlet.sip.Address#setQ(float)
*/
public void setQ(float q) {
if(q == -1.0) {
this.removeParameter(Q_PARAM_NAME);
return;
}
if(q > 1.0 || q < 0) {
throw new IllegalArgumentException("the new qvalue isn't between 0.0 and 1.0 (inclusive) and isn't -1.0.");
}
this.setParameter(Q_PARAM_NAME, Float.toString(q));
/*
try {
Parameters uri = (Parameters) this.address.getURI();
uri.setParameter(Q_PARAM_NAME, Float.toString(q));
} catch (ParseException ex) {
throw new IllegalArgumentException("Bad parameter", ex);
}*/
}
/*
* (non-Javadoc)
* @see javax.servlet.sip.Address#setURI(javax.servlet.sip.URI)
*/
public void setURI(URI uri) {
if(SipServletMessageImpl.isSystemHeader(isModifiable)) {
throw new IllegalStateException("this Address is used in a context where it cannot be modified");
}
this.getAddress().setURI(((URIImpl) uri).uri);
}
public Object clone() {
AddressImpl retval = new AddressImpl();
retval.address = (javax.sip.address.Address) address.clone();
retval.parameters = ParameterableHeaderImpl.cloneParameters(this.parameters);
return retval;
}
public String toString() {
// Returns the value of this address as a String. The resulting string
// must be a valid value of a SIP From or To header.
// To/From are parametrable.
StringBuffer retval = new StringBuffer();
retval.append(address.toString());
//excluding the parameters already present in the address uri
if ( parameters!= null) {
for(Map.Entry entry : parameters.entrySet()) {
if((!(address.getURI() instanceof Parameters)) || ((Parameters)address.getURI()).getParameter(entry.getKey()) == null) {
String value = entry.getValue();
if(value != null && value.length() > 0) {
retval.append(PARAM_SEPARATOR).append(entry.getKey()).append(PARAM_NAME_VALUE_SEPARATOR).append(value);
} else {
retval.append(PARAM_SEPARATOR).append(entry.getKey());
}
}
}
}
return retval.toString();
}
/*
* (non-Javadoc)
* @see javax.servlet.sip.Parameterable#getValue()
*/
public String getValue() {
return toString();
}
/*
* (non-Javadoc)
* @see javax.servlet.sip.Parameterable#setValue(java.lang.String)
*/
public void setValue(String value) {
try {
ContactHeader contactHeader = (ContactHeader) SipFactoryImpl.headerFactory.createHeader(
ContactHeader.NAME, value);
this.address = SipFactoryImpl.addressFactory.createAddress(value);
this.parameters = getParameters(((Parameters) contactHeader));
} catch (Exception ex) {
throw new IllegalArgumentException("Illegal argument", ex);
}
}
public void setAddress(javax.sip.address.Address address) {
this.address = address;
}
@Override
public void setParameter(String name, String value) {
super.setParameter(name, value);
/*
if(this.address.getURI() instanceof Parameters) {
Parameters uri = (Parameters) this.address.getURI();
try {
uri.setParameter(name, value);
} catch (ParseException e) {
throw new IllegalArgumentException("Problem setting parameter",e);
}
}*/
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((address == null) ? 0 : address.hashCode());
result = prime * result + ((parameters == null) ? 0 : parameters.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final AddressImpl other = (AddressImpl) obj;
if (address.getURI() == null) {
if (other.address.getURI() != null)
return false;
} else if (!address.getURI().equals(other.address.getURI())) {
return false;
}
if (parameters == null) {
if (other.parameters != null)
return false;
} else {
for (Iterator it = parameters.keySet().iterator(); it.hasNext();) {
String pname = it.next();
String p1 = parameters.get(pname);
String p2 = other.parameters.get(pname);
// those present in both must match (case-insensitive)
if (p1!=null && p2!=null) {
if(Q_PARAM_NAME.equalsIgnoreCase(pname)) {
// https://github.com/RestComm/sip-servlets/issues/123
float p1Float = Float.valueOf(p1);
float p2Float = Float.valueOf(p2);
if(p1Float != p2Float) {
return false;
}
} else if(!RFC2396UrlDecoder.decode(p1).equalsIgnoreCase(RFC2396UrlDecoder.decode(p2))) {
return false;
}
}
}
}
return true;
}
public static final Map getParameters(Parameters headerParams) {
Map params = new HashMap();
Iterator parameterNames = headerParams.getParameterNames();
while (parameterNames.hasNext()) {
String name = (String) parameterNames.next();
String value = null;
// Fix for Issue 1477 http://code.google.com/p/mobicents/issues/detail?id=1477
// Address parameters become un-quoted after coping from address
if(headerParams instanceof ParametersExt) {
value = ((ParametersExt)headerParams).getParameter(name, false);
} else {
value = headerParams.getParameter(name);
}
params.put(name, value);
}
return params;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy