All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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: * * * @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