Package com.ericsson.ssa.sip

Source Code of com.ericsson.ssa.sip.TelURLImpl

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) Ericsson AB, 2004-2008. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.ericsson.ssa.sip;

import com.ericsson.ssa.sip.dns.EnumUtil;

import com.sun.enterprise.util.LocalStringManagerImpl;

import java.io.Serializable;

import java.util.HashMap;
import java.util.Iterator;

import javax.servlet.sip.ServletParseException;
import javax.servlet.sip.TelURL;


/**
* Implementation of the TelURL.
*
*
* @author ekrigro
* @since 2005-maj-04
* @reviewed qmigkra 2007-jan-17
*
*/
public class TelURLImpl extends URIImpl implements TelURL, Serializable {
    private static final long serialVersionUID = 3690194326332258097L;
    static String NO_NUMBER = "The parsed TEL URL did not cantain any number";
    static String DUPLICATE_PARAM = "The parsed TEL URL has two parameter with the same name : ";
    static String PHONE_CTX_MISSING = "The parsed TEL URL doesn't contain the mandatory parameter phone-context";
    public static String PHONE_CONTEXT = "phone-context";
    protected static final LocalStringManagerImpl localStrings = new LocalStringManagerImpl(SipSessionImplBase.class);
    private boolean _global = false;
    private String _number = null;

    private TelURLImpl() {
    }

    public TelURLImpl(String uri, int offset) throws ServletParseException {
        parse(uri, offset);
    }

    public String getPhoneNumber() {
        return _number;
    }

    public void setPhoneNumber(String number) {
        verify();
        ParseResult pr = parsePhoneNumber(number, 0);
        validateAndSetParsetResult(pr);
    }

    public void setPhoneNumber(String number, String phoneContext) {
        verify();
        ParseResult pr = parsePhoneNumber(number, 0);

        if (pr.global) {
            String msg = localStrings.getLocalString("number_cannotbe_global",
                    "The Telephone number cannot be global.");
            throw new IllegalArgumentException(msg);
        }

        pr.phoneContext = phoneContext;
        validateAndSetParsetResult(pr);
    }

    public String getPhoneContext() {
        if (_global) {
            return null;
        }

        return getParameter(PHONE_CONTEXT);
    }

    public boolean isGlobal() {
        return _global;
    }

    public TelURLImpl clone() {
        TelURLImpl uri = new TelURLImpl();
        uri._global = _global;
        uri._number = _number;
        uri._parameters = (ParameterByteMap) _parameters.clone();

        return uri;
    }

    /**
     * The comparison is done according to RFC 3966, chapter 4 "URI Comparisons"
     *
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals(Object o) {
        if (o == null) {
            return false;
        }

        TelURL uri;

        try {
            uri = (TelURL) o;
        } catch (Exception e) {
            return false;
        }

        if (_global != uri.isGlobal()) {
            return false;
        }

        // Remove visual separators
        String tel1 = EnumUtil.getAUSValue(_number);
        String tel2 = EnumUtil.getAUSValue(uri.getPhoneNumber());

        // and compare
        if (!tel1.equals(tel2)) {
            return false;
        }

        if (!_global) {
            // context = ";phone-context=" descriptor
            // descriptor = domainname / global-number-digits
            // global-number-digits = "+" *phonedigit DIGIT *phonedigit
            // local-number-digits =
            // *phonedigit-hex (HEXDIG / "*" / "#")*phonedigit-hex
            // domainname = *( domainlabel "." ) toplabel [ "." ]
            // domainlabel = alphanum
            // / alphanum *( alphanum / "-" ) alphanum
            // toplabel = ALPHA / ALPHA *( alphanum / "-" ) alphanum

            // Compare the phone-context
            String phoneContext1 = getParameter(PHONE_CONTEXT);
            String phoneContext2 = uri.getParameter(PHONE_CONTEXT);

            // If it is a global number
            if (phoneContext1.startsWith("+") && phoneContext2.startsWith("+")) {
                phoneContext1 = EnumUtil.getAUSValue(phoneContext1);
                phoneContext2 = EnumUtil.getAUSValue(phoneContext2);

                if (!phoneContext1.equals(phoneContext2)) {
                    return false;
                }
            } else { // else it is a domain

                if (!phoneContext1.equals(phoneContext2)) {
                    return false;
                }
            }
        }

        HashMap<String, String> map1 = new HashMap<String, String>(8);
        Iterator<String> thisParameters = _parameters.getKeys();

        while (thisParameters.hasNext()) {
            String parameter = (String) thisParameters.next();
            String value = (String) getParameter(parameter);

            // Do not compare phone-context
            if (!parameter.equals(PHONE_CONTEXT)) {
                map1.put(parameter, value);
            }
        }

        HashMap<String, String> map2 = new HashMap<String, String>(8);
        Iterator<String> uriParameters = uri.getParameterNames();

        while (uriParameters.hasNext()) {
            String parameter = (String) uriParameters.next();
            String value = (String) uri.getParameter(parameter);

            // Do not compare phone-context
            if (!parameter.equals(PHONE_CONTEXT)) {
                map2.put(parameter, value);
            }
        }

        if (!map1.equals(map2)) {
            return false;
        }

        return true;

        //        if (!_global) {
        //            ParameterByteMap map1 = (ParameterByteMap) _parameters.clone();
        //            ParameterByteMap map2 = (ParameterByteMap) uri._parameters.clone();
        //
        //            // context = ";phone-context=" descriptor
        //            // descriptor = domainname / global-number-digits
        //            // global-number-digits = "+" *phonedigit DIGIT *phonedigit
        //            // local-number-digits =
        //            // *phonedigit-hex (HEXDIG / "*" / "#")*phonedigit-hex
        //            // domainname = *( domainlabel "." ) toplabel [ "." ]
        //            // domainlabel = alphanum
        //            // / alphanum *( alphanum / "-" ) alphanum
        //            // toplabel = ALPHA / ALPHA *( alphanum / "-" ) alphanum
        //            String phoneContext1 = map1.get(PHONE_CONTEXT);
        //            map1.remove(PHONE_CONTEXT);
        //
        //            String phoneContext2 = map2.get(PHONE_CONTEXT);
        //            map2.remove(PHONE_CONTEXT);
        //
        //            // If it is a global number
        //            if (phoneContext1.startsWith("+") && phoneContext2.startsWith("+")) {
        //                phoneContext1 = EnumUtil.getAUSValue(phoneContext1);
        //                phoneContext2 = EnumUtil.getAUSValue(phoneContext2);
        //
        //                if (!phoneContext1.equals(phoneContext2)) {
        //                    return false;
        //                }
        //            } else { // else it is a domain
        //
        //                if (!phoneContext1.equals(phoneContext2)) {
        //                    return false;
        //                }
        //            }
        //
        //            if (!map1.equals(map2)) {
        //                return false;
        //            }
        //        } else {
        //            if (!_parameters.equals(uri._parameters)) {
        //                return false;
        //            }
        //        }
        //
        //        return true;
    }

    private void validateCharacter(char c, ParseResult pr) {
        char[] validChars = { '-', '.', '(', ')' };
        char[] validHexChars = { 'A', 'B', 'C', 'D', 'E', 'F' };
        char[] validLocalChars = { '*', '#' };

        if (Character.isDigit(c)) {
            pr.digitFound = true;

            return;
        }

        for (char valid : validChars) {
            if (valid == c) {
                return;
            }
        }

        if (!pr.global) {
            for (char valid : validHexChars) {
                if (valid == c) {
                    pr.digitFound = true;

                    return;
                }
            }

            for (char valid : validLocalChars) {
                if (valid == c) {
                    return;
                }
            }
        }

        String msg = localStrings.getLocalString("number_contains_invalidchar",
                "The Telephone number contains and invalid character :" + c,
                new Object[] { "" + c });
        throw new IllegalArgumentException(msg);
    }

    private ParseResult parsePhoneNumber(String str, int offset) {
        int mark = offset;
        int current = offset;
        int end = str.length();
        char c = 0;
        ParseResult pr = new ParseResult();

        if (current < end) {
            c = str.charAt(current++);
        }

        if (c == '+') {
            pr.global = true;
            mark = current;

            if (current < end) {
                c = str.charAt(current++);
                validateCharacter(c, pr);
            }
        }

        //int restCurrent = -1;
        //int restEnd = -1;
        while (current < end) {
            if (c == ';') {
                //restCurrent = current;
                //restEnd = end;
                pr.offset = current;
                current--;

                break;
            } else {
                validateCharacter(c, pr);
                c = str.charAt(current++);
            }
        }

        pr.phoneNumber = str.substring(mark, current);

        return pr;
    }

    private void parseParameters(String str, ParseResult pr)
        throws ServletParseException {
        int restCurrent = pr.offset;
        int restEnd = str.length();
        char c = 0;

        if (restCurrent != -1) {
            String pname = null;
            StringBuilder temp = new StringBuilder();
            StringBuilder pvalue = new StringBuilder();

            while (restCurrent < restEnd) {
                c = str.charAt(restCurrent++);

                if (c == '=') {
                    pname = temp.toString();
                } else if (c == ';') {
                    setParameter(pname, pvalue, pr);
                    pname = null;
                    temp = new StringBuilder();
                    pvalue = new StringBuilder();
                } else if (pname == null) {
                    temp.append(c);
                } else {
                    pvalue.append(c);
                }
            }

            if (pname != null) {
                setParameter(pname, pvalue, pr);
            }
        }
    }

    private void setParameter(String pname, StringBuilder pvalue, ParseResult pr)
        throws ServletParseException {
        if (_parameters.get(pname) != null) {
            throw new ServletParseException(DUPLICATE_PARAM + pname);
        }

        if (!pr.global && pname.equals(PHONE_CONTEXT)) {
            pr.phoneContext = pvalue.toString();
        } else {
            _parameters.put(pname, pvalue.toString());
        }
    }

    private void validateAndSetParsetResult(ParseResult pr) {
        if ((pr.phoneNumber == null) || (pr.phoneNumber.length() == 0)) {
            String msg = localStrings.getLocalString("number_cannotbe_null",
                    "The Telephone number cannot be null.");
            throw new IllegalArgumentException(msg);
        }

        //Do we need this strictness checking?
        if (!pr.digitFound) {
            String msg = localStrings.getLocalString("number_shouldcontain_onedigit",
                    "The Telephone number should contain atleast one digit.");
            throw new IllegalArgumentException(msg);
        }

        if (!pr.global && (pr.phoneContext == null)) {
            String msg = localStrings.getLocalString("context_cantbe_null",
                    "For a local number, phone context cannot be null.");
            throw new IllegalArgumentException(msg);
        }

        _number = pr.phoneNumber;
        _global = pr.global;

        if (!_global) {
            setParameter(PHONE_CONTEXT, pr.phoneContext);
        }
    }

    private void parse(String str, int offset) throws ServletParseException {
        ParseResult pr = parsePhoneNumber(str, offset);
        parseParameters(str, pr);

        try {
            validateAndSetParsetResult(pr);
        } catch (IllegalArgumentException iae) {
            ServletParseException spe = new ServletParseException(iae.getMessage());
            throw ServletParseException.class.cast(spe.initCause(iae));
        }
    }

    public String getScheme() {
        return SipFactoryImpl.TEL_URI_PROTOCOL;
    }

    public boolean isSipURI() {
        return false;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder("tel:");

        addBody(sb);

        return sb.toString();
    }

    private void addBody(StringBuilder sb) {
        if (_global) {
            sb.append('+');
        }

        sb.append(_number);

        if (_parameters != null) {
            Iterator<String> i = _parameters.getKeys();

            while (i.hasNext()) {
                String pname = i.next();
                sb.append(';');
                sb.append(pname);
                sb.append('=');
                sb.append(_parameters.get(pname));
            }
        }
    }

    /**
     * Gets the string representation of this Tel-URL as it should be specified in a
     * SIP-URI user.
     * @return the string representation of this Tel-URL as it should be specified in a
     * SIP-URI user
     */
    public String getAsSipUriUser() {
        StringBuilder sb = new StringBuilder();

        addBody(sb);

        return sb.toString();
    }

    class ParseResult {
        int offset = -1;
        boolean global;
        String phoneNumber;
        String phoneContext;
        boolean digitFound;
    }
}
TOP

Related Classes of com.ericsson.ssa.sip.TelURLImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.