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