You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by sc...@apache.org on 2008/04/05 20:05:25 UTC

svn commit: r645154 - in /webservices/axis2/trunk/java/modules: jaxws-integration/test/org/apache/axis2/jaxws/provider/ jaxws-integration/test/org/apache/axis2/jaxws/provider/soapmsg/ jaxws/src/org/apache/axis2/jaxws/ jaxws/src/org/apache/axis2/jaxws/c...

Author: scheu
Date: Sat Apr  5 11:05:22 2008
New Revision: 645154

URL: http://svn.apache.org/viewvc?rev=645154&view=rev
Log:
AXIS2-3708
Contributor:Rich Scheuerle
Adding code to support inbound/outbound properties on the jaxws client binding to set/query the SOAP Headers.
See the JIRA proposal for info.

Added:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/SOAPHeadersAdapter.java
Modified:
    webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/SoapMessageProviderTests.java
    webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/soapmsg/SoapMessageProvider.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/client/async/AsyncResponse.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/impl/InvocationControllerImpl.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/BaseMessageContext.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/XMLPart.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLPartBase.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpine.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/util/MessageUtils.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java
    webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/Constants.java
    webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPElementImpl.java

Modified: webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/SoapMessageProviderTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/SoapMessageProviderTests.java?rev=645154&r1=645153&r2=645154&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/SoapMessageProviderTests.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/SoapMessageProviderTests.java Sat Apr  5 11:05:22 2008
@@ -22,6 +22,8 @@
 
 import junit.framework.Test;
 import junit.framework.TestSuite;
+
+import org.apache.axis2.Constants;
 import org.apache.axis2.jaxws.TestLogger;
 import org.apache.axis2.jaxws.provider.soapmsg.SoapMessageProvider;
 
@@ -33,14 +35,20 @@
 import javax.xml.soap.SOAPBody;
 import javax.xml.soap.SOAPConstants;
 import javax.xml.soap.SOAPElement;
+import javax.xml.soap.SOAPFactory;
 import javax.xml.soap.SOAPFault;
 import javax.xml.soap.SOAPMessage;
 import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.Binding;
 import javax.xml.ws.Dispatch;
 import javax.xml.ws.Service;
 import javax.xml.ws.soap.SOAPFaultException;
 import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 /**
  * Tests Dispatch<SOAPMessage> client and a Provider<SOAPMessage> service.
@@ -64,6 +72,9 @@
     private String EMPTYBODY_INVOKE = "<ns2:invokeOp xmlns:ns2=\"http://org.test.soapmessage\"><invoke_str>" + 
         SoapMessageProvider.XML_EMPTYBODY_REQUEST +
         "</invoke_str></ns2:invokeOp>";
+    private String CHECKHEADERS_INVOKE = "<ns2:invokeOp xmlns:ns2=\"http://org.test.soapmessage\"><invoke_str>" + 
+        SoapMessageProvider.XML_CHECKHEADERS_REQUEST +
+        "</invoke_str></ns2:invokeOp>";
     private String ATTACHMENT_INVOKE = "<ns2:invokeOp xmlns:ns2=\"http://org.test.soapmessage\"><invoke_str>" + 
         SoapMessageProvider.XML_ATTACHMENT_REQUEST +
         "</invoke_str></ns2:invokeOp>";
@@ -78,11 +89,11 @@
         SoapMessageProvider.SWAREF_REF +
         "</ns2:invokeOp>";   
     private String XML_FAULT_INVOKE = "<ns2:invokeOp xmlns:ns2=\"http://org.test.soapmessage\"><invoke_str>" + 
-    SoapMessageProvider.XML_FAULT_REQUEST +
-    "</invoke_str></ns2:invokeOp>";
+        SoapMessageProvider.XML_FAULT_REQUEST +
+        "</invoke_str></ns2:invokeOp>";
     private String XML_WSE_INVOKE = "<ns2:invokeOp xmlns:ns2=\"http://org.test.soapmessage\"><invoke_str>" + 
-    SoapMessageProvider.XML_WSE_REQUEST +
-    "</invoke_str></ns2:invokeOp>";
+        SoapMessageProvider.XML_WSE_REQUEST +
+        "</invoke_str></ns2:invokeOp>";
                 
     public static Test suite() {
         return getTestSetup(new TestSuite(SoapMessageProviderTests.class));
@@ -92,10 +103,7 @@
      * Sends an SOAPMessage containing only xml data to the web service.  
      * Receives a response containing just xml data.
      */
-    
-    // TODO: test disabled due to XMLDispatch.createMessageFromValue failing to copy
-    // mime header to request.  Server sample has an assert that checks for it, and fails.
-    public void testProviderSourceXMLOnly(){
+    public void testProviderSOAPMessageXMLOnly(){
         try{       
             // Create the dispatch
             Dispatch<SOAPMessage> dispatch = createDispatch();
@@ -110,7 +118,7 @@
             request.setContentDescription(SoapMessageProvider.XML_REQUEST);
             
             // Dispatch
-            TestLogger.logger.debug(">> Invoking SourceMessageProviderDispatch");
+            TestLogger.logger.debug(">> Invoking SOAPMessageProviderDispatch");
         	SOAPMessage response = dispatch.invoke(request);
 
             // Check for valid content description
@@ -124,7 +132,6 @@
             
             // Print out the response
             TestLogger.logger.debug(">> Response [" + response.toString() + "]");
-            response.writeTo(System.out);
         	
         }catch(Exception e){
         	e.printStackTrace();
@@ -137,7 +144,7 @@
      * Sends an SOAPMessage containing only xml data to the web service.  
      * Receives a response containing an empty body
      */
-    public void testProviderSourceXMLEmptyBody(){
+    public void testProviderSOAPMessageXMLEmptyBody(){
         try{       
             // Create the dispatch
             Dispatch<SOAPMessage> dispatch = createDispatch();
@@ -152,7 +159,7 @@
             request.setContentDescription(SoapMessageProvider.XML_EMPTYBODY_REQUEST);
             
             // Dispatch
-            TestLogger.logger.debug(">> Invoking SourceMessageProviderDispatch");
+            TestLogger.logger.debug(">> Invoking SOAPMessageProviderDispatch");
             SOAPMessage response = dispatch.invoke(request);
             
             // Check assertions
@@ -164,7 +171,6 @@
             
             // Print out the response
             TestLogger.logger.debug(">> Response [" + response.toString() + "]");
-            response.writeTo(System.out);
             
         }catch(Exception e){
             e.printStackTrace();
@@ -177,7 +183,7 @@
      * Sends an SOAPMessage containing only xml data 
      * Provider will throw a Fault
      */
-    public void testProviderSOAPFault() throws Exception {
+    public void testProviderSOAPMessageSOAPFault() throws Exception {
              
             // Create the dispatch
             Dispatch<SOAPMessage> dispatch = createDispatch();
@@ -193,7 +199,7 @@
             
             try {
                 // Dispatch
-                TestLogger.logger.debug(">> Invoking SourceMessageProviderDispatch");
+                TestLogger.logger.debug(">> Invoking SOAPMessageProviderDispatch");
                 SOAPMessage response = dispatch.invoke(request);
                 assertTrue("Expected failure", false);
             } catch (SOAPFaultException e) {
@@ -216,7 +222,7 @@
      * Sends an SOAPMessage containing only xml data 
      * Provider will throw a generic WebServicesException
      */
-    public void testProviderWebServiceException() throws Exception {
+    public void testProviderSOAPMessageWebServiceException() throws Exception {
              
             // Create the dispatch
             Dispatch<SOAPMessage> dispatch = createDispatch();
@@ -232,7 +238,7 @@
             
             try {
                 // Dispatch
-                TestLogger.logger.debug(">> Invoking SourceMessageProviderDispatch");
+                TestLogger.logger.debug(">> Invoking SOAPMessageProviderDispatch");
                 SOAPMessage response = dispatch.invoke(request);
                 assertTrue("Expected failure", false);
             } catch (SOAPFaultException e) {
@@ -248,7 +254,7 @@
      * Receives a response containing xml data and the same raw attachments.
      */
     
-    public void testProviderSourceRawAttachment(){
+    public void testProviderSOAPMessageRawAttachment(){
         // Raw Attachments are attachments that are not referenced in the xml with MTOM or SWARef.
         // Currently there is no support in Axis 2 for these kinds of attachments.
         // The belief is that most customers will use MTOM.  Some legacy customers will use SWARef.
@@ -267,12 +273,9 @@
             AttachmentPart ap = request.createAttachmentPart(SoapMessageProvider.TEXT_XML_ATTACHMENT, "text/xml");
             ap.setContentId(SoapMessageProvider.ID);
             request.addAttachmentPart(ap);
-
-            TestLogger.logger.debug("Request Message:");
-            request.writeTo(System.out);
             
             // Dispatch
-            TestLogger.logger.debug(">> Invoking SourceMessageProviderDispatch");
+            TestLogger.logger.debug(">> Invoking SOAPMessageProviderDispatch");
             SOAPMessage response = dispatch.invoke(request);
 
             // Check assertions and get the data element
@@ -290,7 +293,6 @@
             
             // Print out the response
             TestLogger.logger.debug(">> Response [" + response.toString() + "]");
-            response.writeTo(System.out);
             
         }catch(Exception e){
             e.printStackTrace();
@@ -303,7 +305,7 @@
      * Sends an SOAPMessage containing xml data and mtom attachment.  
      * Receives a response containing xml data and the mtom attachment.
      */
-    public void testProviderSourceMTOM(){
+    public void testProviderSOAPMessageMTOM(){
         try{       
             // Create the dispatch
             Dispatch<SOAPMessage> dispatch = createDispatch();
@@ -323,12 +325,9 @@
             AttachmentPart ap = request.createAttachmentPart(SoapMessageProvider.TEXT_XML_ATTACHMENT, "text/xml");
             ap.setContentId(SoapMessageProvider.ID);
             request.addAttachmentPart(ap);
-
-            TestLogger.logger.debug("Request Message:");
-            request.writeTo(System.out);
             
             // Dispatch
-            TestLogger.logger.debug(">> Invoking SourceMessageProviderDispatch");
+            TestLogger.logger.debug(">> Invoking SOAPMessageProviderDispatch");
             SOAPMessage response = dispatch.invoke(request);
 
             // Check assertions and get the data element
@@ -346,7 +345,6 @@
             
             // Print out the response
             TestLogger.logger.debug(">> Response [" + response.toString() + "]");
-            response.writeTo(System.out);
             
         }catch(Exception e){
             e.printStackTrace();
@@ -359,7 +357,7 @@
      * Sends an SOAPMessage containing xml data and a swaref attachment to the web service.  
      * Receives a response containing xml data and the swaref attachment attachment.
      */
-    public void testProviderSourceSWARef(){
+    public void testProviderSOAPMessageSWARef(){
         try{       
             // Create the dispatch
             Dispatch<SOAPMessage> dispatch = createDispatch();
@@ -374,12 +372,9 @@
             AttachmentPart ap = request.createAttachmentPart(SoapMessageProvider.TEXT_XML_ATTACHMENT, "text/xml");
             ap.setContentId(SoapMessageProvider.ID);
             request.addAttachmentPart(ap);
-
-            TestLogger.logger.debug("Request Message:");
-            request.writeTo(System.out);
             
             // Dispatch
-            TestLogger.logger.debug(">> Invoking SourceMessageProviderDispatch");
+            TestLogger.logger.debug(">> Invoking SOAPMessageProviderDispatch");
             SOAPMessage response = dispatch.invoke(request);
 
             // Check assertions and get the data element
@@ -398,7 +393,6 @@
             
             // Print out the response
             TestLogger.logger.debug(">> Response [" + response.toString() + "]");
-            response.writeTo(System.out);
             
         }catch(Exception e){
             e.printStackTrace();
@@ -422,6 +416,148 @@
             e.printStackTrace();
         }
     }
+    
+    /**
+     * Sends an String payload containing only xml data to the Provider<SOAPMessage>
+     * The header information is sent using a jaxws.request.soap.header Map  
+     * Receives a response containing xml data
+     */
+    public void testProviderSOAPMessage_RequestHeaders(){
+        try{       
+            // Create the dispatch
+            Dispatch<String> dispatch = createStringDispatch();
+             
+            // Create the String Payload
+            String request = CHECKHEADERS_INVOKE;
+            MessageFactory factory = MessageFactory.newInstance();
+            
+            // Create the request headers
+            Map<String, Object> requestContext = dispatch.getRequestContext();
+            Map<QName, List<String>> requestHeaders = new HashMap<QName, List<String>>();
+            
+            SOAPFactory sf = SOAPFactory.newInstance();
+            SOAPElement e = sf.createElement(SoapMessageProvider.FOO_HEADER_QNAME);
+            e.addTextNode(SoapMessageProvider.FOO_HEADER_CONTENT);
+            String fooHeader = e.toString();
+            TestLogger.logger.debug("Foo Header:" + fooHeader);
+            List<String> list = new ArrayList<String>();
+            list.add(fooHeader);
+            requestHeaders.put(SoapMessageProvider.FOO_HEADER_QNAME, list);
+            
+            list = new ArrayList<String>();
+            e = sf.createElement(SoapMessageProvider.BAR_HEADER_QNAME);
+            e.addTextNode(SoapMessageProvider.BAR_HEADER_CONTENT1);
+            String barHeader = e.toString();
+            
+            TestLogger.logger.debug("Bar Header:" + barHeader);
+            list.add(barHeader);
+            e = sf.createElement(SoapMessageProvider.BAR_HEADER_QNAME);
+            e.addTextNode(SoapMessageProvider.BAR_HEADER_CONTENT2);
+            barHeader = e.toString();
+            
+            TestLogger.logger.debug("Bar Header:" + barHeader);
+            list.add(barHeader);
+            
+            
+            requestHeaders.put(SoapMessageProvider.BAR_HEADER_QNAME, list);
+            requestContext.put(Constants.JAXWS_OUTBOUND_SOAP_HEADERS, requestHeaders);
+            
+            // Dispatch
+            TestLogger.logger.debug(">> Invoking SOAPMessageProviderDispatch");
+            String response = dispatch.invoke(request);
+            
+            // Check assertions and get the data element
+            assertTrue(response.contains(SoapMessageProvider.XML_CHECKHEADERS_RESPONSE));
+            
+            // Print out the response
+            TestLogger.logger.debug(">> Response [" + response + "]");
+                
+        }catch(Exception e){
+            e.printStackTrace();
+            fail("Caught exception " + e);
+        }
+        
+    }
+    
+    /**
+     * Sends an String payload containing only xml data to the Provider<SOAPMessage>
+     * The header information is sent using a jaxws.request.soap.header Map  
+     * Receives a response containing xml data
+     */
+    public void testProviderSOAPMessage_RequestAndResponseHeaders(){
+        try{       
+            // Create the dispatch
+            Dispatch<String> dispatch = createStringDispatch();
+             
+            // Create the String Payload
+            String request = CHECKHEADERS_INVOKE;
+            MessageFactory factory = MessageFactory.newInstance();
+            
+            // Create the request headers
+            Map<String, Object> requestContext = dispatch.getRequestContext();
+            Map<QName, List<String>> requestHeaders = new HashMap<QName, List<String>>();
+            
+            SOAPFactory sf = SOAPFactory.newInstance();
+            SOAPElement e = sf.createElement(SoapMessageProvider.FOO_HEADER_QNAME);
+            e.addTextNode(SoapMessageProvider.FOO_HEADER_CONTENT);
+            String fooHeader = e.toString();
+            TestLogger.logger.debug("Foo Header:" + fooHeader);
+            List<String> list = new ArrayList<String>();
+            list.add(fooHeader);
+            requestHeaders.put(SoapMessageProvider.FOO_HEADER_QNAME, list);
+            
+            list = new ArrayList<String>();
+            e = sf.createElement(SoapMessageProvider.BAR_HEADER_QNAME);
+            e.addTextNode(SoapMessageProvider.BAR_HEADER_CONTENT1);
+            String barHeader = e.toString();
+            
+            TestLogger.logger.debug("Bar Header:" + barHeader);
+            list.add(barHeader);
+            e = sf.createElement(SoapMessageProvider.BAR_HEADER_QNAME);
+            e.addTextNode(SoapMessageProvider.BAR_HEADER_CONTENT2);
+            barHeader = e.toString();
+            
+            TestLogger.logger.debug("Bar Header:" + barHeader);
+            list.add(barHeader);
+            
+            requestHeaders.put(SoapMessageProvider.BAR_HEADER_QNAME, list);
+            requestContext.put(Constants.JAXWS_OUTBOUND_SOAP_HEADERS, requestHeaders);
+            
+            // Dispatch
+            TestLogger.logger.debug(">> Invoking SOAPMessageProviderDispatch");
+            String response = dispatch.invoke(request);
+            
+            // Check assertions and get the data element
+            assertTrue(response.contains(SoapMessageProvider.XML_CHECKHEADERS_RESPONSE));
+            
+            // Check outbound headers
+            Map<String, Object> responseContext = dispatch.getResponseContext();
+            assertTrue(responseContext != null);
+            Map<QName, List<String>> responseHeaders = (Map<QName, List<String>>) 
+                responseContext.get(Constants.JAXWS_INBOUND_SOAP_HEADERS);
+            assertTrue(responseHeaders != null);
+            assertTrue(responseHeaders.size() >= 2);
+            List<String> batHeaders = responseHeaders.get(SoapMessageProvider.BAT_HEADER_QNAME);
+            assertTrue(batHeaders != null && batHeaders.size() == 1);
+            assertTrue(batHeaders.get(0).contains(SoapMessageProvider.BAT_HEADER_CONTENT));
+            List<String> barHeaders =responseHeaders.get(SoapMessageProvider.BAR_HEADER_QNAME);
+            assertTrue(barHeaders != null &&  barHeaders.size() == 2);
+            assertTrue(barHeaders.get(0).contains(SoapMessageProvider.BAR_HEADER_CONTENT1));
+            assertTrue(barHeaders.get(1).contains(SoapMessageProvider.BAR_HEADER_CONTENT2));
+            
+            // There should be no foo header in the response
+            List<String> fooHeaders = responseHeaders.get(SoapMessageProvider.FOO_HEADER_QNAME);
+            assertTrue(fooHeaders == null);
+            
+            // Print out the response
+            TestLogger.logger.debug(">> Response [" + response + "]");
+                
+        }catch(Exception e){
+            e.printStackTrace();
+            fail("Caught exception " + e);
+        }
+        
+    }
 
     /**
      * @return
@@ -434,6 +570,20 @@
         svc.addPort(portName,null, endpointUrl);
         Dispatch<SOAPMessage> dispatch = 
         	svc.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE);
+        return dispatch;
+    }
+    
+    /**
+     * @return
+     * @throws Exception
+     */
+    private Dispatch<String> createStringDispatch() throws Exception {
+        
+        
+        Service svc = Service.create(serviceName);
+        svc.addPort(portName,null, endpointUrl);
+        Dispatch<String> dispatch = 
+                svc.createDispatch(portName, String.class, Service.Mode.PAYLOAD);
         return dispatch;
     }
     

Modified: webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/soapmsg/SoapMessageProvider.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/soapmsg/SoapMessageProvider.java?rev=645154&r1=645153&r2=645154&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/soapmsg/SoapMessageProvider.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws-integration/test/org/apache/axis2/jaxws/provider/soapmsg/SoapMessageProvider.java Sat Apr  5 11:05:22 2008
@@ -32,6 +32,8 @@
 import javax.xml.soap.SOAPElement;
 import javax.xml.soap.SOAPFactory;
 import javax.xml.soap.SOAPFault;
+import javax.xml.soap.SOAPHeader;
+import javax.xml.soap.SOAPHeaderElement;
 import javax.xml.soap.SOAPMessage;
 import javax.xml.transform.Result;
 import javax.xml.transform.Transformer;
@@ -71,6 +73,8 @@
     public static String XML_REQUEST              = "xml request";
     public static String XML_RESPONSE             = "xml response";
     public static String XML_EMPTYBODY_REQUEST    = "xml empty body request";
+    public static String XML_CHECKHEADERS_REQUEST = "xml check headers request";
+    public static String XML_CHECKHEADERS_RESPONSE= "xml check headers response";
     public static String XML_ATTACHMENT_REQUEST   = "xml and attachment request";
     public static String XML_ATTACHMENT_RESPONSE  = "xml and attachment response";
     public static String XML_MTOM_REQUEST         = "xml and mtom request";
@@ -96,6 +100,10 @@
         "</return_str>" + 
         SoapMessageProvider.SWAREF_REF +
         "</ns2:ReturnType>";     
+    private String CHECKHEADERS_RETURN = "<ns2:ReturnType xmlns:ns2=\"http://test\"><return_str>" + 
+        SoapMessageProvider.XML_CHECKHEADERS_RESPONSE +
+        "</return_str>" + 
+        "</ns2:ReturnType>";     
     
     public static String TEXT_XML_ATTACHMENT = "<myAttachment>Hello World</myAttachment>";
     public static String ID = "helloWorld123";
@@ -107,7 +115,14 @@
         "cid:" + ID +
         "</data>";
     
+    public static final QName FOO_HEADER_QNAME = new QName("http://sample1", "foo", "pre1");
+    public static final QName BAR_HEADER_QNAME = new QName("http://sample2", "bar", "pre2");
+    public static final QName BAT_HEADER_QNAME = new QName("http://sample3", "bat", "pre3");
     
+    public static final String FOO_HEADER_CONTENT = "foo content";
+    public static final String BAR_HEADER_CONTENT1 = "bar content1";
+    public static final String BAR_HEADER_CONTENT2 = "bar content2";
+    public static final String BAT_HEADER_CONTENT = "bat content";
     
     public SOAPMessage invoke(SOAPMessage soapMessage) throws SOAPFaultException {
         TestLogger.logger.debug(">> SoapMessageProvider: Request received.");
@@ -130,6 +145,8 @@
                 response = getXMLResponse(soapMessage, discElement);
             } else if (XML_EMPTYBODY_REQUEST.equals(text)) {
                 response = getXMLEmptyBodyResponse(soapMessage, discElement);
+            } else if (XML_CHECKHEADERS_REQUEST.equals(text)) {
+                response = getXMLCheckHeadersResponse(soapMessage, discElement);
             } else if (XML_ATTACHMENT_REQUEST.equals(text)) {
                 response = getXMLAttachmentResponse(soapMessage, discElement);
             } else if (XML_MTOM_REQUEST.equals(text)) {
@@ -230,6 +247,59 @@
         MessageFactory factory = MessageFactory.newInstance();
         response = factory.createMessage();
      
+        return response;
+    }
+    
+    /**
+     * Get the response for an XML check headers request
+     * @param request
+     * @param dataElement
+     * @return SOAPMessage
+     */
+    private SOAPMessage getXMLCheckHeadersResponse(SOAPMessage request, 
+                                                   SOAPElement dataElement) throws Exception {
+        SOAPMessage response;
+        
+        // Additional assertion checks
+        assertTrue(countAttachments(request) == 0);
+        
+        // Check for specific headers
+        SOAPHeader sh = request.getSOAPHeader();
+        assertTrue(sh != null);
+        
+        SOAPHeaderElement she = (SOAPHeaderElement)
+            sh.getChildElements(FOO_HEADER_QNAME).next();
+        assertTrue(she != null);
+        assertTrue(she instanceof SOAPHeaderElement);
+        String text = she.getValue();
+        assertTrue(FOO_HEADER_CONTENT.equals(text));
+        
+        Iterator it = sh.getChildElements(BAR_HEADER_QNAME);
+        she = (SOAPHeaderElement) it.next();
+        assertTrue(she != null);
+        assertTrue(she instanceof SOAPHeaderElement);
+        text = she.getValue();
+        assertTrue(BAR_HEADER_CONTENT1.equals(text));
+        she = (SOAPHeaderElement) it.next();
+        assertTrue(she != null);
+        assertTrue(she instanceof SOAPHeaderElement);
+        text = she.getValue();
+        assertTrue(BAR_HEADER_CONTENT2.equals(text));
+        
+        assertTrue(!sh.getChildElements(BAT_HEADER_QNAME).hasNext());
+   
+        
+        // Build the Response
+        MessageFactory factory = MessageFactory.newInstance();
+        String responseXML = responseMsgStart + CHECKHEADERS_RETURN + responseMsgEnd;
+        response = factory.createMessage(null, new ByteArrayInputStream(responseXML.getBytes()));
+        response.getSOAPHeader().addHeaderElement(BAR_HEADER_QNAME).
+            addTextNode(BAR_HEADER_CONTENT1);
+        response.getSOAPHeader().addHeaderElement(BAR_HEADER_QNAME).
+            addTextNode(BAR_HEADER_CONTENT2);
+        response.getSOAPHeader().addHeaderElement(BAT_HEADER_QNAME).
+            addTextNode(BAT_HEADER_CONTENT);
+        
         return response;
     }
     

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java?rev=645154&r1=645153&r2=645154&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java Sat Apr  5 11:05:22 2008
@@ -26,4 +26,9 @@
 public interface Constants {
     public static final String ENDPOINT_CONTEXT_MAP =
         "org.apache.axis2.jaxws.addressing.util.EndpointContextMap";
+    
+    public static final String JAXWS_OUTBOUND_SOAP_HEADERS  = 
+        org.apache.axis2.Constants.JAXWS_OUTBOUND_SOAP_HEADERS;
+    public static final String JAXWS_INBOUND_SOAP_HEADERS   = 
+        org.apache.axis2.Constants.JAXWS_INBOUND_SOAP_HEADERS;
 }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/client/async/AsyncResponse.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/client/async/AsyncResponse.java?rev=645154&r1=645153&r2=645154&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/client/async/AsyncResponse.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/client/async/AsyncResponse.java Sat Apr  5 11:05:22 2008
@@ -26,6 +26,7 @@
 import org.apache.axis2.jaxws.handler.AttachmentsAdapter;
 import org.apache.axis2.jaxws.handler.HandlerChainProcessor;
 import org.apache.axis2.jaxws.handler.HandlerInvokerUtils;
+import org.apache.axis2.jaxws.handler.SOAPHeadersAdapter;
 import org.apache.axis2.jaxws.handler.TransportHeadersAdapter;
 import org.apache.axis2.jaxws.i18n.Messages;
 import org.apache.axis2.jaxws.message.attachments.AttachmentUtils;
@@ -303,6 +304,7 @@
             // Install the adapters and invoke inbound handlers.
             TransportHeadersAdapter.install(response);
             AttachmentsAdapter.install(response);
+            SOAPHeadersAdapter.install(response);
             HandlerInvokerUtils.invokeInboundHandlers(response.getMEPContext(),
                                                       response.getInvocationContext().getHandlers(),
                                                       HandlerChainProcessor.MEP.RESPONSE,

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/impl/InvocationControllerImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/impl/InvocationControllerImpl.java?rev=645154&r1=645153&r2=645154&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/impl/InvocationControllerImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/impl/InvocationControllerImpl.java Sat Apr  5 11:05:22 2008
@@ -28,6 +28,7 @@
 import org.apache.axis2.jaxws.handler.AttachmentsAdapter;
 import org.apache.axis2.jaxws.handler.HandlerChainProcessor;
 import org.apache.axis2.jaxws.handler.HandlerInvokerUtils;
+import org.apache.axis2.jaxws.handler.SOAPHeadersAdapter;
 import org.apache.axis2.jaxws.handler.TransportHeadersAdapter;
 import org.apache.axis2.jaxws.i18n.Messages;
 import org.apache.axis2.jaxws.util.Constants;
@@ -104,6 +105,7 @@
             // Invoke inbound handlers.
             TransportHeadersAdapter.install(response);
             AttachmentsAdapter.install(response);
+            SOAPHeadersAdapter.install(response);
             HandlerInvokerUtils.invokeInboundHandlers(response.getMEPContext(),
                                                       ic.getHandlers(),
                                                       HandlerChainProcessor.MEP.RESPONSE,

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/BaseMessageContext.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/BaseMessageContext.java?rev=645154&r1=645153&r2=645154&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/BaseMessageContext.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/BaseMessageContext.java Sat Apr  5 11:05:22 2008
@@ -50,6 +50,7 @@
         // MessageContext Attachments implementation.
         AttachmentsAdapter.install(messageCtx);
         TransportHeadersAdapter.install(messageCtx);
+        SOAPHeadersAdapter.install(messageCtx);
     }
 
     /* (non-Javadoc)

Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/SOAPHeadersAdapter.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/SOAPHeadersAdapter.java?rev=645154&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/SOAPHeadersAdapter.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/SOAPHeadersAdapter.java Sat Apr  5 11:05:22 2008
@@ -0,0 +1,252 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.axis2.jaxws.handler;
+
+import org.apache.axis2.jaxws.Constants;
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.core.MessageContext;
+import org.apache.axis2.jaxws.message.Block;
+import org.apache.axis2.jaxws.message.Message;
+import org.apache.axis2.jaxws.message.factory.XMLStringBlockFactory;
+import org.apache.axis2.jaxws.registry.FactoryRegistry;
+import org.apache.axis2.jaxws.utility.JavaUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.xml.namespace.QName;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The JAX-WS exposes soap header properties whose value is Map<QName, List<String>>.  The
+ * QName is the name of the header and List<String> are the xml values of the headers for qname.
+ * 
+ * The JAX-WS MessageContext stores soap headers in an Axiom tree object located on the JAX-WS 
+ * Message.
+ * 
+ * This class, SOAPHeadersAdapter, is an adapter between the Map<QName, List<String>> interface needed
+ * by the properties and the actual implementation.  All useful function is delegated through the MessageContext, so 
+ * that we only have one copy of the soap header information.  
+ * 
+ * To use this class, invoke the install method.  This will create an SOAPHeaderAdapter (if necessary) and install it
+ * on to provide the JAX-WS soap headers property.  (See BaseMessageContext.)
+ */
+public class SOAPHeadersAdapter implements Map<QName, List<String>> {
+
+    private static final Log log = LogFactory.getLog(SOAPHeadersAdapter.class);
+    
+    private MessageContext mc;     // MessageContext which provides the backing implementation of Attachments
+    private boolean isOutbound;    // IsOutbound
+    private String property;
+    
+    /**
+     * Add the AttachmentAdapter as the property for the inbound and/or
+     * outbound attachment property
+     * @param mc MessageContext
+     */
+    public static void install(MessageContext mc) {
+        
+        Message m = mc.getMessage();
+        
+        if (m == null) {
+            // Probably a unit test, can't continue.
+            return;
+        }
+        
+        boolean isOutbound = mc.isOutbound();
+       
+        if (log.isDebugEnabled()) {
+            log.debug("Installing SOAPHeadersAdapter: " + 
+                      JavaUtils.callStackToString());
+        }
+        
+        String property = (isOutbound) ? 
+                Constants.JAXWS_OUTBOUND_SOAP_HEADERS :
+                    Constants.JAXWS_INBOUND_SOAP_HEADERS;
+        
+        // See if there is an existing map
+        Object map = mc.getProperty(property);
+
+        // Reuse existing Adapter
+        if (map instanceof SOAPHeadersAdapter) {
+            if (log.isDebugEnabled()) {
+                log.debug("A SOAPHeadersAdapter is already installed.  Reusing the existing one.");
+            }
+            return;
+        } 
+      
+        // Create a new AttachmentsAdapter and set it on the property 
+        SOAPHeadersAdapter sha = 
+            new SOAPHeadersAdapter(mc, 
+                                   isOutbound);
+
+        if (map != null) {
+            // Copy the existing Map contents to this new adapter
+            sha.putAll((Map<QName, List<String>>) map);
+        }
+        mc.setProperty(property, sha);
+    }
+
+    /**
+     * The backing storage of the Attachments is the JAX-WS MessageContext.
+     * Intentionally private, use install(MessageContext)
+     */
+    private SOAPHeadersAdapter(MessageContext mc, 
+                               boolean isOutbound) {
+        this.mc = mc;
+        this.isOutbound = isOutbound;
+        this.property = (isOutbound) ? 
+                    Constants.JAXWS_OUTBOUND_SOAP_HEADERS :
+                    Constants.JAXWS_INBOUND_SOAP_HEADERS;
+        
+        if (log.isDebugEnabled()) {
+            log.debug("Init SOAPHeadersAdapter for " + property);
+        }
+    }
+    
+
+    public void clear() {
+        // Throw unsupported operation exception per Map javadoc
+        // for any method that is not supported.
+        throw new UnsupportedOperationException();
+    }
+    
+    public boolean containsKey(Object key) {
+        Set<QName> keys = this.keySet();
+        return keys.contains(key);
+    }
+    
+    public boolean containsValue(Object value) {
+        Set<QName> keys = this.keySet();
+        for(QName key: keys) {
+            List<String> tryValue = get(key);
+
+            if (tryValue == value ||
+                value.equals(tryValue)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    public Set<Entry<QName, List<String>>> entrySet() {
+        Map<QName, List<String>> tempMap = new HashMap<QName, List<String>>();
+        tempMap.putAll(this);
+        return tempMap.entrySet();
+    }
+    
+    public List<String> get(Object _key) {
+        try {
+            if (!(keySet().contains(_key))) {
+                return null;
+            }
+            QName key = (QName) _key;
+            Message m = mc.getMessage();
+            List<Block> blocks = m.getHeaderBlocks(key.getNamespaceURI(), 
+                                                   key.getLocalPart(),
+                                                   null,
+                                                   getXMLStringBlockFactory(),
+                                                   null);
+            if (blocks == null || blocks.size() == 0) {
+                return null;
+            }
+            
+            // Get the strings from the blocks
+            ArrayList<String> xmlStrings = new ArrayList<String>();
+            for (int i=0; i<blocks.size(); i++) {
+                Block block = blocks.get(i);
+                String value = (block == null) ? null : (String) block.getBusinessObject(false);
+                xmlStrings.add(value);
+            }
+            
+            return xmlStrings;
+        } catch (Throwable t) {
+            throw ExceptionFactory.makeWebServiceException(t);
+        }
+    }
+    
+    public boolean isEmpty() {
+        return this.keySet().isEmpty();
+    }
+    
+    public Set<QName> keySet() {
+        Message m = mc.getMessage();
+        return m.getHeaderQNames();
+    }
+    
+    public List<String> put(QName key, List<String> values) {
+        Message m = mc.getMessage();
+        if (log.isDebugEnabled()) {
+            log.debug("put(" + key + " , " + values + ")");
+        }
+        // Get the old value
+        List<String> old = get(key);
+        
+        if (values != null) {
+            if (old != null) {
+                // Replace the existing header blocks
+                m.removeHeaderBlock(key.getNamespaceURI(), key.getLocalPart());
+            }
+            for (int i=0; i < values.size(); i++) {
+                String value = values.get(i);
+                Block block = getXMLStringBlockFactory().createFrom(value, null, key);
+                m.appendHeaderBlock(key.getNamespaceURI(), key.getLocalPart(), block);
+            }
+        }
+        
+        return old;
+        
+    }
+    
+    public void putAll(Map<? extends QName, ? extends List<String>> t) {
+        for(Entry<? extends QName, ? extends List<String>> entry: t.entrySet()) {
+            QName key = entry.getKey();
+            List<String> value = entry.getValue();  
+            put(key, value);
+        }
+    }
+    
+    public List<String> remove(Object key) {
+        // Throw unsupported operation exception per Map javadoc
+        // for any method that is not supported.
+        throw new UnsupportedOperationException();
+    }
+    
+    public int size() {
+        return this.keySet().size();
+    }
+    
+    public Collection<List<String>> values() {
+        Map<QName, List<String>> tempMap = new HashMap<QName, List<String>>();
+        tempMap.putAll(this);
+        return tempMap.values();
+    }
+    
+    private XMLStringBlockFactory getXMLStringBlockFactory() {
+        return (XMLStringBlockFactory)
+            FactoryRegistry.getFactory(XMLStringBlockFactory.class);
+    }
+
+}

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/XMLPart.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/XMLPart.java?rev=645154&r1=645153&r2=645154&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/XMLPart.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/XMLPart.java Sat Apr  5 11:05:22 2008
@@ -31,6 +31,7 @@
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.ws.WebServiceException;
 import java.util.List;
+import java.util.Set;
 
 
 /**
@@ -301,8 +302,9 @@
             throws WebServiceException;
 
     /**
-     * appendHeaderBlock Append the block to the list of header blocks. The Message owns the block.
-     * You must use the getHeaderBlock method to access it.
+     * setHeaderBlock 
+     * replaces the first existing header block with this new block.  If there is no
+     * existing header block, one is added to the end of the headers
      *
      * @param namespace
      * @param localPart
@@ -311,9 +313,28 @@
      */
     public void setHeaderBlock(String namespace, String localPart, Block block)
             throws WebServiceException;
+    
+    /**
+     * appendHeaderBlock 
+     * Append the block to the list of header blocks. The Message owns the block.
+     * You must use the getHeaderBlock method to access it.
+     *
+     * @param namespace
+     * @param localPart
+     * @param block
+     * @throws WebServiceException
+     */
+    public void appendHeaderBlock(String namespace, String localPart, Block block)
+            throws WebServiceException;
 
     /**
-     * removePayload Removes the indicated block
+     * @return QNames of headers
+     */
+    public Set<QName> getHeaderQNames();
+    
+    /**
+     * removeHeaderBlock
+     * Removes all header blocks with this namespace/localpart
      *
      * @param namespace
      * @param localPart

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java?rev=645154&r1=645153&r2=645154&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java Sat Apr  5 11:05:22 2008
@@ -63,6 +63,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * MessageImpl
@@ -460,6 +461,11 @@
         xmlPart.setHeaderBlock(namespace, localPart, block);
     }
     
+    public void appendHeaderBlock(String namespace, String localPart, Block block) 
+    throws WebServiceException {
+        xmlPart.appendHeaderBlock(namespace, localPart, block);
+    }
+    
     public String traceString(String indent) {
         return xmlPart.traceString(indent);
     }
@@ -634,8 +640,12 @@
     
     public void close() {
         if (xmlPart != null) {
-              xmlPart.close();
+            xmlPart.close();
         }
-     }
+    }
+
+    public Set<QName> getHeaderQNames() {
+        return (xmlPart == null) ? null : xmlPart.getHeaderQNames();     
+    }
 
 }

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLPartBase.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLPartBase.java?rev=645154&r1=645153&r2=645154&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLPartBase.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLPartBase.java Sat Apr  5 11:05:22 2008
@@ -45,12 +45,16 @@
 import javax.xml.soap.SOAPElement;
 import javax.xml.soap.SOAPEnvelope;
 import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPHeader;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.ws.WebServiceException;
+
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
 
 /**
@@ -535,7 +539,54 @@
         return block;
     }
     
-    
+    public Set<QName> getHeaderQNames() {
+        try {
+            switch (contentType) {
+                case OM: {
+                    HashSet<QName> qnames = new HashSet<QName>();
+                    OMElement om = this.getAsOMElement();
+                    if (om instanceof org.apache.axiom.soap.SOAPEnvelope) {
+                        org.apache.axiom.soap.SOAPEnvelope se =
+                            (org.apache.axiom.soap.SOAPEnvelope) om;
+                        org.apache.axiom.soap.SOAPHeader header = se.getHeader();
+                        if (header != null) {
+                            Iterator it = header.getChildElements(); 
+                            while (it != null && it.hasNext()) {
+                                Object node = it.next();
+                                if (node instanceof OMElement) {
+                                    qnames.add(((OMElement) node).getQName());
+                                }
+                            }
+                        }
+                    }
+                    return qnames;
+                }
+                case SOAPENVELOPE: {
+                    HashSet<QName> qnames = new HashSet<QName>();
+                    SOAPEnvelope se = this.getContentAsSOAPEnvelope();
+                    if (se != null) {
+                        SOAPHeader header = se.getHeader();
+                        if (header != null) {
+                            Iterator it = header.getChildElements(); 
+                            while (it != null && it.hasNext()) {
+                                Object node = it.next();
+                                if (node instanceof SOAPElement) {
+                                    qnames.add(((SOAPElement) node).getElementQName());
+                                }
+                            }
+                        }
+                    }
+                    return qnames;
+                }
+                case SPINE:
+                    return getContentAsXMLSpine().getHeaderQNames();
+                default:
+                    return null;
+            }
+        } catch (SOAPException se) {
+            throw ExceptionFactory.makeWebServiceException(se);
+        }
+    }
 
     public List<Block> getHeaderBlocks(String namespace, String localPart, 
                                       Object context, BlockFactory blockFactory, 
@@ -602,6 +653,12 @@
             throws WebServiceException {
         block.setParent(getParent());
         getContentAsXMLSpine().setHeaderBlock(namespace, localPart, block);
+    }
+    
+    public void appendHeaderBlock(String namespace, String localPart, Block block)
+    throws WebServiceException {
+        block.setParent(getParent());
+        getContentAsXMLSpine().appendHeaderBlock(namespace, localPart, block);
     }
 
     /*

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpine.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpine.java?rev=645154&r1=645153&r2=645154&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpine.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpine.java Sat Apr  5 11:05:22 2008
@@ -34,6 +34,7 @@
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.ws.WebServiceException;
 import java.util.List;
+import java.util.Set;
 
 /**
  * XMLSpine
@@ -237,8 +238,9 @@
             throws WebServiceException;
 
     /**
-     * appendHeaderBlock Append the block to the list of header blocks. The Message owns the block.
-     * You must use the getHeaderBlock method to access it.
+     * setHeaderBlock 
+     * replaces the first existing header block with this new block.  If there is no
+     * existing header block, one is added to the end of the headers
      *
      * @param namespace
      * @param localPart
@@ -249,7 +251,25 @@
             throws WebServiceException;
 
     /**
-     * removePayload Removes the indicated block
+     * appendHeaderBlock 
+     * Append the block to the list of header blocks. The Message owns the block.
+     * You must use the getHeaderBlock method to access it.
+     *
+     * @param namespace
+     * @param localPart
+     * @param block
+     * @throws WebServiceException
+     */
+    public void appendHeaderBlock(String namespace, String localPart, Block block)
+        throws WebServiceException;
+    /**
+     * @return Set of QNames
+     */
+    public Set<QName> getHeaderQNames();
+    
+    /**
+     * removePayload 
+     * Removes all header blocks with this namespace/localpart
      *
      * @param namespace
      * @param localPart

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java?rev=645154&r1=645153&r2=645154&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java Sat Apr  5 11:05:22 2008
@@ -61,8 +61,10 @@
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.ws.WebServiceException;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
 /**
  * XMLSpineImpl
@@ -462,6 +464,21 @@
         return blocks;
     }
 
+    public Set<QName> getHeaderQNames() {
+        HashSet<QName> qnames = new HashSet<QName>();
+        SOAPHeader header = root.getHeader();
+        if (header != null) {
+            Iterator it = header.getChildElements(); 
+            while (it != null && it.hasNext()) {
+                Object node = it.next();
+                if (node instanceof OMElement) {
+                    qnames.add(((OMElement) node).getQName());
+                }
+            }
+        }
+        return qnames;
+    }
+    
     public void setHeaderBlock(String namespace, String localPart, Block block)
             throws WebServiceException {
         block.setParent(getParent());
@@ -479,12 +496,25 @@
             om.detach();
         }
     }
+    
+    public void appendHeaderBlock(String namespace, String localPart, Block block)
+    throws WebServiceException {
+        block.setParent(getParent());
+        OMNamespace ns = soapFactory.createOMNamespace(namespace, null);
+        OMElement newOM =
+            _createOMElementFromBlock(localPart, ns, block, soapFactory, true);
+        if (root.getHeader() == null) {
+            soapFactory.createSOAPHeader(root);
+        }
+        root.getHeader().addChild(newOM);
+    }
 
 
     public void removeHeaderBlock(String namespace, String localPart) throws WebServiceException {
         OMElement om = this._getChildOMElement(root.getHeader(), namespace, localPart);
-        if (om != null) {
+        while (om != null) {
             om.detach();
+            om = this._getChildOMElement(root.getHeader(), namespace, localPart);
         }
     }
 

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/util/MessageUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/util/MessageUtils.java?rev=645154&r1=645153&r2=645154&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/util/MessageUtils.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/util/MessageUtils.java Sat Apr  5 11:05:22 2008
@@ -39,6 +39,7 @@
 import org.apache.axis2.context.OperationContext;
 import org.apache.axis2.jaxws.ExceptionFactory;
 import org.apache.axis2.jaxws.handler.AttachmentsAdapter;
+import org.apache.axis2.jaxws.handler.SOAPHeadersAdapter;
 import org.apache.axis2.jaxws.handler.TransportHeadersAdapter;
 import org.apache.axis2.jaxws.i18n.Messages;
 import org.apache.axis2.jaxws.message.Message;
@@ -212,6 +213,7 @@
         if (message.getMessageContext() != null) {
             AttachmentsAdapter.install(message.getMessageContext());
             TransportHeadersAdapter.install(message.getMessageContext());
+            SOAPHeadersAdapter.install(message.getMessageContext());
         }
         
         if (message.isDoingSWA()) {

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java?rev=645154&r1=645153&r2=645154&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java Sat Apr  5 11:05:22 2008
@@ -36,6 +36,7 @@
 import org.apache.axis2.jaxws.description.ServiceDescription;
 import org.apache.axis2.jaxws.handler.AttachmentsAdapter;
 import org.apache.axis2.jaxws.handler.MEPContext;
+import org.apache.axis2.jaxws.handler.SOAPHeadersAdapter;
 import org.apache.axis2.jaxws.handler.TransportHeadersAdapter;
 import org.apache.axis2.jaxws.i18n.Messages;
 import org.apache.axis2.jaxws.message.util.MessageUtils;
@@ -133,6 +134,7 @@
             // The adapters need to be installed on the new request Message Context
             AttachmentsAdapter.install(requestMsgCtx);
             TransportHeadersAdapter.install(requestMsgCtx);
+            SOAPHeadersAdapter.install(requestMsgCtx);
             
             Binding binding = (Binding)axisRequestMsgCtx.getProperty(PARAM_BINDING);
             EndpointInvocationContext eic = InvocationContextFactory.createEndpointInvocationContext(binding);

Modified: webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/Constants.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/Constants.java?rev=645154&r1=645153&r2=645154&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/Constants.java (original)
+++ webservices/axis2/trunk/java/modules/kernel/src/org/apache/axis2/Constants.java Sat Apr  5 11:05:22 2008
@@ -274,6 +274,10 @@
      */
     public static final String UNPROCESSED_HEADER_QNAMES = "unprocessedHeaderQNames";
 
+    // Keys to access JAXWS Request and Response SOAP Headers
+    public static final String JAXWS_OUTBOUND_SOAP_HEADERS  = "jaxws.binding.soap.headers.outbound";
+    public static final String JAXWS_INBOUND_SOAP_HEADERS = "jaxws.binding.soap.headers.inbound";
+    
     public static interface Configuration {
         public static final String ENABLE_REST = "enableREST";
         public static final String ENABLE_HTTP_CONTENT_NEGOTIATION = "httpContentNegotiation";

Modified: webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPElementImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPElementImpl.java?rev=645154&r1=645153&r2=645154&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPElementImpl.java (original)
+++ webservices/axis2/trunk/java/modules/saaj/src/org/apache/axis2/saaj/SOAPElementImpl.java Sat Apr  5 11:05:22 2008
@@ -860,4 +860,8 @@
     public NamedNodeMap getAttributes() {
         return element.getAttributes();
     }
+    
+    public String toString() {
+        return element.toString();
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org