Package org.apache.muse.ws.addressing

Source Code of org.apache.muse.ws.addressing.EndpointReference

/*=============================================================================*
*  Copyright 2006 The Apache Software Foundation
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*=============================================================================*/

package org.apache.muse.ws.addressing;

import java.net.URI;

import javax.xml.namespace.QName;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import org.apache.muse.util.messages.Messages;
import org.apache.muse.util.messages.MessagesFactory;
import org.apache.muse.util.xml.XmlSerializable;
import org.apache.muse.util.xml.XmlUtils;
import org.apache.muse.ws.addressing.soap.SoapFault;

/**
*
* EndpointReference is a complete implementation of the EndpointReferenceType
* type defined in WS-Addressing 1.0.
* <br><br>
* This class is implemented as a wrapper for an XML representation of an EPR,
* providing methods that allow users to get and set values with regular Java
* types rather than DOM types. It also provides a number of copy and conversion
* constructors for creating EPRs from various sources.
*
* @author Dan Jemiolo (danj)
*
*/

public class EndpointReference implements XmlSerializable
{
    //
    // Used to lookup all exception messages
    //
    private static Messages _MESSAGES = MessagesFactory.get(EndpointReference.class);
   
    private URI _address = null;
   
    //
    // pointer to the set of reference parameters - this node is added to
    // the EPR's XML tree when it has one or more children
    //
    private Element _parameters = null;
       
    //
    // The QName of the root element in the XML representation. The default
    // is wsa:EndpointReference, but sub-types will have a different QName.
    //
    private QName _rootName = null;
   
    //
    // The XML representation of the EPR
    //
    private Element _xml = null;

    /**
     *
     * This is a convenience constructor that creates a new EPR from the
     * given XML, making a deep copy of it in the process. It is equivalent
     * to calling the EndpointReference(Element, boolean) constructor with
     * the second parameter set to "true".
     *
     * @see #EndpointReference(Element, boolean)
     *
     */
    public EndpointReference(Element root)
        throws SoapFault
    {
        this(root, true);
    }
   
    /**
     *
     * Creates a new EPR from the given XML definition.
     *
     * @param root
     *        The XML definition of the EPR.
     *
     * @param makeDeepCopyOfXML
     *        True if you want the class to clone the given XML fragment
     *        so that it has an independent copy of the data. If a copy of
     *        the given XML is made, it will retain the same root element
     *        QName.
     *
     * @throws SoapFault
     *         <ul>
     *         <li>If the XML fragment is not valid according to the WS-A EPR
     *         type definition.</li>
     *         </ul>
     *
     */
    public EndpointReference(Element root, boolean makeDeepCopyOfXML)
        throws SoapFault
    {
        if (root == null)
            throw new NullPointerException(_MESSAGES.get("NullEPRElement"));
       
        //
        // option #1 - make our own copy of the XML sub-tree
        //
        if (makeDeepCopyOfXML)
            _xml = (Element)XmlUtils.EMPTY_DOC.importNode(root, true);
       
        //
        // option #2 - just use the existing fragment
        //
        else
            _xml = root;
        
        initializeFromXML();
    }
   
    /**
     *
     * This is a convenience constructor that is equivalent to calling the
     * EndpointReference(EndpointReference, QName) constructor with the
     * standard wsa:EndpointReference QName.
     *
     * @see #EndpointReference(EndpointReference, QName)
     * @see WsaConstants#EPR_QNAME
     *
     */
    public EndpointReference(EndpointReference copy)
    {
        this(copy, WsaConstants.EPR_QNAME);
    }
   
    /**
     *
     * A copy constructor for EPRs - creates a deep copy of the given EPR.
     * When serialized to XML, the given QName will be used as the name of
     * the root element (regardless of the root QName of the copied EPR).
     *
     * @param copy
     *        The EPR to copy (deep copy).
     *
     * @param typeName
     *        The QName of the root element when this EPR is serialized to XML.
     *
     */
    public EndpointReference(EndpointReference copy, QName typeName)
    {
        if (copy == null)
            throw new NullPointerException(_MESSAGES.get("NullCopyEPR"));
       
        if (typeName == null)
            throw new NullPointerException(_MESSAGES.get("NullEPRTypeQName"));
       
        //
        // create the root element - we can't just importNode because the
        // QName might be different
        //
        Document doc = XmlUtils.EMPTY_DOC;
        _xml = XmlUtils.createElement(doc, typeName);
       
        //
        // now copy all child elements...
        //
        NodeList children = copy.toXML().getChildNodes();
        int length = children.getLength();
       
        for (int n = 0; n < length; ++n)
        {
            Node next = doc.importNode(children.item(n), true);
            _xml.appendChild(next);
        }
       
        try
        {
            initializeFromXML();
        }
       
        catch (SoapFault error)
        {
            throw new RuntimeException(_MESSAGES.get("InvalidEPRCreated"), error);
        }
    }

    /**
     *
     * This is a convenience constructor that is the equivalent of calling
     * EndpointReference(URI, QName) constructor with the standard
     * wsa:EndpointReference QName.
     *
     * @see #EndpointReference(URI, QName)
     * @see WsaConstants#EPR_QNAME
     *
     */
    public EndpointReference(URI address)
    {
        this(address, WsaConstants.EPR_QNAME);
    }
   
    /**
     *
     * Creates a new EPR with the given wsa:Address URI; when the EPR is
     * serialized to XML, its root element will have the given QName. The
     * new EPR will have no reference parameters or properties elements.
     *
     * @param address
     *        The wsa:Address of the EPR.
     *
     * @param typeName
     *        The QName of the root element when the EPR is serialized to XML.
     *
     */
    public EndpointReference(URI address, QName typeName)
    {
        if (address == null)
            throw new NullPointerException(_MESSAGES.get("NullToAddress"));

        if (typeName == null)
            throw new NullPointerException(_MESSAGES.get("NullEPRTypeQName"));
       
        _address = address;
       
        Document doc = XmlUtils.EMPTY_DOC;       
        _xml = XmlUtils.createElement(doc, typeName);
       
        //
        // wsa:Address
        //
        Element addressNode =
            XmlUtils.createElement(doc, WsaConstants.ADDRESS_QNAME, address);
        _xml.appendChild(addressNode);
       
        //
        // create blank parameters
        //
        _parameters = XmlUtils.createElement(doc, WsaConstants.PARAMETERS_QNAME);
    }
   
    /**
     *
     * Adds the given Element to the collection of reference parameters. The
     * object will make a deep copy of the Element.
     *
     * @param parameter
     *
     */
    public void addParameter(Element parameter)
    {
        if (parameter == null)
            throw new NullPointerException(_MESSAGES.get("NullReferenceParameter"));
       
        //
        // if the ReferenceParameters was previously empty, we need to
        // append it to the EPR XML tree
        //
        if (!_parameters.hasChildNodes())
            _xml.appendChild(_parameters);
       
        //
        // copy the parameter element into the ReferenceParameters
        //
        Document doc = _xml.getOwnerDocument();
        parameter = (Element)doc.importNode(parameter, true);
        _parameters.appendChild(parameter);
    }
   
    /**
     *
     * This is a convenience method that calls addParameter(QName, Object)
     * with a null parameter value.
     *
     * @see #addParameter(QName, Object)
     *
     */
    public void addParameter(QName qname)
    {
        addParameter(qname, null);
    }
   
    /**
     *
     * Creates a new reference parameter with the given name and value.
     *
     * @param qname
     *        The name of the reference parameter's XML element.
     *
     * @param value
     *        The parameter value (can be null).
     *
     */
    public void addParameter(QName qname, Object value)
    {
        if (qname == null)
            throw new NullPointerException(_MESSAGES.get("NullParameterQName"));
       
        //
        // translate to XML, add it to the internal tree
        //
        Element parameter = XmlUtils.createElement(qname, value);
        addParameter(parameter);
    }
   
    /**
     *
     * @return True, if:
     *         <ul>
     *         <li>The argument is not null.</li>
     *         <li>The wsa:Address values match.</li>
     *         <li>The wsa:PortType values match (if present).</li>
     *         <li>The wsa:ServiceName and PortName values match (if
     *         present).</li>
     *         </ul>
     *         The equality test does <b>not</b> compare the root element
     *         QNames used when serializing the EPRs to XML. It also does
     *         <b>not</b> compare any reference parameters or properties.
     *
     */
    public boolean equals(Object obj)
    {
        if (obj == null)
            return false;

        EndpointReference that = (EndpointReference)obj;
       
        //
        // compare wsa:Address - EXCLUDING the host. this allows us
        // to compare EPRs that have equivalent IP addresses and
        // machine names/localhost
        //
        String thisPath = getAddress().getPath();
        String thatPath = that.getAddress().getPath();
       
        if (!thisPath.equals(thatPath))
            return false;
       
        //
        // test params that the user wants to include in equality check
        //

        Element[] values1 = getParameters();
        Element[] values2 = that.getParameters();
       
        if (values1.length != values2.length)
            return false;
       
        for (int n = 0; n < values1.length; ++n)
            if (!XmlUtils.equals(values1[n], values2[n]))
                return false;
       
        //
        // if we made it this far, all values were equal
        //
        return true;
    }
   
    /**
     *
     * @return The wsa:Address value.
     *
     */
    public URI getAddress()
    {
        return _address;
    }
   
    /**
     *
     * @return The current number of elements in the wsa:ReferenceParameters
     *         section.
     *
     */
    public int getNumberOfParameters()
    {
        return _parameters.getChildNodes().getLength();
    }
   
    /**
     *
     * @param qname
     *        The name of the reference parameter to look up.
     *
     * @return The first instance of the given parameter, or null if no
     *         instances exist.
     *
     */
    public Element getParameter(QName qname)
    {
        return getParameter(qname, 0);
    }
   
    /**
     *
     * @param qname
     *        The name of the reference parameter to look up.
     *
     * @return The n-th instance of the given parameter, or null if no
     *         instances exist.
     *
     */
    public Element getParameter(QName qname, int index)
    {
        return XmlUtils.getElement(_parameters, qname, index);
    }
   
    /**
     *
     * @return All reference parameter instances (there is no guarantee as
     *         to the order of the elements). If there are no reference
     *         parameters, the array is empty.
     *
     */
    public Element[] getParameters()
    {
        return XmlUtils.getAllElements(_parameters);
    }
   
    /**
    *
    * @return All reference parameter instances with the given name. If
    *         there are no instances with that name, the array is empty.
    *
    */
    public Element[] getParameters(QName qname)
    {
        return XmlUtils.getElements(_parameters, qname);
    }
   
    /**
     *
     * @param qname
     *        The name of the reference parameter to look up.
     *
     * @return The text value of the first instance of the parameter, or
     *         null if there was none.
     *
     */
    public String getParameterString(QName qname)
    {
        return getParameterString(qname, 0);
    }
   
    /**
     *
     * @param qname
     *        The name of the reference parameter to look up.
     *
     *
     * @return The text value of the n-th instance of the parameter, or
     *         null if there was none.
     *
     */
    public String getParameterString(QName qname, int index)
    {
        Element xml = getParameter(qname, index);
       
        if (xml == null)
            return null;
       
        return XmlUtils.extractText(xml);
    }
   
    /**
     *
     * @return The QName that is used for the root element when serializing
     *         this EPR to XML. The default value is wsa:EndpointReference,
     *         but this is not required.
     *
     */
    public QName getRootTypeName()
    {
        return _rootName;
    }
   
    /**
     *
     * This method has been properly overridden to account for the change
     * to equals(Object). Overriding equals(Object) and not hashCode() can
     * cause incorrect behavior when storing objects in associative data
     * structures.
     *
     */
    public int hashCode()
    {
        String address = getAddress().getPath();
       
        Element[] parameters = getParameters();
        int paramHashCode = 0;
       
        for (int n = 0; n < parameters.length; ++n)
            paramHashCode += XmlUtils.getHashCode(parameters[n]);
               
        return address.hashCode() + paramHashCode;
    }

    /**
     *
     * Parses the internal XML representation of the EPR to cache read-only
     * values and set up references to other frequently-used data structures.
     *
     * @throws SoapFault
     *         <ul>
     *         <li>If the XML is not valid according to the WS-A EPR schema.</li>
     *         </ul>
     *
     */
    private void initializeFromXML()
        throws SoapFault
    {
        //
        // save the QName of the EPR type (could be a sub-type)
        //
        _rootName = XmlUtils.getElementQName(_xml);

        String uri = XmlUtils.getElementText(_xml, WsaConstants.ADDRESS_QNAME);
       
        try
        {
            _address = new URI(uri);
        }
           
        catch (Exception error)
        {
            Object[] filler = { uri };
            String message = _MESSAGES.get("InvalidAddressURI", filler);
            throw new SoapFault(message, error);
        }
       
        Document doc = _xml.getOwnerDocument();
       
        //
        // save references to the parameters sub-tree
        //       
        _parameters = XmlUtils.getElement(_xml, WsaConstants.PARAMETERS_QNAME);
       
        if (_parameters == null)
            _parameters = XmlUtils.createElement(doc, WsaConstants.PARAMETERS_QNAME);
    }
   
    /**
     *
     * This is a convenience method that removes the first instance of a
     * reference parameter with the given name. It is equivalent to calling
     * removeParameter(QName, 0).
     *
     * @see #removeParameter(QName, int)
     *
     */
    public void removeParameter(QName qname)
    {
        removeParameter(qname, 0);
    }
   
    /**
     *
     * Removes the n-th instance of the parameter with the given name. If
     * the parameter was the last one in the reference parameters collection,
     * the wsa:ReferenceParameters section will no longer be serialized into
     * the EPR's XML.
     *
     * @param qname
     *        The name of the parameter instance to delete.
     *
     * @param index
     *        The instance of the parameter to delete.
     *
     */
    public void removeParameter(QName qname, int index)
    {
        Node match = XmlUtils.getElement(_parameters, qname, index);
       
        if (match == null)
        {
            Object[] filler = { qname };
            String message = _MESSAGES.get("NoParameterFound", filler);
            throw new IllegalArgumentException(message);
        }
       
        _parameters.removeChild(match);
       
        //
        // if the wsa:ReferenceParameters is empty, we don't want it
        // in the EPR XML
        //
        if (!_parameters.hasChildNodes())
            _xml.removeChild(_parameters);
    }
   
    /**
     *
     * Removes all instances of the parameter with the given name. If
     * the parameters were the last in the reference parameters collection,
     * the wsa:ReferenceParameters section will no longer be serialized into
     * the EPR's XML.
     *
     * @param qname
     *        The name of the parameter(s) to delete.
     *
     */
    public void removeParameters(QName qname)
    {
        Element[] matches = XmlUtils.getElements(_parameters, qname);
       
        if (matches.length == 0)
        {
            Object[] filler = { qname };
            String message = _MESSAGES.get("NoParametersFound", filler);
            throw new IllegalArgumentException(message);
        }
       
        for (int n = 0; n < matches.length; ++n)
            _parameters.removeChild(matches[n]);
       
        //
        // if the wsa:ReferenceParameters is empty, we don't want it
        // in the EPR XML
        //
        if (!_parameters.hasChildNodes())
            _xml.removeChild(_parameters);
    }
   
    /**
     *
     * @param address
     *        The wsa:Address of the EPR (cannot be null).
     *
     */
    public void setAddress(URI address)
    {
        if (address == null)
            throw new NullPointerException(_MESSAGES.get("NullToAddress"));
       
        _address = address;
        XmlUtils.setElement(_xml, WsaConstants.ADDRESS_QNAME, _address);
    }
   
    /**
     *
     * @return A string with the XML representation of the EPR.
     *
     */
    public String toString()
    {
        return XmlUtils.toString(toXML(), false);
    }
   
    /**
     *
     * @return The complete XML representation of the EPR. This is the actual
     *         underlying data structure of the EPR, so modifications should
     *         be made judiciously (if at all).
     *
     * @see #toXML(Document)
     *
     */
    public Element toXML()
    {
        return _xml;
    }
   
    /**
     *
     * @return A copy of the EPR'S XML representation, created using the
     *         given Document.
     *
     */
    public Element toXML(Document doc)
    {
        return (Element)doc.importNode(_xml, true);
    }
}
TOP

Related Classes of org.apache.muse.ws.addressing.EndpointReference

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.