Read on - design issue at the end.

I have modified the original soap:header support implementation to allow
full flexibility around the header management.  The way I have achieve this
is by allowing the user to specify the header object lifecycle.  The current
three lifecycles are: 

HeaderLifeCycle.REPLACE: the response's header object will overwrite the
request's one
HeaderLifeCycle.DISCARD: the request's header object is removed from the
list after the call.
HeaderLifeCycle.PERSIST: the request's header stays as is.

A user then do:
        binding.setHeader("CAM", cam, HeaderLifeCycle.REPLACE );
        binding.setHeader("hdrSession", hdrs, HeaderLifeCycle.DISCARD );

To allow the setHeader() and getHeader() method to work off the binding
(PortType) class I had to add a new extension to the PortType interface
(currently org.apache.axis.client.HeaderSupport) this is all fine for client
side since the HeaderSupport interface is implemented by the abstract Stub,
but doing so, I broke the Impl class since it also implements the PortType.

This being said we will ultimately want access to those two methods on the
server-side but in the mean time (since I am not implementing server support
now) I need a spot to put those two methods.  Any idea?

Would bringing back the skeleton be the answer to my problem?

I am attaching the patch and the new files so you can experiment the problem
with the Impl class.

Note: I did not yet rename the Header and Headers classes as was suggested
when I submitted the first implementation of the feature.

All feedback much appreciated.

--
Sylvain 

This message may contain privileged and/or confidential information.  If you
have received this e-mail in error or are not the intended recipient, you
may not use, copy, disseminate or distribute it; do not open any
attachments, delete it immediately from your system and notify the sender
promptly by e-mail that you have done so.  Thank you.
              

Attachment: ServiceContext.java
Description: Binary data

Attachment: HeaderLifeCycle.java
Description: Binary data

Attachment: HeaderKey.java
Description: Binary data

Attachment: HeaderSupport.java
Description: Binary data

Attachment: Headers.java
Description: Binary data

Attachment: Header.java
Description: Binary data

Index: xml-axis/java/src/org/apache/axis/client/Stub.java
===================================================================
RCS file: /home/cvspublic/xml-axis/java/src/org/apache/axis/client/Stub.java,v
retrieving revision 1.8
diff -r1.8 Stub.java
66a67,68
> import org.apache.axis.serviceContext.*;
> import org.apache.axis.message.SOAPHeaderElement;
74c76
< public abstract class Stub implements javax.xml.rpc.Stub {
---
> public abstract class Stub implements javax.xml.rpc.Stub, 
>org.apache.axis.client.HeaderSupport {
92a95,97
>               // Support for Header
>     private ServiceContext serviceContext = new ServiceContext();
> 
258a264,374
> 
> 
>     /**
>      * This method returns the ServiceContext object for this binding.
>      * @return ServiceContext
>      */
>     public ServiceContext getServiceContext() {
>         return serviceContext;
>     }
>     
>     /**
>      * This method allow the user to substitute this ServiceContext object with 
>another one.
>      * In general this is not required, but is provided in case someone would have 
>two binding to the same service 
>      * and would want to have both binding using the same ServiceContext.
>      * @return ServiceContext
>      */
>     public void setServiceContext(ServiceContext sc) {
>         serviceContext = sc;
>     }
> 
> 
>     /**
>      * This method allows a service consumer to set a SOAP Header object defined by
>      * <b>soap:header</b> operation element.  Every opertaion refering to this 
>soap:header 
>      * part in their binding will send this object as a SOAP Header.  The returned 
>object 
>      * will overwrite the current Service's ServiceContext instance of this part 
>object if 
>      * replace is set to true.
>      * @param partName a String that identify the soap:header part
>      * @param header an Object that will be sent as a SOAPHeader
>      * @param lifeCycle a HeaderLifeCycle that defines the request's object life 
>cycle.
>      * @return void
>      */
>     public void setHeader(String partName, Object header, HeaderLifeCycle lifeCycle) 
>{           
>         // Store the roudtrip attribute for this header, 
>         HeaderKey hk = new HeaderKey(partName);
>         hk.setLifeCycle(lifeCycle);
>           
>         serviceContext.setHeader(hk, header);      
>     }
> 
>     /**
>      * This method is meant to be used by the service consumer to retreive a 
>Service's 
>      * ServiceContext header object.  It returns the current object stored for the 
>given part 
>      * name from the response hash of headers.  The object the one returned by the 
>service 
>      * provider for that part.  It is null when the header does not exists, which 
>means that it 
>      * has not been returned bu the service provider.
>      * @param partName a String that identify the soap:header part            
>      * @return Object
>      */    
>     public Object getHeader(String partName) {                
>         return serviceContext.getHeader(partName);
>     }
> 
>     /**
>      * This method is meant to be used by the BindingStub to set the requested 
>request header onto 
>      * the Call object just before the call gets invoked. 
>      * @return SOAPHeaderElement
>      */    
>     public SOAPHeaderElement getHeader(String namespace, String partName) {          
> 
>         return new SOAPHeaderElement(
>                       namespace, 
>                       partName, 
>                       serviceContext.getRequestHeader( new HeaderKey(partName)) );
>     }
>     
>     /**
>      * This method is provided with the soap:header part name and the namespace so 
>it can update the 
>      * Header object stored in the Service's ServiceContext using the one retreived 
>in the response
>      * @return void
>      */
>     public void updateHeader(org.apache.axis.client.Call call, String namespace, 
>String partName) {           
> 
>         try {      
>             org.apache.axis.Message              response = 
>call.getMessageContext().getResponseMessage();      
>             org.apache.axis.message.SOAPEnvelope env      = 
>response.getSOAPEnvelope();
>             
>             if ( env != null )        {               
>                 SOAPHeaderElement header = env.getHeaderByName(namespace, partName, 
>true);
>             
>               if ( header != null )   {                                              
> 
>                     // Retrieve the object from the response
>                     Object theHeader = header.getObjectValue();
>                     // Retrieve this header object LifeCycle in the hash of request 
>headers.
>                     HeaderKey currentHeaderKey = 
>serviceContext.getRequestHeaderKey(new HeaderKey(partName));
>             
>                     if ( currentHeaderKey != null ) {
>                     
>                       if ( 
>currentHeaderKey.getLifeCycle().equals(HeaderLifeCycle.REPLACE) ) {
>                               // If the header lifeCycle is set to 
>HeaderLifeCycle.REPLACE we replace the 
>                               // header object found for that part in the 
>ServiceContext requestHeader Hashtable.
>                               serviceContext.setRequestHeader(currentHeaderKey, 
>theHeader);
>                               
>                                               } else if ( 
>currentHeaderKey.getLifeCycle().equals(HeaderLifeCycle.DISCARD) ) {
>                               // If the header lifeCycle is set to 
>HeaderLifeCycle.DISCARD we remove the 
>                               // header object found for that part in the 
>ServiceContext requestHeader Hashtable.
>                               serviceContext.removeRequestHeader(currentHeaderKey);
>                     
>                               } else if ( 
>currentHeaderKey.getLifeCycle().equals(HeaderLifeCycle.PERSIST) ) {
>                               // If the header lifeCycle is set to 
>HeaderLifeCycle.PERSIST we keep the the 
>                               // header object therefore we do nothing.
>                       }
>                     
>                         // In all case the received header object is stored in the 
>ServiceContext's 
>                         // responseHeader Hashtable.  This could be change to a 
>lazyer approach where
>                         // we would store the object on demand only....
>                         serviceContext.setResponseHeader(currentHeaderKey, 
>theHeader);
>                     }
>                 }                                     
>             }                         
>         } catch ( Exception e ) { /* Not really sure what to do with this... */ }
>     }    
Index: xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaInterfaceWriter.java
===================================================================
RCS file: 
/home/cvspublic/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaInterfaceWriter.java,v
retrieving revision 1.6
diff -r1.6 JavaInterfaceWriter.java
115c115
<         pw.println("public interface " + className + " extends java.rmi.Remote {");
---
>         pw.println("public interface " + className + " extends java.rmi.Remote, 
>org.apache.axis.client.HeaderSupport {");
Index: xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaStubWriter.java
===================================================================
RCS file: 
/home/cvspublic/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaStubWriter.java,v
retrieving revision 1.55
diff -r1.55 JavaStubWriter.java
70a71
> import javax.wsdl.extensions.soap.SOAPHeader;
73a75
> import java.util.Enumeration;
231a234
> 
259a263
>                              
262c266
<                     if (obj instanceof SOAPBody) {
---
>                     if ( obj instanceof SOAPBody) {
269d272
<                         break;
275a279,283
> 
>                                               // Take care of this operation's 
>header management stuff.
>             Headers headers = new Headers();
>             headers.prepareHeaders( operation );
> 
285c293
<                         operation, parameters, soapAction, namespace, isRPC);
---
>                         operation, headers, parameters, soapAction, namespace, 
>isRPC);
468a477
>             Headers headers,
578a588,595
>         // Set the headers
>         pw.println();
>         Enumeration headersEnum = headers.getRequestHeaders().elements();
>         while ( headersEnum.hasMoreElements() ) {
>           Header h = (Header)headersEnum.nextElement();          
>               pw.println("        call.addHeader( getHeader( \"" + namespace + "\", 
>\"" + h.getPartName() + "\"));");
>         }                
>         
606a624,632
>         
>         // Update the headers
>         headersEnum = headers.getResponseHeaders().elements();
>         while ( headersEnum.hasMoreElements() ) {
>           Header h = (Header)headersEnum.nextElement();          
>               pw.println("        updateHeader( call, \"" + namespace + "\", \"" + 
>h.getPartName() + "\");");
>         }       
>         
>         pw.println();       

Reply via email to