I would like to propose a change to handle certain situations in jaxws 
where we need to postpone the must understand header check from the 
AxisEngine to the MessageReceiver. For example, in case of jaxws handler, 
an application can choose to implement getHeaders() and choose to add 
valid header qnames in that implementation. A mustUnderstand validation 
needs to happen for this scenario as described in section 10.2.1 of jaxws 
specification, in this situation if the jaxws handlers are not loaded, the 
must understand checks has to be postponed from AxisEngine until the 
handler are loaded and available in jaxws implementation.

Currently all the must understand processing happens in AxisEngine's 
receive() method, I would like to provide a facility in AxisEngine code 
where we can choose to delegate MustUnderstand Check to a  Message 
Receiver. I would like to propose addition of a new interface called 
MessageReceiverExtension in Kernel module which has a method 
isMustUnderstandCheckPostponed, this new interface will be implemented by 
JAXWSMessageReceiver and will help in making the runtime decision to 
postpone must understand check in AxisEngine code. 

Attached is the patch with proposed changes.



Nikhil Thaker
office: 512 838 9964
[EMAIL PROTECTED]
Index: 
C:/webservices/rad/WSFP_GM_092507/modules/kernel/src/org/apache/axis2/Constants.java
===================================================================
--- 
C:/webservices/rad/WSFP_GM_092507/modules/kernel/src/org/apache/axis2/Constants.java
        (revision 3243)
+++ 
C:/webservices/rad/WSFP_GM_092507/modules/kernel/src/org/apache/axis2/Constants.java
        (working copy)
@@ -241,7 +241,12 @@
      * from SOAPFault to AxisFault 
      */
     public static final String INBOUND_FAULT_OVERRIDE = "inboundFaultOverride";
-
+    
+    /**
+     * This is used to store Header QNames that failed mustUnderstand check.
+     */
+    public static final String FAULTY_HEADER_QNAMES = "faultyHeaderQNames";
+    
     public static interface Configuration {
         public static final String ENABLE_REST = "enableREST";
         public static final String ENABLE_REST_THROUGH_GET = "restThroughGet";
@@ -329,6 +334,7 @@
          * @see org.apache.axis2.transport.MessageFormatter
          */
         public static final String MESSAGE_TYPE = "messageType";
+        
 
     }
 }
Index: 
C:/webservices/rad/WSFP_GM_092507/modules/kernel/src/org/apache/axis2/engine/MessageReceiverExtension.java
===================================================================
--- 
C:/webservices/rad/WSFP_GM_092507/modules/kernel/src/org/apache/axis2/engine/MessageReceiverExtension.java
  (revision 0)
+++ 
C:/webservices/rad/WSFP_GM_092507/modules/kernel/src/org/apache/axis2/engine/MessageReceiverExtension.java
  (revision 0)
@@ -0,0 +1,19 @@
+package org.apache.axis2.engine;
+/*
+ * MessageReceiverExtension will be used to add additional functionality to 
MessageReceiver.
+ * For Example MessageReceiverExtension can be used by JAXWSMessageReceiver to 
validate the 
+ * MustUnderstand Checks, We use this functionality in case a webservice uses 
jaxws handlers and
+ * that AxisEngine does not have handler instance which get loaded later in 
the webservice lifecycle.
+ *  
+ */
+public interface MessageReceiverExtension{
+    /**
+     * checkNonUnderstoodHeaderInFuture returns a true if the header 
mustUnderstand check need to be
+     * posponed till the request is received by MessageReceiver.
+     * In some instances especially in Handler processing, the handlers are 
not loaded/instantiated until the 
+     * first webservice call is made. Thus header qNames that are set in 
getHeaders()are not available to
+     * AxisEngine. We will use this method in such situations to pospone the 
MustUnderstand Check. 
+     * @return
+     */
+    public boolean 
isMustUnderstandCheckPostponed(org.apache.axis2.context.MessageContext 
axisRequestMsgCtx);
+}
Index: 
C:/webservices/rad/WSFP_GM_092507/modules/kernel/src/org/apache/axis2/engine/AxisEngine.java
===================================================================
--- 
C:/webservices/rad/WSFP_GM_092507/modules/kernel/src/org/apache/axis2/engine/AxisEngine.java
        (revision 3243)
+++ 
C:/webservices/rad/WSFP_GM_092507/modules/kernel/src/org/apache/axis2/engine/AxisEngine.java
        (working copy)
@@ -17,12 +17,19 @@
 
 package org.apache.axis2.engine;
 
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import javax.xml.namespace.QName;
+
 import org.apache.axiom.soap.SOAP11Constants;
 import org.apache.axiom.soap.SOAP12Constants;
 import org.apache.axiom.soap.SOAPConstants;
 import org.apache.axiom.soap.SOAPEnvelope;
 import org.apache.axiom.soap.SOAPHeaderBlock;
 import org.apache.axis2.AxisFault;
+import org.apache.axis2.Constants;
 import org.apache.axis2.client.async.Callback;
 import org.apache.axis2.context.ConfigurationContext;
 import org.apache.axis2.context.MessageContext;
@@ -41,12 +48,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import javax.xml.namespace.QName;
 
-import java.util.ArrayList;
-import java.util.Iterator;
-
-
 /**
  * There is one engine for the Server and the Client. the send() and receive()
  * Methods are the basic operations the Sync, Async messageing are build on 
top.
@@ -80,6 +82,15 @@
             return;
         }
         Iterator headerBlocks = envelope.getHeader().examineAllHeaderBlocks();
+        //If MustUnderstand check is delegated to MessageReceiver
+        //Lets store the HeaderQnames that failed check and we will
+        //re-check them when MessageReceiver performs its checks.
+        ArrayList faultyHeaderQNames = new ArrayList();
+        
+        if(log.isDebugEnabled()){
+               log.debug("Check if MessageReceiver will handle MustUnderstand 
check");
+        }
+        boolean delegateToMR = delegateMustUnderstandCheckToMR(msgContext);
         while (headerBlocks.hasNext()) {
             SOAPHeaderBlock headerBlock = (SOAPHeaderBlock) 
headerBlocks.next();
             QName headerQName = headerBlock.getQName();
@@ -109,7 +120,18 @@
             if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled()) {
                 log.debug("MustUnderstand header not processed or registered 
as understood " + headerQName);
             }
-
+            
+            if(delegateToMR){
+                if(log.isDebugEnabled()){
+                    log.debug("MustUnderstandCheck delegated to 
MessageReceiver");
+                }
+                if(!faultyHeaderQNames.contains(headerQName)){
+                    faultyHeaderQNames.add(headerQName);
+                }
+                continue;
+            }
+            
+            
             // Throw a MustUnderstand fault for the current SOAP version
             String prefix = envelope.getNamespace().getPrefix();
 
@@ -125,7 +147,7 @@
                                                         
headerQName.toString()),
                                     
SOAP12Constants.FAULT_CODE_MUST_UNDERSTAND);
             } else {
-
+               
                 // TODO: should we be using a prefix on the faultcode?  What 
about
                 // the QName object Constants.FAULT_MUSTUNDERSTAND?
                 throw new AxisFault(Messages.getMessage("mustunderstandfailed",
@@ -134,8 +156,46 @@
                                     
SOAP11Constants.FAULT_CODE_MUST_UNDERSTAND);
             }
         }
+        //Adding HeaderQName that failed mustUnderstand Check as AxisService 
Parameter 
+        //If mustUnderstand check is delegated to MessageReceiver these faulty 
headers will
+        //be examined later by MessageReceiver.
+        AxisService axisService = msgContext.getAxisService();
+        Parameter p = new Parameter(Constants.FAULTY_HEADER_QNAMES, 
faultyHeaderQNames);
+        axisService.addParameter(p);
     }
 
+    /**
+     * This method uses java reflection on MessageReceiver to see if the 
+     * MustUnderstandCheck will be handled by the MessageReceiver 
implementation.
+     * @param msgContext
+     * @return
+     * @throws AxisFault
+     */
+    private boolean delegateMustUnderstandCheckToMR(MessageContext msgContext) 
throws AxisFault{
+        //Check if MustUnderstand check should be posponed
+        if (msgContext.isServerSide()) {
+            // Get Message Receiver
+            MessageReceiver receiver = 
msgContext.getAxisOperation().getMessageReceiver();
+            if (receiver == null) {
+                throw new AxisFault(Messages.getMessage("nomessagereciever",
+                    msgContext.getAxisOperation()
+                    .getName()
+                    .toString()));
+            }
+
+            
if(MessageReceiverExtension.class.isAssignableFrom(receiver.getClass())){
+                MessageReceiverExtension mre = (MessageReceiverExtension) 
receiver;
+                return mre.isMustUnderstandCheckPostponed(msgContext);
+            }else{
+                if(log.isDebugEnabled()){
+                    log.debug("Receiver does not implement 
MessageReceiverExtension");
+                }
+            }
+
+        }
+        return false;
+
+    }
     private boolean checkThisHeader(SOAPHeaderBlock headerBlock, 
MessageContext msgContext) {
         boolean checkIt = true;
         // Return true if this header should be validated for mustUnderstand
Index: 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java
===================================================================
--- 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java
        (revision 3243)
+++ 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java
        (working copy)
@@ -41,6 +41,7 @@
 import org.apache.axis2.jaxws.handler.HandlerChainProcessorTests;
 import org.apache.axis2.jaxws.handler.context.CompositeMessageContextTests;
 import org.apache.axis2.jaxws.handler.context.LogicalMessageContextTests;
+import org.apache.axis2.jaxws.handler.header.tests.HandlerTests;
 import org.apache.axis2.jaxws.i18n.JaxwsMessageBundleTests;
 import org.apache.axis2.jaxws.injection.ResourceInjectionTests;
 import org.apache.axis2.jaxws.lifecycle.EndpointLifecycleTests;
@@ -208,6 +209,7 @@
         suite.addTestSuite(BindingProviderTests.class);
         suite.addTestSuite(StringListTests.class);
         suite.addTestSuite(RPCLitStringArrayTests.class);
+        suite.addTestSuite(HandlerTests.class);
         // ------ Endpoint Tests ------
         suite.addTestSuite(BasicEndpointTests.class);
         
Index: 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/META-INF/services.xml
===================================================================
--- 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/META-INF/services.xml
    (revision 0)
+++ 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/META-INF/services.xml
    (revision 0)
@@ -0,0 +1,14 @@
+<serviceGroup>
+ <service name="DemoServiceService">
+  <messageReceivers>
+   <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"; 
class="org.apache.axis2.jaxws.server.JAXWSMessageReceiver"/>
+  </messageReceivers>
+  <parameter locked="false" 
name="ServiceClass">org.apache.axis2.jaxws.handler.header.DemoService</parameter>
+  <operation name="addNumbers" mep="http://www.w3.org/2004/08/wsdl/in-out";>
+    <actionMapping/>
+  </operation>
+  <operation name="echo" mep="http://www.w3.org/2004/08/wsdl/in-only";>
+    <actionMapping/>
+  </operation>
+ </service>
+</serviceGroup>
Index: 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/META-INF/DemoServiceService_schema1.xsd
===================================================================
--- 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/META-INF/DemoServiceService_schema1.xsd
  (revision 0)
+++ 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/META-INF/DemoServiceService_schema1.xsd
  (revision 0)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<xs:schema version="1.0" targetNamespace="http://demo/"; 
xmlns:xs="http://www.w3.org/2001/XMLSchema"; xmlns:tns="http://demo/";>
+
+  <xs:element name="echo" type="tns:echo"/>
+
+  <xs:element name="echoResponse" type="tns:echoResponse"/>
+
+  <xs:complexType name="echo">
+    <xs:sequence>
+      <xs:element name="arg0" type="xs:string" minOccurs="0"/>
+    </xs:sequence>
+  </xs:complexType>
+
+  <xs:complexType name="echoResponse">
+    <xs:sequence>
+      <xs:element name="return" type="xs:string" minOccurs="0"/>
+    </xs:sequence>
+  </xs:complexType>
+</xs:schema>
+
Index: 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/META-INF/DemoServiceService.wsdl
===================================================================
--- 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/META-INF/DemoServiceService.wsdl
 (revision 0)
+++ 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/META-INF/DemoServiceService.wsdl
 (revision 0)
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<definitions targetNamespace="http://demo/"; name="DemoServiceService" 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"; 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"; xmlns:tns="http://demo/"; 
xmlns="http://schemas.xmlsoap.org/wsdl/";>
+  <types>
+    <xsd:schema>
+      <xsd:import namespace="http://demo/"; 
schemaLocation="DemoServiceService_schema1.xsd"/>
+    </xsd:schema>
+  </types>
+  <message name="echo">
+    <part name="parameters" element="tns:echo"/>
+  </message>
+  <message name="echoResponse">
+    <part name="parameters" element="tns:echoResponse"/>
+  </message>
+  <portType name="DemoService">
+    <operation name="echo">
+      <input message="tns:echo"/>
+      <output message="tns:echoResponse"/>
+    </operation>
+  </portType>
+  <binding name="DemoServicePortBinding" type="tns:DemoService">
+    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"; 
style="document"/>
+    <operation name="echo">
+      <soap:operation soapAction=""/>
+      <input>
+        <soap:body use="literal"/>
+      </input>
+      <output>
+        <soap:body use="literal"/>
+      </output>
+    </operation>
+  </binding>
+  <service name="DemoServiceService">
+    <port name="DemoServicePort" binding="tns:DemoServicePortBinding">
+      <soap:address 
location="http://localhost:8080/axis2/services/DemoServiceService"/>
+    </port>
+  </service>
+</definitions>
+
Index: 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/tests/HandlerTests.java
===================================================================
--- 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/tests/HandlerTests.java
  (revision 0)
+++ 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/tests/HandlerTests.java
  (revision 0)
@@ -0,0 +1,37 @@
+package org.apache.axis2.jaxws.handler.header.tests;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.Dispatch;
+import javax.xml.ws.Service;
+
+import junit.framework.TestCase;
+
+public class HandlerTests extends TestCase {
+
+    public void testHandler_getHeader_invocation(){
+        System.out.println("----------------------------------");
+        System.out.println("test: " + getName());
+        Object res = null;
+        String soapMessage = "<soap:Envelope 
xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"; 
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"; 
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"; 
xmlns:demo=\"http://demo/\";><soap:Header> <demo:myheader 
soap:mustUnderstand=\"1\"/></soap:Header><soap:Body><demo:echo><arg0>test</arg0></demo:echo></soap:Body></soap:Envelope>";
+        String url = "http://localhost:8080/axis2/services/DemoServiceService";;
+        QName name = new QName("http://demo/";, "DemoServiceService");
+        QName portName = new QName("http://demo/";, "DemoServicePort");
+        try{
+                //Create Service
+                Service s = Service.create(name);
+                assertNotNull(s);
+                //add port
+                s.addPort(portName, null, url);
+                
+                //Create Dispatch
+                Dispatch<String> dispatch = s.createDispatch(portName, 
String.class, Service.Mode.MESSAGE);
+                assertNotNull(dispatch);
+                res = dispatch.invoke(soapMessage);
+                assertNotNull(res);
+                System.out.println("----------------------------------");
+        }catch(Exception e){
+                e.printStackTrace();
+                fail();
+        }       
+    }
+}
Index: 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/DemoHandler.java
===================================================================
--- 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/DemoHandler.java
 (revision 0)
+++ 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/DemoHandler.java
 (revision 0)
@@ -0,0 +1,35 @@
+package org.apache.axis2.jaxws.handler.header;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.handler.MessageContext;
+import javax.xml.ws.handler.soap.SOAPHandler;
+import javax.xml.ws.handler.soap.SOAPMessageContext;
+
+public class DemoHandler implements SOAPHandler<SOAPMessageContext> {
+
+    public Set<QName> getHeaders() {
+        System.out.println("DemoHandler.getHeaders Invoked by JAXWS");
+        Set<QName> result = new HashSet<QName>();
+        result.add(new QName("http://demo/";, "myheader"));
+        return result;
+    }
+
+    public void close(MessageContext arg0) {
+
+    }
+
+    public boolean handleFault(SOAPMessageContext arg0) {
+        return true;
+    }
+
+    public boolean handleMessage(SOAPMessageContext arg0) {
+        System.out.println("DemoHandler.handleMessage");
+        return true;
+    }
+
+
+
+}
Index: 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/DemoService.java
===================================================================
--- 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/DemoService.java
 (revision 0)
+++ 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/DemoService.java
 (revision 0)
@@ -0,0 +1,15 @@
+package org.apache.axis2.jaxws.handler.header;
+
+import javax.jws.HandlerChain;
+import javax.jws.WebService;
+
[EMAIL PROTECTED]
[EMAIL PROTECTED](file="handler.xml")
+public class DemoService {
+
+    public String echo(String msg)  {
+        System.out.println("DemoService.echo called with msg: " + msg);
+        return "Hello, " + msg;
+    }
+
+}
Index: 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/handler.xml
===================================================================
--- 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/handler.xml
      (revision 0)
+++ 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/test/org/apache/axis2/jaxws/handler/header/handler.xml
      (revision 0)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jws:handler-chains xmlns:jws="http://java.sun.com/xml/ns/javaee";>
+       <jws:handler-chain name="demo">
+               <jws:handler>
+                       <jws:handler-class>
+                               
org.apache.axis2.jaxws.handler.header.DemoHandler
+                       </jws:handler-class>
+               </jws:handler>
+       </jws:handler-chain>    
+</jws:handler-chains>
\ No newline at end of file
Index: C:/webservices/rad/WSFP_GM_092507/modules/jaxws/maven.xml
===================================================================
--- C:/webservices/rad/WSFP_GM_092507/modules/jaxws/maven.xml   (revision 3243)
+++ C:/webservices/rad/WSFP_GM_092507/modules/jaxws/maven.xml   (working copy)
@@ -792,6 +792,26 @@
                           <ant:include 
name="org/apache/axis2/jaxws/server/**"/>
                        </ant:fileset>
                </ant:copy>     
+               
+               <ant:copy 
toDir="target/test-classes/services/HandlerHeaderService/">
+                       <ant:fileset dir="target/test-classes">
+                          <ant:include 
name="org/apache/axis2/jaxws/handler/header/**"/>
+                       </ant:fileset>
+                       <ant:fileset 
dir="test/org/apache/axis2/jaxws/handler/header">
+                          <ant:include name="META-INF/**"/>
+                          <ant:include name="handler.xml"/>
+                       </ant:fileset>
+                       <ant:fileset dir="target/classes">
+                          <ant:include 
name="org/apache/axis2/jaxws/server/**"/>
+                       </ant:fileset>
+               </ant:copy>     
+               <!-- We have to explicitly copy the xml file refered to by the 
client interface HandlerChain annotation -->
+               <ant:copy toDir="target/test-classes/">
+                       <ant:fileset dir="test">
+                               <ant:include 
name="org/apache/axis2/jaxws/handler/header/handler.xml"/>
+                       </ant:fileset>
+               </ant:copy>
+               
                <ant:copy 
toDir="target/test-classes/services/StringListService/">
                        <ant:fileset dir="target/test-classes">
                           <ant:include 
name="org/apache/axis2/jaxws/stringlist//**"/>
Index: 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java
===================================================================
--- 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java
   (revision 3243)
+++ 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java
   (working copy)
@@ -33,6 +33,7 @@
 import org.apache.axis2.jaxws.handler.HandlerChainProcessor;
 import org.apache.axis2.jaxws.handler.HandlerInvokerUtils;
 import org.apache.axis2.jaxws.handler.HandlerResolverImpl;
+import org.apache.axis2.jaxws.handler.HandlerUtils;
 import org.apache.axis2.jaxws.i18n.Messages;
 import org.apache.axis2.jaxws.message.Message;
 import org.apache.axis2.jaxws.message.Protocol;
@@ -196,9 +197,12 @@
             if (log.isDebugEnabled()) {
                 log.debug("No handlers found on the InvocationContext, 
initializing handler list.");
             }
-            eic.setHandlers(new 
HandlerResolverImpl(endpointDesc.getServiceDescription()).getHandlerChain(endpointDesc.getPortInfo()));
+            eic.setHandlers(new 
HandlerResolverImpl(endpointDesc.getServiceDescription()).getHandlerChain(endpointDesc.getPortInfo()));
 
         }
-
+        //Since we are adding the handlers to description layer here we will 
register all the
+        //headers set by SOAPHandler->getHeader with AxisService here.
+        
HandlerUtils.registerSOAPHandlerHeaders(request.getAxisMessageContext(), 
eic.getHandlers());
+        
         if (!Utils.bindingTypesMatch(request, 
endpointDesc.getServiceDescription())) {
             Protocol protocol = request.getMessage().getProtocol();
             MessageContext faultContext = 
Utils.createVersionMismatchMessage(request, protocol);
@@ -217,6 +221,10 @@
             // modify/destroy parts of the message.  Make sure to save
             // the request message if appropriate.
             saveRequestMessage(request);
+            //As per section 10.2.1 of JAXWS Specification, perform a 
mustUnderstand processing before
+            //invoking inbound handlers.
+           
+            HandlerUtils.checkMustUnderstand(request.getAxisMessageContext());
             
             // Invoke inbound application handlers.  It's safe to use the 
first object on the iterator because there is
             // always exactly one EndpointDescription on a server invoke
Index: 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java
===================================================================
--- 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java
 (revision 3243)
+++ 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java
 (working copy)
@@ -19,17 +19,22 @@
 
 package org.apache.axis2.jaxws.server;
 
+import javax.xml.ws.Binding;
+import javax.xml.ws.WebServiceException;
+
 import org.apache.axis2.AxisFault;
 import org.apache.axis2.addressing.AddressingConstants;
 import org.apache.axis2.context.OperationContext;
 import org.apache.axis2.description.AxisOperation;
 import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.Parameter;
 import org.apache.axis2.engine.AxisEngine;
 import org.apache.axis2.engine.MessageReceiver;
+import org.apache.axis2.engine.MessageReceiverExtension;
 import org.apache.axis2.jaxws.ExceptionFactory;
-import org.apache.axis2.jaxws.core.InvocationContext;
 import org.apache.axis2.jaxws.core.InvocationContextFactory;
 import org.apache.axis2.jaxws.core.MessageContext;
+import org.apache.axis2.jaxws.description.EndpointDescription;
 import org.apache.axis2.jaxws.handler.AttachmentsAdapter;
 import org.apache.axis2.jaxws.handler.MEPContext;
 import org.apache.axis2.jaxws.handler.TransportHeadersAdapter;
@@ -43,15 +48,12 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import javax.xml.ws.Binding;
-import javax.xml.ws.WebServiceException;
-
 /**
  * The JAXWSMessageReceiver is the entry point, from the server's perspective,
  * to the JAX-WS code.  This will be called by the Axis Engine and is the end
  * of the chain from an Axis2 perspective.
  */
-public class JAXWSMessageReceiver implements MessageReceiver {
+public class JAXWSMessageReceiver implements MessageReceiver, 
MessageReceiverExtension{
 
     private static final Log log = 
LogFactory.getLog(JAXWSMessageReceiver.class);
 
@@ -206,8 +208,35 @@
             throw faultToReturn;
         }
     }
+    
+    /* (non-Javadoc)
+     * @see 
org.apache.axis2.jaxws.server.MessageReceiverExtension#isMustUnderstandCheckPosponed()
+     */
+    public boolean 
isMustUnderstandCheckPostponed(org.apache.axis2.context.MessageContext 
axisRequestMsgCtx) {
+        AxisService axisSvc = axisRequestMsgCtx.getAxisService();
+        if (axisSvc.getParameter(EndpointDescription.AXIS_SERVICE_PARAMETER) 
!= null) {
+            Parameter param = 
axisSvc.getParameter(EndpointDescription.AXIS_SERVICE_PARAMETER);
+            EndpointDescription ed = (EndpointDescription)param.getValue();
+            //Lets check if there is a Handler implementation present using 
Metadata layer.
+            //HandlerChain annotation can be present in Service Endpoint or 
ServiceEndpointInterface.
+            // ed.getHandlerChain() looks for HandlerAnnotation at both 
Endpoint and at SEI.
+            if(log.isDebugEnabled()){
+                log.debug("Check to see if a jaxws handler is configured.");
+            }
+            if(ed.getHandlerChain()!=null){
+                return true;
+            }
 
-    private boolean isMepInOnly(String mep) {
+            return false;
+        }
+        else{
+            //If we cannot get to ServiceDescription to check for HandlerChain 
annotation we will return true.
+            return true;
+        }
+
+    }
+
+       private boolean isMepInOnly(String mep) {
         boolean inOnly =
                 mep.equals(WSDL20_2004_Constants.MEP_URI_ROBUST_IN_ONLY)
                         || mep.equals(WSDL20_2004_Constants.MEP_URI_IN_ONLY)
Index: 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerUtils.java
===================================================================
--- 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerUtils.java
        (revision 0)
+++ 
C:/webservices/rad/WSFP_GM_092507/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerUtils.java
        (revision 0)
@@ -0,0 +1,148 @@
+package org.apache.axis2.jaxws.handler;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.handler.Handler;
+import javax.xml.ws.handler.soap.SOAPHandler;
+
+import org.apache.axiom.soap.SOAP11Constants;
+import org.apache.axiom.soap.SOAP12Constants;
+import org.apache.axiom.soap.SOAPConstants;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.Constants;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.AxisOperation;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.i18n.Messages;
+import org.apache.axis2.util.LoggingControl;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+/*
+ * Utility class to perform static utility type of operations on Handlers.
+ */
+public class HandlerUtils {
+    private static Log log = LogFactory.getLog(HandlerUtils.class);
+
+    /**
+     * IregisterHandlerHeaders will invoke getHeaders on SOAPHandlers and 
register these headers
+     * with AxisService as Understood headers.
+     * @param msgContext
+     * @param handlers
+     */
+    public static void registerSOAPHandlerHeaders(MessageContext msgContext, 
List<Handler> handlers){
+        if(msgContext == null){
+            return;
+        }
+        AxisOperation axisOperation = msgContext.getAxisOperation();
+
+        AxisService axisService = msgContext.getAxisService();
+        //do nothing if handlers or axisService is null.
+        if(handlers == null || axisService == null){
+            return;
+        }
+
+        ArrayList<QName> understoodHeaderNames = 
axisOperation.getUnderstoodHeaderQNames();
+        for(Handler handler:handlers){
+            if(handler instanceof SOAPHandler){
+                SOAPHandler soapHandler = (SOAPHandler)handler;
+                //Invoking getHeaders.
+                if(log.isDebugEnabled()){
+                    log.debug("Invoking getHeader() on SOAPHandler");
+                }
+                Set<QName> headers = soapHandler.getHeaders();
+                if(headers!=null){
+                    for(QName header:headers){
+                        if(!understoodHeaderNames.contains(header)){
+                            if(log.isDebugEnabled()){
+                                log.debug("Adding Header QName" + header + " 
to uderstoodHeaderQName List");
+                            }
+                            //Adding this to understood header list of 
AxisOperation.
+                            understoodHeaderNames.add(header);
+                        }
+                    }
+                }
+            }
+        }              
+    }
+
+    /**
+     * checkMustUnderstand will validate headers that where delegated by Axis 
Engine
+     * to MessageReceiver for mustUnderstand check.
+     * @param msgContext
+     * @throws AxisFault
+     */
+    public static void checkMustUnderstand(MessageContext msgContext)throws 
AxisFault{
+        if (msgContext == null || !msgContext.isHeaderPresent()) {
+            return;
+        }
+        SOAPEnvelope envelope = msgContext.getEnvelope();
+        if (envelope.getHeader() == null) {
+            return;
+        }
+        AxisService axisService =msgContext.getAxisService();
+        if(axisService == null){
+            return;
+        }
+        if(log.isDebugEnabled()){
+            log.debug("Reading faultyHeaderQNames from axisService Parameter");
+        }
+        Parameter param = 
axisService.getParameter(Constants.FAULTY_HEADER_QNAMES);
+        if(param == null){
+            if(log.isDebugEnabled()){
+                log.debug("axisService Parameter FAULTY_HEADER_QNAMES is 
null");
+            }
+            return;
+        }
+
+        ArrayList<QName> headerQNames = (ArrayList)param.getValue();
+        AxisOperation axisOperation = msgContext.getAxisOperation();
+        for (QName headerQName : headerQNames) {           
+            if (axisOperation != null) {
+                ArrayList understoodHeaderList = (ArrayList) 
axisOperation.getUnderstoodHeaderQNames();
+                if (understoodHeaderList != null && 
!understoodHeaderList.isEmpty()) {
+                    if (understoodHeaderList.contains(headerQName)) {
+                        if (LoggingControl.debugLoggingAllowed && 
log.isDebugEnabled()) {
+                            log.debug("MustUnderstand header registered as 
understood on AxisOperation: " + headerQName);
+                        }    
+                        continue;
+                    }
+                }
+            }
+
+            if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled()) {
+                log.debug("MustUnderstand header not processed or registered 
as understood " + headerQName);
+            }
+
+            // Throw a MustUnderstand fault for the current SOAP version
+            String prefix = envelope.getNamespace().getPrefix();
+
+            if (!msgContext.isSOAP11()) {
+
+                if (prefix == null || "".equals(prefix)) {
+                    prefix = SOAPConstants.SOAP_DEFAULT_NAMESPACE_PREFIX;
+                }
+                // TODO: should we be using a prefix on the faultcode?  What 
about
+                // the QName object Constants.FAULT_SOAP12_MUSTUNDERSTAND?
+                throw new AxisFault(Messages.getMessage("mustunderstandfailed",
+                    prefix,
+                    headerQName.toString()),
+                    SOAP12Constants.FAULT_CODE_MUST_UNDERSTAND);
+            } else {
+
+                // TODO: should we be using a prefix on the faultcode?  What 
about
+                // the QName object Constants.FAULT_MUSTUNDERSTAND?
+                throw new AxisFault(Messages.getMessage("mustunderstandfailed",
+                    prefix,
+                    headerQName.toString()),
+                    SOAP11Constants.FAULT_CODE_MUST_UNDERSTAND);
+            }
+        }
+        //resetting the FAULTY_HEADER_QNAME to null.
+        param.setValue(null);
+    }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to