You are viewing a plain text version of this content. The canonical link for it is here.
Posted to muse-commits@ws.apache.org by da...@apache.org on 2006/06/12 18:04:44 UTC
svn commit: r413691 [1/2] - in
/webservices/muse/trunk/modules/muse-wsa-soap: ./ specs/
src/org/apache/muse/ws/addressing/ src/org/apache/muse/ws/addressing/soap/
Author: danj
Date: Mon Jun 12 09:04:42 2006
New Revision: 413691
URL: http://svn.apache.org/viewvc?rev=413691&view=rev
Log:
Initial check-in of IBM-donated code for Muse 2.0 - with
support for Axis2 (re-try after failure due to problem
with email to muse-commits).
Currently, the modules that are not implementations of the
WS-* specs - core, utils, WS-A/SOAP, etc. - have working
Maven 2.0 build files. Right now they simply compile and
write to the user's local $module/build directory. I have
not determined how to get Maven to skip this intermediary
copy and just put the jars in the user's local repository.
I currently use a script to build each module's POM file,
but as I learn more about Maven I will hopefully find a way
to aggregate POM files into one larger project. If not, I
will provide a simple Ant script.
I'm not sure where the design doc should go, and don't
want to mess with the web site yet, so please look at the
design-doc.zip that was uploaded to JIRA along with the
other IBM contributions until I determine the proper place.
Added:
webservices/muse/trunk/modules/muse-wsa-soap/pom.xml
webservices/muse/trunk/modules/muse-wsa-soap/specs/SOAP-Envelope-1_2.xsd
webservices/muse/trunk/modules/muse-wsa-soap/specs/WS-Addressing-2005_08.xsd
webservices/muse/trunk/modules/muse-wsa-soap/specs/XML-Namespace-1998.xsd
webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/EndpointReference.java
webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/MessageHeaders.java
webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/Messages.properties
webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/WsaConstants.java
webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/Messages.properties
webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/SimpleSoapClient.java
webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/SoapClient.java
webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/SoapConstants.java
webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/SoapFault.java
webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/SoapMonitor.java
webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/SoapUtils.java
Added: webservices/muse/trunk/modules/muse-wsa-soap/pom.xml
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsa-soap/pom.xml?rev=413691&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsa-soap/pom.xml (added)
+++ webservices/muse/trunk/modules/muse-wsa-soap/pom.xml Mon Jun 12 09:04:42 2006
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>muse</groupId>
+ <artifactId>muse-wsa-soap</artifactId>
+ <packaging>jar</packaging>
+ <version>2.0-SNAPSHOT</version>
+ <name>Apache Muse - WS-Addressing and SOAP APIs</name>
+ <url>http://ws.apache.org/muse</url>
+ <dependencies>
+ <dependency>
+ <groupId>muse</groupId>
+ <artifactId>muse-util</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>muse</groupId>
+ <artifactId>muse-util-qname</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>muse</groupId>
+ <artifactId>muse-util-xml</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <sourceDirectory>src</sourceDirectory>
+ <outputDirectory>build/classes</outputDirectory>
+ <directory>build/jars</directory>
+ </build>
+</project>
Added: webservices/muse/trunk/modules/muse-wsa-soap/specs/SOAP-Envelope-1_2.xsd
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsa-soap/specs/SOAP-Envelope-1_2.xsd?rev=413691&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsa-soap/specs/SOAP-Envelope-1_2.xsd (added)
+++ webservices/muse/trunk/modules/muse-wsa-soap/specs/SOAP-Envelope-1_2.xsd Mon Jun 12 09:04:42 2006
@@ -0,0 +1,160 @@
+<?xml version="1.0"?>
+
+<!-- Schema defined in the SOAP Version 1.2 Part 1 specification
+ Proposed Recommendation:
+ http://www.w3.org/TR/2003/PR-soap12-part1-20030507/
+ $Id: SOAP-Envelope-1_2.xsd,v 1.1 2006/05/07 18:45:32 danj Exp $
+
+ Copyright (C)2003 W3C(R) (MIT, ERCIM, Keio), All Rights Reserved.
+ W3C viability, trademark, document use and software licensing rules
+ apply.
+ http://www.w3.org/Consortium/Legal/
+
+ This document is governed by the W3C Software License [1] as
+ described in the FAQ [2].
+
+ [1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
+ [2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
+-->
+
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:tns="http://www.w3.org/2003/05/soap-envelope"
+ targetNamespace="http://www.w3.org/2003/05/soap-envelope"
+ elementFormDefault="qualified">
+
+ <xs:import namespace="http://www.w3.org/XML/1998/namespace"
+ schemaLocation="XML-Namespace-1998.xsd"/>
+
+ <!-- Envelope, header and body -->
+ <xs:element name="Envelope" type="tns:Envelope"/>
+ <xs:complexType name="Envelope">
+ <xs:sequence>
+ <xs:element ref="tns:Header" minOccurs="0"/>
+ <xs:element ref="tns:Body" minOccurs="1"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <xs:element name="Header" type="tns:Header"/>
+ <xs:complexType name="Header">
+ <xs:annotation>
+ <xs:documentation>
+ Elements replacing the wildcard MUST be namespace qualified, but can be in the targetNamespace
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <xs:element name="Body" type="tns:Body"/>
+ <xs:complexType name="Body">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <!-- Global Attributes. The following attributes are intended to be
+ usable via qualified attribute names on any complex type referencing
+ them. -->
+ <xs:attribute name="mustUnderstand" type="xs:boolean" default="0"/>
+ <xs:attribute name="relay" type="xs:boolean" default="0"/>
+ <xs:attribute name="role" type="xs:anyURI"/>
+
+ <!-- 'encodingStyle' indicates any canonicalization conventions
+ followed in the contents of the containing element. For example, the
+ value 'http://www.w3.org/2003/05/soap-encoding' indicates the pattern
+ described in the last call working draft of SOAP Version 1.2 Part 2:
+ Adjuncts -->
+
+ <xs:attribute name="encodingStyle" type="xs:anyURI"/>
+
+ <xs:element name="Fault" type="tns:Fault"/>
+ <xs:complexType name="Fault" final="extension">
+ <xs:annotation>
+ <xs:documentation>
+ Fault reporting structure
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element name="Code" type="tns:faultcode"/>
+ <xs:element name="Reason" type="tns:faultreason"/>
+ <xs:element name="Node" type="xs:anyURI" minOccurs="0"/>
+ <xs:element name="Role" type="xs:anyURI" minOccurs="0"/>
+ <xs:element name="Detail" type="tns:detail" minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="faultreason">
+ <xs:sequence>
+ <xs:element name="Text" type="tns:reasontext"
+ minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="reasontext">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute ref="xml:lang" use="required"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:complexType name="faultcode">
+ <xs:sequence>
+ <xs:element name="Value"
+ type="tns:faultcodeEnum"/>
+ <xs:element name="Subcode"
+ type="tns:subcode"
+ minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:simpleType name="faultcodeEnum">
+ <xs:restriction base="xs:QName">
+ <xs:enumeration value="tns:DataEncodingUnknown"/>
+ <xs:enumeration value="tns:MustUnderstand"/>
+ <xs:enumeration value="tns:Receiver"/>
+ <xs:enumeration value="tns:Sender"/>
+ <xs:enumeration value="tns:VersionMismatch"/>
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="subcode">
+ <xs:sequence>
+ <xs:element name="Value"
+ type="xs:QName"/>
+ <xs:element name="Subcode"
+ type="tns:subcode"
+ minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="detail">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax"/>
+ </xs:complexType>
+
+ <!-- Global element declaration and complex type definition for header entry returned due to a mustUnderstand fault -->
+ <xs:element name="NotUnderstood" type="tns:NotUnderstoodType"/>
+ <xs:complexType name="NotUnderstoodType">
+ <xs:attribute name="qname" type="xs:QName" use="required"/>
+ </xs:complexType>
+
+ <!-- Global element and associated types for managing version transition as described in Appendix A of the SOAP Version 1.2 Part 1 Last Call Working Draft -->
+ <xs:complexType name="SupportedEnvType">
+ <xs:attribute name="qname" type="xs:QName" use="required"/>
+ </xs:complexType>
+
+ <xs:element name="Upgrade" type="tns:UpgradeType"/>
+ <xs:complexType name="UpgradeType">
+ <xs:sequence>
+ <xs:element name="SupportedEnvelope" type="tns:SupportedEnvType" minOccurs="1" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+</xs:schema>
Added: webservices/muse/trunk/modules/muse-wsa-soap/specs/WS-Addressing-2005_08.xsd
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsa-soap/specs/WS-Addressing-2005_08.xsd?rev=413691&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsa-soap/specs/WS-Addressing-2005_08.xsd (added)
+++ webservices/muse/trunk/modules/muse-wsa-soap/specs/WS-Addressing-2005_08.xsd Mon Jun 12 09:04:42 2006
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema
+ targetNamespace="http://www.w3.org/2005/08/addressing"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:tns="http://www.w3.org/2005/08/addressing"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified">
+
+ <!-- Constructs from the WS-Addressing Core -->
+
+ <xs:element name="EndpointReference"
+ type="tns:EndpointReferenceType" />
+ <xs:complexType name="EndpointReferenceType" mixed="false">
+ <xs:sequence>
+ <xs:element name="Address" type="tns:AttributedURIType" />
+ <xs:element name="ReferenceParameters"
+ type="tns:ReferenceParametersType" minOccurs="0" />
+ <xs:element ref="tns:Metadata" minOccurs="0" />
+ <xs:any namespace="##other" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax" />
+ </xs:complexType>
+
+ <xs:complexType name="ReferenceParametersType" mixed="false">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax" />
+ </xs:complexType>
+
+ <xs:element name="Metadata" type="tns:MetadataType" />
+ <xs:complexType name="MetadataType" mixed="false">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax"
+ minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax" />
+ </xs:complexType>
+
+ <xs:element name="MessageID" type="tns:AttributedURIType" />
+ <xs:element name="RelatesTo" type="tns:RelatesToType" />
+ <xs:complexType name="RelatesToType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:attribute name="RelationshipType"
+ type="tns:RelationshipTypeOpenEnum" use="optional"
+ default="http://www.w3.org/2005/08/addressing/reply" />
+ <xs:anyAttribute namespace="##other"
+ processContents="lax" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:simpleType name="RelationshipTypeOpenEnum">
+ <xs:union memberTypes="tns:RelationshipType xs:anyURI" />
+ </xs:simpleType>
+
+ <xs:simpleType name="RelationshipType">
+ <xs:restriction base="xs:anyURI">
+ <xs:enumeration
+ value="http://www.w3.org/2005/08/addressing/reply" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="ReplyTo" type="tns:EndpointReferenceType" />
+ <xs:element name="From" type="tns:EndpointReferenceType" />
+ <xs:element name="FaultTo" type="tns:EndpointReferenceType" />
+ <xs:element name="To" type="tns:AttributedURIType" />
+ <xs:element name="Action" type="tns:AttributedURIType" />
+
+ <xs:complexType name="AttributedURIType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:anyURI">
+ <xs:anyAttribute namespace="##other"
+ processContents="lax" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <!-- Constructs from the WS-Addressing SOAP binding -->
+
+ <xs:attribute name="IsReferenceParameter" type="xs:boolean" />
+
+ <xs:simpleType name="FaultCodesOpenEnumType">
+ <xs:union memberTypes="tns:FaultCodesType xs:QName" />
+ </xs:simpleType>
+
+ <xs:simpleType name="FaultCodesType">
+ <xs:restriction base="xs:QName">
+ <xs:enumeration value="tns:InvalidAddressingHeader" />
+ <xs:enumeration value="tns:InvalidAddress" />
+ <xs:enumeration value="tns:InvalidEPR" />
+ <xs:enumeration value="tns:InvalidCardinality" />
+ <xs:enumeration value="tns:MissingAddressInEPR" />
+ <xs:enumeration value="tns:DuplicateMessageID" />
+ <xs:enumeration value="tns:ActionMismatch" />
+ <xs:enumeration value="tns:MessageAddressingHeaderRequired" />
+ <xs:enumeration value="tns:DestinationUnreachable" />
+ <xs:enumeration value="tns:ActionNotSupported" />
+ <xs:enumeration value="tns:EndpointUnavailable" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:element name="RetryAfter" type="tns:AttributedUnsignedLongType" />
+ <xs:complexType name="AttributedUnsignedLongType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:unsignedLong">
+ <xs:anyAttribute namespace="##other"
+ processContents="lax" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:element name="ProblemHeaderQName"
+ type="tns:AttributedQNameType" />
+ <xs:complexType name="AttributedQNameType" mixed="false">
+ <xs:simpleContent>
+ <xs:extension base="xs:QName">
+ <xs:anyAttribute namespace="##other"
+ processContents="lax" />
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:element name="ProblemHeader" type="tns:AttributedAnyType" />
+ <xs:complexType name="AttributedAnyType" mixed="false">
+ <xs:sequence>
+ <xs:any namespace="##any" processContents="lax"
+ minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax" />
+ </xs:complexType>
+
+ <xs:element name="ProblemIRI" type="tns:AttributedURIType" />
+
+ <xs:element name="ProblemAction" type="tns:ProblemActionType" />
+ <xs:complexType name="ProblemActionType" mixed="false">
+ <xs:sequence>
+ <xs:element ref="tns:Action" minOccurs="0" />
+ <xs:element name="SoapAction" minOccurs="0"
+ type="xs:anyURI" />
+ </xs:sequence>
+ <xs:anyAttribute namespace="##other" processContents="lax" />
+ </xs:complexType>
+
+</xs:schema>
Added: webservices/muse/trunk/modules/muse-wsa-soap/specs/XML-Namespace-1998.xsd
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsa-soap/specs/XML-Namespace-1998.xsd?rev=413691&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsa-soap/specs/XML-Namespace-1998.xsd (added)
+++ webservices/muse/trunk/modules/muse-wsa-soap/specs/XML-Namespace-1998.xsd Mon Jun 12 09:04:42 2006
@@ -0,0 +1,25 @@
+<?xml version='1.0'?>
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en">
+
+ <xs:attribute name="lang" type="xs:language">
+ </xs:attribute>
+
+ <xs:attribute name="space" default="preserve">
+ <xs:simpleType>
+ <xs:restriction base="xs:NCName">
+ <xs:enumeration value="default"/>
+ <xs:enumeration value="preserve"/>
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="base" type="xs:anyURI">
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+ <xs:attribute ref="xml:base"/>
+ <xs:attribute ref="xml:lang"/>
+ <xs:attribute ref="xml:space"/>
+ </xs:attributeGroup>
+
+</xs:schema>
Added: webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/EndpointReference.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/EndpointReference.java?rev=413691&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/EndpointReference.java (added)
+++ webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/EndpointReference.java Mon Jun 12 09:04:42 2006
@@ -0,0 +1,686 @@
+/*=============================================================================*
+ * 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.
+ * <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);
+ }
+
+ /**
+ *
+ * @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 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);
+ }
+
+ /**
+ *
+ * @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-trees
+ //
+
+ _parameters = XmlUtils.getElement(_xml, WsaConstants.PARAMETERS_QNAME);
+
+ if (_parameters == null || _parameters.getChildNodes().getLength() == 0)
+ _parameters = XmlUtils.createElement(doc, WsaConstants.PARAMETERS_QNAME);
+
+ else
+ _xml.appendChild(_parameters);
+ }
+
+ /**
+ *
+ * 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);
+ }
+}
Added: webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/MessageHeaders.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/MessageHeaders.java?rev=413691&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/MessageHeaders.java (added)
+++ webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/MessageHeaders.java Mon Jun 12 09:04:42 2006
@@ -0,0 +1,779 @@
+/*=============================================================================*
+ * 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 java.net.URISyntaxException;
+
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.muse.util.messages.Messages;
+import org.apache.muse.util.messages.MessagesFactory;
+import org.apache.muse.util.uuid.RandomUuidFactory;
+import org.apache.muse.util.xml.XmlSerializable;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.addressing.soap.SoapConstants;
+
+/**
+ *
+ * MessageHeaders provides WS-Addressing processing for SOAP message headers.
+ * It can be used to parse SOAP headers according to WS-A spec and read the
+ * values <b>or</b> create a new set of headers that can be serialized to a
+ * set of valid SOAP headers.
+ * <br><br>
+ * This class processes WS-A headers differently from other implementations
+ * in three ways:<br>
+ * <ol>
+ * <li>It provides the wsa:To header as an
+ * {@linkplain EndpointReference EndpointReference}, not
+ * a simple URI value.</li>
+ * <li>It turns all non-WS-A SOAP headers into reference properties for
+ * the wsa:To EPR.</li>
+ * <li>It provides a simple mechanism for generating the appropriate response
+ * headers for each set of request headers.</li>
+ * </ol>
+ * This class references the W3C DOM API rather than the JAX-RPC SOAP API
+ * because SOAPElements can usually be converted into DOM Elements very
+ * easily, but having a DOM Element does not mean that the user code has
+ * access to (or wants access to) the JAX-RPC API and its SOAP factories.
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ * @see EndpointReference
+ *
+ */
+
+public class MessageHeaders implements XmlSerializable
+{
+ //
+ // Used to lookup all exception messages
+ //
+ private static Messages _MESSAGES = MessagesFactory.get(MessageHeaders.class);
+
+ //
+ // below are the standard WS-A header values for SOAP messages
+ //
+
+ private URI _action = null;
+
+ private EndpointReference _faultTo = null;
+
+ private EndpointReference _from = null;
+
+ private URI _messageID = null;
+
+ private URI _relationship = null;
+
+ private EndpointReference _replyTo = null;
+
+ private EndpointReference _to = null;
+
+ /**
+ *
+ * Creates a valid set of WS-A message headers from the given SOAP Header.
+ * If the WS-A headers are using an old namespace, they are first converted
+ * to use the most current namespace (WsaUtils.NAMESPACE_URI) before being
+ * processed to maximize interoperability.
+ * <br><br>
+ * The wsa:To URI is transformed into an EPR. If there are non-WS-A
+ * headers in the SOAP Header, these are tranformed into reference
+ * properties for the wsa:To EPR.
+ * <br><br>
+ * An appropriate set of reply headers can be generated with the
+ * createReplyHeaders(URI) and createFaultHeaders() methods, assuming the
+ * SOAP Header included the appropriate wsa:From, wsa:ReplyTo, or
+ * wsa:FaultTo EPR.
+ *
+ * @param soapHeaders
+ * The Element representing a SOAP envelope's Header. The Header
+ * should contain all of the required WS-A elements.
+ *
+ * @throws SoapFault
+ * <ul>
+ * <li>
+ * If either the wsa:To, wsa:From, wsa:ReplyTo, or wsa:FaultTo
+ * XML is invalid according to the WS-A EPR definition.
+ * </li>
+ * <li>
+ * If either the wsa:To, wsa:MessageID, wsa:RelatesTo, or
+ * wsa:Action value is not a valid URI.
+ * </li>
+ * <li>
+ * If either the wsa:To, wsa:MessageID, or wsa:Action value is
+ * undefined.
+ * </li>
+ * </ul>
+ *
+ * @see #createFaultHeaders()
+ * @see #createReplyHeaders()
+ *
+ */
+ public MessageHeaders(Element soapHeaders)
+ throws SoapFault
+ {
+ if (soapHeaders == null)
+ throw new NullPointerException(_MESSAGES.get("NullSOAPHeader"));
+
+ URI toURI = null;
+
+ //
+ // collect all URI values in one try/catch
+ //
+ try
+ {
+ toURI = getURI(soapHeaders, WsaConstants.TO_QNAME);
+
+ _action = getURI(soapHeaders, WsaConstants.ACTION_QNAME);
+ _messageID = getURI(soapHeaders, WsaConstants.MESSAGE_ID_QNAME);
+ _relationship = getURI(soapHeaders, WsaConstants.RELATES_TO_QNAME);
+ }
+
+ catch (URISyntaxException error)
+ {
+ Object[] filler = { error.getMessage() };
+ throw new SoapFault(_MESSAGES.get("InvalidURI", filler));
+ }
+
+ //
+ // all of the URIs are required values
+ //
+
+ if (toURI == null)
+ {
+ Object[] filler = { WsaConstants.TO_QNAME };
+ throw new SoapFault(_MESSAGES.get("HeaderMissing", filler));
+ }
+
+ if (_action == null)
+ {
+ Object[] filler = { WsaConstants.ACTION_QNAME };
+ throw new SoapFault(_MESSAGES.get("HeaderMissing", filler));
+ }
+
+ //
+ // wsa:To is a URI, but we want to access it as an EPR
+ //
+ _to = new EndpointReference(toURI);
+
+ //
+ // read in optional EPR values that tell us where to send replies
+ //
+ _faultTo = getEPR(soapHeaders, WsaConstants.FAULT_TO_QNAME);
+ _from = getEPR(soapHeaders, WsaConstants.FROM_QNAME);
+ _replyTo = getEPR(soapHeaders, WsaConstants.REPLY_TO_QNAME);
+
+ if (_messageID == null && (_from != null || _replyTo != null))
+ throw new SoapFault(_MESSAGES.get("MessageIDMissing"));
+
+ Element[] children = XmlUtils.getAllElements(soapHeaders);
+
+ //
+ // NOTE: add all elements to the ReferenceProperties, since WS-A
+ // provides no way to distinguish between properties and
+ // parameters in the SOAP header.
+ //
+
+ for (int n = 0; n < children.length; ++n)
+ {
+ String attr = children[n].getAttributeNS(WsaConstants.NAMESPACE_URI, WsaConstants.IS_REFERENCE_PARAMETER);
+
+ if (Boolean.valueOf(attr) == Boolean.TRUE)
+ {
+ //
+ // remove SOAP junk from property XML - this is especially
+ // important when you start moving the EPR XML to other
+ // messages/fragments that may not have the SOAP prefixes
+ //
+ children[n].removeAttributeNS(SoapConstants.NAMESPACE_URI, SoapConstants.ACTOR);
+ children[n].removeAttributeNS(SoapConstants.NAMESPACE_URI, SoapConstants.MUST_UNDERSTAND);
+
+ QName qname = XmlUtils.getElementQName(children[n]);
+ _to.addParameter(qname, children[n]);
+ }
+ }
+ }
+
+ /**
+ *
+ * Creates a new set of WS-A message headers targeted to the given EPR
+ * and Action. This constructor creates its own unique wsa:MessageID.
+ *
+ * @param to
+ * The EPR that will supply the URI for wsa:To.
+ *
+ * @param action
+ * The wsa:Action URI.
+ *
+ */
+ public MessageHeaders(EndpointReference to, URI action)
+ {
+ if (to == null)
+ throw new NullPointerException(_MESSAGES.get("NullToEPR"));
+
+ _to = to;
+ _action = action;
+
+ _messageID = createMessageID();
+ }
+
+ /**
+ *
+ * Returns a new set of WS-A message headers based on this object; the
+ * headers returned can be used when replying to a message with a fault.
+ * The headers will be targeted to the wsa:FaultTo EPR and the WS-A
+ * fault action URI. If there is no wsa:FaultTo, wsa:From or the WS-A
+ * anonymous EPR is used.
+ * <br><br>
+ * <b>Note:</b> This method should not be used to create headers for
+ * "normal" responses - that is done with createReplyHeaders(URI).
+ *
+ * @return A new MessageHeaders where:
+ * <ul>
+ * <li>the wsa:To is the URI of this object's wsa:FaultTo,
+ * wsa:From, or the anonymous EPR</li>
+ * <li>the wsa:From is this object's wsa:To EPR</li>
+ * <li>the wsa:RelatesTo is the URI of this object's
+ * wsa:MessageID</li>
+ * <li>the wsa:Action is the standard WS-A fault URI.</li>
+ * </ul>
+ *
+ * @see #createReplyHeaders()
+ * @see #getFaultToAddress()
+ * @see #setFaultToAddress(EndpointReference)
+ * @see WsaConstants#FAULT_ACTION
+ *
+ */
+ public MessageHeaders createFaultHeaders()
+ {
+ EndpointReference faultTo = getFaultToAddress();
+ URI messageID = getMessageID();
+
+ //
+ // we can only send back fault headers if wsa:FaultTo or wsa:From exists
+ //
+ if (faultTo == null)
+ {
+ EndpointReference from = getFromAddress();
+
+ if (from == null)
+ from = WsaConstants.ANONYMOUS_EPR;
+
+ faultTo = from;
+ }
+
+ //
+ // 1. create headers bound for wsa:FaultTo
+ // 2. associate headers with request MessageID
+ // 3. set source that was in wsa:To
+ //
+ MessageHeaders faultHeaders =
+ new MessageHeaders(faultTo, WsaConstants.FAULT_ACTION);
+
+ if (messageID != null)
+ faultHeaders.setRelationship(messageID);
+
+ faultHeaders.setFromAddress(getToAddress());
+
+ return faultHeaders;
+ }
+
+ /**
+ *
+ * @return A unique UUID for use as a wsa:MessageID.
+ *
+ */
+ private URI createMessageID()
+ {
+ return RandomUuidFactory.getInstance().createUUID();
+ }
+
+ /**
+ *
+ * Returns a new set of WS-A message headers based on this object; the
+ * headers returned can be used when replying to a message (no fault).
+ * The headers will be targeted to the wsa:ReplyTo EPR. If there is no
+ * wsa:ReplyTo, wsa:From or the WS-A anonymous EPR is used.
+ * <br><br>
+ * <b>Note:</b> This method should not be used to create headers for
+ * responses where a fault has occurred - that should be done with
+ * createFaultHeaders().
+ *
+ * @return A new MessageHeaders where:
+ * <ul>
+ * <li>the wsa:To is the URI of this object's wsa:ReplyTo,
+ * wsa:From, or the anonymous EPR</li>
+ * <li>the wsa:From is this object's wsa:To EPR</li>
+ * <li>the wsa:RelatesTo is the URI of this object's
+ * wsa:MessageID</li>
+ * <li>the wsa:Action is the current URI with a "Response" suffix.</li>
+ * </ul>
+ *
+ * @see #getReplyToAddress()
+ * @see #setReplyToAddress(EndpointReference)
+ *
+ */
+ public MessageHeaders createReplyHeaders()
+ {
+ EndpointReference replyTo = getReplyToAddress();
+ URI messageID = getMessageID();
+
+ //
+ // we can only send back headers if wsa:ReplyTo or wsa:From exists
+ //
+ if (replyTo == null)
+ {
+ EndpointReference from = getFromAddress();
+
+ if (from == null)
+ from = WsaConstants.ANONYMOUS_EPR;
+
+ replyTo = from;
+ }
+
+ String requestAction = getAction().toString();
+ String replyAction = null;
+
+ if (requestAction.endsWith("Request"))
+ replyAction = requestAction.replaceAll("Request", "Response");
+
+ else
+ replyAction += "Response";
+
+ URI replyActionURI = URI.create(replyAction);
+
+ //
+ // 1. create headers bound for wsa:ReplyTo
+ // 2. associate headers with request MessageID
+ // 3. set source that was in wsa:To
+ //
+ MessageHeaders replyHeaders = new MessageHeaders(replyTo, replyActionURI);
+
+
+ if (messageID != null)
+ replyHeaders.setRelationship(messageID);
+
+ replyHeaders.setFromAddress(getToAddress());
+
+ return replyHeaders;
+ }
+
+ /**
+ *
+ * @return The wsa:Action URI. This is required value.
+ *
+ */
+ public URI getAction()
+ {
+ return _action;
+ }
+ /**
+ *
+ * @return The identifier found after the last slash in the wsa:Action
+ * URI. If the URI is 'http://ibm.com/spec/DoStuff', the value
+ * that is returned is 'DoStuff'.
+ *
+ */
+ public String getMethodName()
+ {
+ String actionURI = getAction().toString();
+ int lastSlash = actionURI.lastIndexOf('/');
+ String name = actionURI.substring(lastSlash + 1);
+
+ int request = name.indexOf("Request");
+
+ if (request >= 0)
+ name = name.substring(0, request);
+
+ return Character.toLowerCase(name.charAt(0)) + name.substring(1);
+ }
+
+ /**
+ *
+ * Parses the given XML to create a valid EPR. The EPR XML root element
+ * must have the given QName.
+ *
+ * @param root
+ * The Element containing the EPR Element as one of its children.
+ *
+ * @param qname
+ * The QName of the child element that defines an EPR.
+ *
+ * @return A valid EPR based on the given XML.
+ *
+ */
+ private EndpointReference getEPR(Element root, QName qname)
+ throws SoapFault
+ {
+ Element epr = XmlUtils.getElement(root, qname);
+
+ if (epr == null)
+ return null;
+
+ return new EndpointReference(epr);
+ }
+
+ /**
+ *
+ * @return The wsa:FaultTo EPR. The method returns null if the value is
+ * not set.
+ *
+ */
+ public EndpointReference getFaultToAddress()
+ {
+ return _faultTo;
+ }
+
+ /**
+ *
+ * @return The wsa:From EPR. The method returns null if the value is
+ * not set.
+ *
+ */
+ public EndpointReference getFromAddress()
+ {
+ return _from;
+ }
+
+ /**
+ *
+ * @return The unique wsa:MessageID UUID. This is a required value.
+ *
+ */
+ public URI getMessageID()
+ {
+ return _messageID;
+ }
+
+ /**
+ *
+ * @return The wsa:RelatesTo value. The method returns null if the value
+ * is not set. wsa:RelatesTo is a UUID that maps to another
+ * MessageHeader's wsa:MessageID.
+ *
+ */
+ public URI getRelationship()
+ {
+ return _relationship;
+ }
+
+ /**
+ *
+ * @return This method always returns WsaUtils.REPLY_RELATIONSHIP_QNAME.
+ *
+ * @see WsaConstants#REPLY_RELATIONSHIP_QNAME
+ *
+ */
+ public QName getRelationshipType()
+ {
+ return WsaConstants.REPLY_RELATIONSHIP_QNAME;
+ }
+
+ /**
+ *
+ * @return The wsa:ReplyTo EPR. The method returns null if the value is
+ * not set.
+ *
+ */
+ public EndpointReference getReplyToAddress()
+ {
+ return _replyTo;
+ }
+
+ /**
+ *
+ * @return An EPR representing the wsa:To URI and the reference properties
+ * defined in the SOAP Header (if any). This is a required value.
+ *
+ */
+ public EndpointReference getToAddress()
+ {
+ return _to;
+ }
+
+ /**
+ *
+ * Parses the given XML to create a valid URI. The URI's XML root element
+ * must have the given QName.
+ *
+ * @param root
+ * The Element containing the URI Element as one of its children.
+ *
+ * @param qname
+ * The QName of the child element that defines a URI.
+ *
+ * @return A URI based on the given text value.
+ *
+ * @throws URISyntaxException
+ * <ul>
+ * <li>If the text in the child element is not a valid URI.</li>
+ * </ul>
+ *
+ */
+ private URI getURI(Element root, QName qname)
+ throws URISyntaxException
+ {
+ String addressText = XmlUtils.getElementText(root, qname);
+
+ if (addressText == null)
+ return null;
+
+ return new URI(addressText);
+ }
+
+ /**
+ *
+ * @param action
+ * The wsa:Action URI. This cannot be null.
+ *
+ */
+ protected void setAction(URI action)
+ {
+ if (action == null)
+ throw new NullPointerException(_MESSAGES.get("NullActionURI"));
+
+ _action = action;
+ }
+
+ /**
+ *
+ * @param faultTo
+ * The wsa:FaultTo EPR - if non-null, a copy of EPR will be made,
+ * so modifications to the original will have no effect on this
+ * set of headers.
+ *
+ */
+ public void setFaultToAddress(EndpointReference faultTo)
+ {
+ if (faultTo == null)
+ _faultTo = null;
+
+ //
+ // need to make our own copy whose root element is wsa:FaultTo
+ //
+ else
+ _faultTo = new EndpointReference(faultTo, WsaConstants.FAULT_TO_QNAME);
+ }
+
+ /**
+ *
+ * @param from
+ * The wsa:From EPR - if non-null, a copy of EPR will be made, so
+ * modifications to the original will have no effect on this set
+ * of headers.
+ *
+ */
+ public void setFromAddress(EndpointReference from)
+ {
+ if (from == null)
+ _from = null;
+
+ //
+ // need to make our own copy whose root element is wsa:From
+ //
+ else
+ _from = new EndpointReference(from, WsaConstants.FROM_QNAME);
+ }
+
+ /**
+ *
+ * @param messageID
+ * The wsa:MessageID. This cannot be null.
+ *
+ */
+ protected void setMessageID(URI messageID)
+ {
+ if (messageID == null)
+ throw new NullPointerException(_MESSAGES.get("NullMessageID"));
+
+ _messageID = messageID;
+ }
+
+ /**
+ *
+ * @param messageID
+ * The wsa:RelatesTo ID. This cannot be null;
+ *
+ */
+ public void setRelationship(URI messageID)
+ {
+ if (messageID == null)
+ throw new NullPointerException(_MESSAGES.get("NullMessageID"));
+
+ _relationship = messageID;
+ }
+
+ /**
+ *
+ * @param replyTo
+ * The wsa:ReplyTo EPR - if non-null, a copy of EPR will be made,
+ * so modifications to the original will have no effect on this
+ * set of headers.
+ *
+ */
+ public void setReplyToAddress(EndpointReference replyTo)
+ {
+ if (replyTo == null)
+ _replyTo = null;
+
+ //
+ // need to make our own copy whose root element is wsa:ReplyTo
+ //
+ else
+ _replyTo = new EndpointReference(replyTo, WsaConstants.REPLY_TO_QNAME);
+ }
+
+ /**
+ *
+ * @param to
+ * An EPR with the address value for the wsa:To URI. This cannot
+ * be null. No copy of the given EPR is made, so subsequent
+ * modifications to it will affect this object.
+ *
+ */
+ protected void setToAddress(EndpointReference to)
+ {
+ if (to == null)
+ throw new NullPointerException(_MESSAGES.get("NullToEPR"));
+
+ _to = to;
+ }
+
+ /**
+ *
+ * @return An XML string representing the collection of WS-A headers.
+ * The XML would be a valid SOAP Header element.
+ *
+ */
+ public String toString()
+ {
+ return XmlUtils.toString(toXML(), false);
+ }
+
+ /**
+ *
+ * @see #toXML(Document)
+ *
+ */
+ public Element toXML()
+ {
+ return toXML(XmlUtils.EMPTY_DOC);
+ }
+
+ /**
+ *
+ *
+ *
+ * @param doc
+ * The XML Document to use when creating new elements for the
+ * SOAP Header XML. The elements that are created will <b>not</b>
+ * be appended to this Document.
+ *
+ * @return A SOAP Header element with all of the valid WS-A headers as
+ * child elements. There is no guarantee on the order of the WS-A
+ * headers. All reference parameters and properties in the wsa:To
+ * EPR will be appended as children of the root SOAP Header element.
+ *
+ * @see SoapConstants#HEADER_QNAME
+ *
+ */
+ public Element toXML(Document doc)
+ {
+ if (doc == null)
+ throw new NullPointerException(_MESSAGES.get("NullXMLDocument"));
+
+ Element soapHeaders =
+ XmlUtils.createElement(doc, SoapConstants.HEADER_QNAME);
+
+ //
+ // wsa:MessageID
+ //
+ URI messageID = getMessageID();
+
+ if (messageID != null)
+ {
+ Element idXML = XmlUtils.createElement(doc, WsaConstants.MESSAGE_ID_QNAME, messageID);
+ soapHeaders.appendChild(idXML);
+ }
+
+ //
+ // wsa:To
+ //
+ URI toURI = getToAddress().getAddress();
+ Element to = XmlUtils.createElement(doc, WsaConstants.TO_QNAME, toURI);
+ soapHeaders.appendChild(to);
+
+ //
+ // wsa:Action
+ //
+ Element action =
+ XmlUtils.createElement(doc, WsaConstants.ACTION_QNAME, getAction());
+ soapHeaders.appendChild(action);
+
+ //
+ // wsa:RelatesTo (optional)
+ //
+ URI relatesTo = getRelationship();
+
+ if (relatesTo != null)
+ {
+ Element relationship =
+ XmlUtils.createElement(doc, WsaConstants.RELATES_TO_QNAME, relatesTo);
+
+ String type = XmlUtils.toString(getRelationshipType());
+ relationship.setAttribute(WsaConstants.RELATIONSHIP_TYPE, type);
+
+ soapHeaders.appendChild(relationship);
+ }
+
+ //
+ // wsa:From, wsa:ReplyTo, and wsa:FaultTo (optional)
+ //
+
+ EndpointReference[] eprs = new EndpointReference[] {
+ getFromAddress(), getReplyToAddress(), getFaultToAddress()
+ };
+
+ for (int n = 0; n < eprs.length; ++n)
+ {
+ if (eprs[n] != null)
+ {
+ Element xml = eprs[n].toXML();
+ xml = (Element)doc.importNode(xml, true);
+ soapHeaders.appendChild(xml);
+ }
+ }
+
+ //
+ // wsa:ReferenceParameters (optional)
+ //
+
+ Element[] parameters = getToAddress().getParameters();
+
+ for (int n = 0; n < parameters.length; ++n)
+ {
+ Element copy = (Element)doc.importNode(parameters[n], true);
+ copy.setAttributeNS(WsaConstants.NAMESPACE_URI, WsaConstants.IS_REFERENCE_PARAMETER_QNAME, "true");
+ soapHeaders.appendChild(copy);
+ }
+
+ return soapHeaders;
+ }
+}
Added: webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/Messages.properties
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/Messages.properties?rev=413691&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/Messages.properties (added)
+++ webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/Messages.properties Mon Jun 12 09:04:42 2006
@@ -0,0 +1,23 @@
+NullSOAPHeader = The SOAP Header element is null.
+NullToAddress = The wsa:To URI is null.
+NullToEPR = The EndpointReference representing wsa:To is null.
+NullActionURI = The wsa:Action URI is null.
+NullMessageID = The wsa:MessageID is null.
+NullXMLDocument = The DOM Document is null.
+NullEPRElement = The DOM Element is null.
+NullCopyEPR = The EndpointReference copy is null.
+NullEPRTypeQName = The QName for the EndpointReference type is null.
+InvalidEPRCreated = The EndpointReference being copied is invalid. The XML serialization (or deserialization) is broken - it should not be possible to create an invalid EPR.
+NullReferenceParameter = The reference parameter is null.
+NullParameterQName = The reference parameter QName is null.
+NullReferenceProperty = The reference property is null.
+NullPropertyQName = The reference property QName is null.
+InvalidAddressURI = Invalid wsa:Address URI: XXX
+NoParameterFound = The reference parameter does not exist: XXX
+NoParametersFound = No reference parameter does not exist: XXX
+NoPropertyFound = The reference property does not exist: XXX
+NoPropertiesFound = The reference property does not exist: XXX
+NoServiceNameFound = There must be a wsa:ServiceName in order to set the PortName attribute.
+InvalidURI = The SOAP headers contained an invalid URI. The original error was: XXX
+HeaderMissing = The SOAP headers are missing a required WS-Addressing header: XXX
+MessageIDMissing = The SOAP headers did not contain a wsa:MessageID. A wsa:MessageID value is required if the headers have a wsa:From or wsa:ReplyTo EPR.
Added: webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/WsaConstants.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/WsaConstants.java?rev=413691&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/WsaConstants.java (added)
+++ webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/WsaConstants.java Mon Jun 12 09:04:42 2006
@@ -0,0 +1,152 @@
+/*=============================================================================*
+ * 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;
+
+/**
+ *
+ * WsaUtils is a collection of properties that is useful when programming
+ * against the WS-Addressing spec. This class uses WS-A 1.0 (08/2005).
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ */
+
+public class WsaConstants
+{
+ /**
+ *
+ * The namespace of the WS-A 1.0 spec
+ *
+ */
+ public static final String NAMESPACE_URI = "http://www.w3.org/2005/08/addressing";
+
+ public static final String PREFIX = "wsa";
+
+ public static final String MUSE_ADDRESSING_URI = "http://ws.apache.org/muse/addressing";
+
+ public static final String MUSE_ADDRESSING_PREFIX = "muse-wsa";
+
+ //
+ // This is the default identifier used for the implied resource pattern.
+ // This is preferred to something like MUWS P1 ResourceId because it is
+ // generic to all resource types.
+ //
+ public static final QName DEFAULT_RESOURCE_ID_QNAME =
+ new QName(MUSE_ADDRESSING_URI, "ResourceId", MUSE_ADDRESSING_PREFIX);
+
+ /**
+ *
+ * The URI for anonymous EPRs.
+ *
+ */
+ public static final String ANONYMOUS_URI = NAMESPACE_URI + "/role/anonymous";
+
+ /**
+ *
+ * The wsa:Action that all fault messages should use.
+ *
+ */
+ public static final String FAULT_URI = NAMESPACE_URI + "/fault";
+
+ /**
+ *
+ * The wsa:Action that all fault messages should use (as a java.net.URI).
+ *
+ */
+ public static final URI FAULT_ACTION = URI.create(FAULT_URI);
+
+ public static final String REPLY_RELATIONSHIP = PREFIX + ":Reply";
+
+ /**
+ *
+ * The standard EndpointReference QName - note that EPRs are <b>not</b>
+ * required to use this as their root element QName when serialized to XML.
+ *
+ */
+ public static final QName EPR_QNAME =
+ new QName(NAMESPACE_URI, "EndpointReference", PREFIX);
+
+ /**
+ *
+ * The name of the XSD EPR type. For EPR XML instances, use EPR_QNAME.
+ *
+ */
+ public static final QName EPR_TYPE_QNAME =
+ new QName(NAMESPACE_URI, "EndpointReferenceType", PREFIX);
+
+ public static final QName ACTION_QNAME =
+ new QName(NAMESPACE_URI, "Action", PREFIX);
+
+ public static final QName ADDRESS_QNAME =
+ new QName(NAMESPACE_URI, "Address", PREFIX);
+
+ public static final QName FAULT_TO_QNAME =
+ new QName(NAMESPACE_URI, "FaultTo", PREFIX);
+
+ public static final QName FROM_QNAME =
+ new QName(NAMESPACE_URI, "From", PREFIX);
+
+ public static final QName METADATA_QNAME =
+ new QName(NAMESPACE_URI, "Metadata", PREFIX);
+
+ public static final QName MESSAGE_ID_QNAME =
+ new QName(NAMESPACE_URI, "MessageID", PREFIX);
+
+ public static final QName PARAMETERS_QNAME =
+ new QName(NAMESPACE_URI, "ReferenceParameters", PREFIX);
+
+ public static final QName PORT_TYPE_QNAME =
+ new QName(NAMESPACE_URI, "PortType", PREFIX);
+
+ public static final QName RELATES_TO_QNAME =
+ new QName(NAMESPACE_URI, "RelatesTo", PREFIX);
+
+ public static final String RELATIONSHIP_TYPE = "RelationshipType";
+
+ public static final QName REPLY_RELATIONSHIP_QNAME =
+ new QName(NAMESPACE_URI, "Reply", PREFIX);
+
+ public static final QName REPLY_TO_QNAME =
+ new QName(NAMESPACE_URI, "ReplyTo", PREFIX);
+
+ public static final QName SERVICE_NAME_QNAME =
+ new QName(NAMESPACE_URI, "ServiceName", PREFIX);
+
+ public static final String SERVICE_PORT_NAME = "PortName";
+
+ public static final QName TO_QNAME =
+ new QName(NAMESPACE_URI, "To", PREFIX);
+
+ public static final String IS_REFERENCE_PARAMETER = "IsReferenceParameter";
+
+ public static final String IS_REFERENCE_PARAMETER_QNAME = "wsa:IsReferenceParameter";
+
+ /**
+ *
+ * The anonymous EPR - this can be used for messages going through
+ * firewalls or situations where the source doesn't want to receive
+ * the reply. Because this EPR is the same no matter where it is
+ * being "sent", we can share one instance of it with all components.
+ *
+ */
+ public static final EndpointReference ANONYMOUS_EPR =
+ new EndpointReference(URI.create(ANONYMOUS_URI));
+}
Added: webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/Messages.properties
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/Messages.properties?rev=413691&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/Messages.properties (added)
+++ webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/Messages.properties Mon Jun 12 09:04:42 2006
@@ -0,0 +1,5 @@
+NullDestinationEPR = The destination EPR is null.
+NullActionURI = The WS-A Action URI (wsa:Action) is null.
+NullSOAPBody = The array of SOAP Body elements is null.
+NullTraceWriter = The PrintWriter for tracing is null. If you want to stop tracing, call setTrace(false). If you need to close the PrintWriter and don't have a reference to it, you can call getTraceWriter().
+InvalidPort = Port numbers must be positive integers between 0 and 65535. You provided XXX.
Added: webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/SimpleSoapClient.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/SimpleSoapClient.java?rev=413691&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/SimpleSoapClient.java (added)
+++ webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/SimpleSoapClient.java Mon Jun 12 09:04:42 2006
@@ -0,0 +1,339 @@
+/*=============================================================================*
+ * 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.soap;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.net.URL;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.muse.util.messages.Messages;
+import org.apache.muse.util.messages.MessagesFactory;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.addressing.MessageHeaders;
+import org.apache.muse.ws.addressing.soap.SoapClient;
+
+/**
+ *
+ * SimpleSoapClient is and implementation of {@linkplain SoapClient SoapClient}
+ * that relies on the java.net.HttpURLConnection API to send and receive
+ * SOAP messages. It provides complete WS-Addressing (WS-A) support, so that
+ * all requests are routed with WS-A EPRs and Actions. Messages are sent with
+ * valid reply and fault EPRs so that responses can be redirected if desired.
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ */
+
+public class SimpleSoapClient implements SoapClient
+{
+ //
+ // Used to lookup all exception messages
+ //
+ private static Messages _MESSAGES =
+ MessagesFactory.get(SimpleSoapClient.class);
+
+ //
+ // Set to 0...65535 if TCP/SOAP monitor is in use
+ //
+ private int _monitorPort = -1;
+
+ //
+ // Print all SOAP messages if true - default is false.
+ //
+ private boolean _trace = false;
+
+ //
+ // The stream used for tracing - the default is stdout
+ //
+ private PrintWriter _traceWriter = new PrintWriter(System.out);
+
+ /**
+ *
+ * Creates a valid SOAP message, including WS-A headers that specify
+ * the destination and operation (action). The WS-A headers include
+ * proper return/fault information for the recipient to use in response.
+ *
+ * @param source
+ * @param destination
+ * @param action
+ * @param bodyElements
+ *
+ * @return A valid SOAP message that can be sent to the destination.
+ *
+ */
+ protected Element createMessage(EndpointReference source,
+ EndpointReference destination,
+ URI action,
+ Element[] bodyElements)
+ {
+ Document doc = XmlUtils.createDocument();
+ Element soapXML = XmlUtils.createElement(doc, SoapConstants.ENVELOPE_QNAME);
+
+ //
+ // add WS-Addressing headers
+ //
+ MessageHeaders headers = new MessageHeaders(destination, action);
+
+ //
+ // if there's a source EPR, we can provide a wsa:From
+ //
+ if (source != null)
+ headers.setFromAddress(source);
+
+ Element headersXML = headers.toXML(doc);
+ soapXML.appendChild(headersXML);
+
+ //
+ // copy data into SOAP body
+ //
+ Element bodyXML = XmlUtils.createElement(doc, SoapConstants.BODY_QNAME);
+ soapXML.appendChild(bodyXML);
+
+ for (int n = 0; n < bodyElements.length; ++n)
+ {
+ if (bodyElements[n].getOwnerDocument() != doc)
+ bodyElements[n] = (Element)doc.importNode(bodyElements[n], true);
+
+ bodyXML.appendChild(bodyElements[n]);
+ }
+
+ return soapXML;
+ }
+
+ /**
+ *
+ * @param destination
+ *
+ * @return The URL of the EPR's wsa:Address. If SOAP monitoring is on,
+ * the URL's port is switched to the monitor port.
+ *
+ */
+ protected URL getDestinationURL(EndpointReference destination)
+ {
+ URI uri = destination.getAddress();
+
+ //
+ // for TCP/SOAP monitoring, copy the URI with the new port.
+ // we have to make a new object because URI's are immutable.
+ //
+ try
+ {
+ if (isUsingSoapMonitor())
+ uri = new URI(uri.getScheme(),
+ uri.getUserInfo(),
+ uri.getHost(),
+ getSoapMonitorPort(),
+ uri.getPath(),
+ uri.getQuery(),
+ uri.getFragment());
+
+ return uri.toURL();
+ }
+
+ catch (Throwable error)
+ {
+ throw new RuntimeException(error.getMessage(), error);
+ }
+ }
+
+ public int getSoapMonitorPort()
+ {
+ return _monitorPort;
+ }
+
+ public PrintWriter getTraceWriter()
+ {
+ return _traceWriter;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ * <br><br>
+ * The default value is 'false'.
+ *
+ */
+ public boolean isUsingSoapMonitor()
+ {
+ return _monitorPort >= 0;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ * <br><br>
+ * The default value is 'false'.
+ *
+ */
+ public boolean isUsingTrace()
+ {
+ return _trace;
+ }
+
+ public Element[] send(EndpointReference src,
+ EndpointReference dest,
+ URI wsaAction,
+ Element[] body)
+ {
+ if (dest == null)
+ throw new NullPointerException(_MESSAGES.get("NullDestinationEPR"));
+
+ if (wsaAction == null)
+ throw new NullPointerException(_MESSAGES.get("NullActionURI"));
+
+ if (body == null)
+ throw new NullPointerException(_MESSAGES.get("NullSOAPBody"));
+
+ //
+ // create the request message and turn it into bytes
+ //
+ Element soapRequest = createMessage(src, dest, wsaAction, body);
+ byte[] soapBytes = XmlUtils.toString(soapRequest).getBytes();
+
+ if (isUsingTrace())
+ trace(soapRequest, false);
+
+ Element soapResponse = null;
+
+ try
+ {
+ //
+ // set up the HTTP request - POST of SOAP 1.2 data
+ //
+ URL url = getDestinationURL(dest);
+ HttpURLConnection connection = (HttpURLConnection)url.openConnection();
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Content-type", SoapConstants.CONTENT_TYPE_HEADER);
+ connection.setDoOutput(true);
+ connection.connect();
+
+ //
+ // send the SOAP request...
+ //
+ OutputStream output = connection.getOutputStream();
+ output.write(soapBytes);
+ output.flush();
+ output.close();
+
+ //
+ // read in the response and build an XML document from it
+ //
+ InputStream input = connection.getInputStream();
+
+ Document responseDoc = XmlUtils.createDocument(input);
+ soapResponse = XmlUtils.getFirstElement(responseDoc);
+
+ input.close();
+ connection.disconnect();
+ }
+
+ catch (Throwable error)
+ {
+ SoapFault soapFault = new SoapFault(error);
+ return new Element[]{ soapFault.toXML() };
+ }
+
+ if (isUsingTrace())
+ trace(soapResponse, true);
+
+ //
+ // return the elements inside the SOAP body
+ //
+ Element responseBody = XmlUtils.getElement(soapResponse, SoapConstants.BODY_QNAME);
+ return XmlUtils.getAllElements(responseBody);
+ }
+
+ public void setTrace(boolean trace)
+ {
+ _trace = trace;
+ }
+
+ /**
+ *
+ * {@inheritDoc}
+ * <br><br>
+ * Note that there is a default PrintWriter set at instantiation - it
+ * wraps the System.out stream.
+ *
+ */
+ public void setTraceWriter(PrintWriter writer)
+ {
+ if (writer == null)
+ throw new NullPointerException(_MESSAGES.get("NullTraceWriter"));
+
+ _traceWriter = writer;
+ }
+
+ public void startSoapMonitor(int monitorPort)
+ {
+ if (monitorPort < 1)
+ {
+ Object[] filler = { new Integer(monitorPort) };
+ throw new RuntimeException(_MESSAGES.get("InvalidPort", filler));
+ }
+
+ _monitorPort = monitorPort;
+ }
+
+ public void stopSoapMonitor()
+ {
+ _monitorPort = -1;
+ }
+
+ /**
+ *
+ * @param xml
+ * An XML fragment that will be sent to the trace log.
+ *
+ * @param incoming
+ * True if the message was part of an incoming SOAP message. This
+ * merely provides some context in the trace log.
+ *
+ */
+ protected void trace(Element xml, boolean incoming)
+ {
+ PrintWriter writer = getTraceWriter();
+ writer.write("[CLIENT TRACE] SOAP envelope contents (");
+ writer.write(incoming ? "incoming" : "outgoing");
+ writer.write("):\n\n");
+ writer.write(XmlUtils.toString(xml, false));
+ writer.write('\n');
+ writer.flush();
+ }
+
+ /**
+ *
+ * @param message
+ * The message to print to the trace log.
+ *
+ */
+ protected void trace(String message)
+ {
+ PrintWriter writer = getTraceWriter();
+ writer.write("[CLIENT TRACE] ");
+ writer.write(message);
+ writer.write('\n');
+ writer.flush();
+ }
+}
Added: webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/SoapClient.java
URL: http://svn.apache.org/viewvc/webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/SoapClient.java?rev=413691&view=auto
==============================================================================
--- webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/SoapClient.java (added)
+++ webservices/muse/trunk/modules/muse-wsa-soap/src/org/apache/muse/ws/addressing/soap/SoapClient.java Mon Jun 12 09:04:42 2006
@@ -0,0 +1,67 @@
+/*=============================================================================*
+ * 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.soap;
+
+import java.net.URI;
+
+import org.w3c.dom.Element;
+
+import org.apache.muse.util.Traceable;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.addressing.soap.SoapMonitor;
+
+/**
+ *
+ * SoapClient is a generic interface for a common set of SOAP utilities that
+ * may be implemented with different APIs from platform to platform. It allows
+ * users to send messages without putting API-specific references in their code.
+ *
+ * @author Dan Jemiolo (danj)
+ *
+ */
+
+public interface SoapClient extends SoapMonitor, Traceable
+{
+ /**
+ *
+ * Sends a SOAP envelope with the given body to the given destination.
+ * The SOAP header will include WS-A headers, one of which will be the
+ * WS-A Action specified in the third parameter. This method is not
+ * asynchronous - it will wait for a response and return the contents
+ * of the SOAP body.
+ *
+ * @param src
+ * The EPR of the service sending the message.
+ *
+ * @param dest
+ * The EPR of the service that will receive the message.
+ *
+ * @param wsaAction
+ * The WS-A Action that specifies the operation to be invoked on
+ * the destination service.
+ *
+ * @param body
+ * The contents of the SOAP body.
+ *
+ * @return The contents of the SOAP body in the response message. If
+ * the request resulted in a fault, the contents will include
+ * the fault XML. Note that such faults are not related to
+ * basic networking/SOAP faults.
+ *
+ */
+ Element[] send(EndpointReference src, EndpointReference dest, URI wsaAction, Element[] body);
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: muse-commits-unsubscribe@ws.apache.org
For additional commands, e-mail: muse-commits-help@ws.apache.org