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 2006/11/04 06:20:28 UTC

svn commit: r471123 - in /webservices/axis2/trunk/java/modules/jaxws: src/org/apache/axis2/jaxws/message/ src/org/apache/axis2/jaxws/message/impl/ test/org/apache/axis2/jaxws/message/

Author: scheu
Date: Fri Nov  3 21:20:27 2006
New Revision: 471123

URL: http://svn.apache.org/viewvc?view=rev&rev=471123
Log:
AXIS2-1602
Contributor:Rich Scheuerle
Upgraded JAX-WS Message subsystem for Style.RPC

Added:
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/MessageRPCTests.java
Modified:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/Block.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/BlockFactoryImpl.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/XMLPartImpl.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

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/Block.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/Block.java?view=diff&rev=471123&r1=471122&r2=471123
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/Block.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/Block.java Fri Nov  3 21:20:27 2006
@@ -129,14 +129,4 @@
 	 */
 	public BlockFactory getBlockFactory();
     
-    /**
-     * Get the XMLPart that contains this Block, if it is attached to one at all.
-     * @return XMLPart that the Block is attached to
-     */
-    public XMLPart getParent();
-    
-    /**
-     * Set the XMLPart that will contain this Block.
-     */
-    public void setParent(XMLPart p);
 }

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?view=diff&rev=471123&r1=471122&r2=471123
==============================================================================
--- 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 Fri Nov  3 21:20:27 2006
@@ -16,6 +16,8 @@
  */
 package org.apache.axis2.jaxws.message;
 
+import javax.jws.soap.SOAPBinding.Style;
+import javax.xml.namespace.QName;
 import javax.xml.soap.SOAPEnvelope;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
@@ -74,6 +76,29 @@
 	 */
 	public XMLStreamReader getXMLStreamReader(boolean consume) throws MessageException;
 	
+    /**
+     * @return the Style (document or rpc)
+     */
+    public Style getStyle();
+    
+    /**
+     * Set the Style. 
+     * @param style Style
+     */
+    public void setStyle(Style style) throws MessageException;
+
+    /**
+     * @return the QName of the operation element if Style.rpc.  Otherwise null
+     */
+    public QName getOperationElement() throws MessageException;
+    
+    /**
+     * Set the operation element qname.  The operation qname is only used if
+     * Style.rpc
+     * @param operationQName
+     */
+    public void setOperationElement(QName operationQName) throws MessageException;
+    
 	/**
 	 * isConsumed
 	 * Return true if the part is consumed.  Once consumed, the information in the 

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/BlockFactoryImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/BlockFactoryImpl.java?view=diff&rev=471123&r1=471122&r2=471123
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/BlockFactoryImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/BlockFactoryImpl.java Fri Nov  3 21:20:27 2006
@@ -57,7 +57,6 @@
 			qName = other.getQName();
 		}
 		Block newBlock = createFrom(other.getXMLStreamReader(true), context, qName);
-        newBlock.setParent(other.getParent());
         return newBlock;
 	}
 

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?view=diff&rev=471123&r1=471122&r2=471123
==============================================================================
--- 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 Fri Nov  3 21:20:27 2006
@@ -23,6 +23,8 @@
 import java.util.List;
 
 import javax.activation.DataHandler;
+import javax.jws.soap.SOAPBinding.Style;
+import javax.xml.namespace.QName;
 import javax.xml.soap.MessageFactory;
 import javax.xml.soap.MimeHeaders;
 import javax.xml.soap.SOAPEnvelope;
@@ -381,6 +383,22 @@
 
     public void setLocalException(Throwable t) {
         localException = t;
+    }
+
+    public Style getStyle() {
+        return xmlPart.getStyle();
+    }
+
+    public void setStyle(Style style) throws MessageException {
+        xmlPart.setStyle(style);
+    }
+
+    public QName getOperationElement() throws MessageException {
+        return xmlPart.getOperationElement();
+    }
+
+    public void setOperationElement(QName operationQName) throws MessageException {
+        xmlPart.setOperationElement(operationQName);
     }
 
 

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?view=diff&rev=471123&r1=471122&r2=471123
==============================================================================
--- 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 Fri Nov  3 21:20:27 2006
@@ -16,7 +16,13 @@
  */
 package org.apache.axis2.jaxws.message.impl;
 
+import java.util.Iterator;
+
+import javax.jws.soap.SOAPBinding.Style;
 import javax.xml.namespace.QName;
+import javax.xml.soap.Name;
+import javax.xml.soap.Node;
+import javax.xml.soap.SOAPElement;
 import javax.xml.soap.SOAPEnvelope;
 import javax.xml.soap.SOAPException;
 import javax.xml.stream.XMLStreamException;
@@ -81,6 +87,8 @@
 	private static Log log = LogFactory.getLog(XMLPartBase.class);
 	
 	Protocol protocol = Protocol.unknown;  // Protocol defaults to unknown
+    Style style = Style.DOCUMENT;          // Style defaults to document
+    
 	
 	// The actual xml representation is always one of the following
 	//   OM if the content is an OM tree
@@ -214,7 +222,6 @@
 		default:
 			throw ExceptionFactory.makeMessageInternalException(Messages.getMessage("XMLPartImplErr2"), null);
 		}
-		spine.setParent(parent);
         setContent(spine, SPINE);
 		return spine;
 	}
@@ -260,6 +267,59 @@
 	}
 
 	/* (non-Javadoc)
+	 * @see org.apache.axis2.jaxws.message.XMLPart#getStyle()
+	 */
+	public Style getStyle() {
+        return style;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.axis2.jaxws.message.XMLPart#setStyle(javax.jws.soap.SOAPBinding.Style)
+     */
+    public void setStyle(Style style) throws MessageException {
+        if (this.style != style) {
+            if (contentType == SPINE) {
+                // Must switch to something other than XMLSpine
+                getContentAsOMElement();
+            }
+        }
+        this.style = style;
+    }
+
+    public QName getOperationElement() throws MessageException {
+        try {
+            if (style != Style.RPC) {
+                return null;
+            }
+            switch (contentType) {
+            case OM:
+                return ((org.apache.axiom.soap.SOAPEnvelope) content).getBody().
+                getFirstElement().getQName();
+            case SPINE:
+                return ((XMLSpine) content).getOperationElement();
+            case SOAPENVELOPE:
+                Iterator it =((SOAPEnvelope) content).getBody().getChildElements();
+                while (it.hasNext()) {
+                    Node node = (Node) it.next();
+                    if (node instanceof SOAPElement) {
+                        Name name =((SOAPElement) node).getElementName();
+                        return new QName(name.getURI(), name.getLocalName(), name.getPrefix());
+                    }
+                }
+            }
+            return null;
+        } catch (SOAPException se) {
+            throw ExceptionFactory.makeMessageException(se);
+        }
+    }
+
+    public void setOperationElement(QName operationQName) throws MessageException {
+        if (this.style == Style.RPC) {
+            this.getContentAsXMLSpine().setOperationElement(operationQName);
+        }
+    }
+
+    /* (non-Javadoc)
 	 * @see org.apache.axis2.jaxws.message.XMLPart#getXMLPartContentType()
 	 */
 	public String getXMLPartContentType() {
@@ -518,7 +578,7 @@
 	protected XMLSpine _createSpine(Protocol protocol) throws MessageException {
 		// Default implementation is to simply construct the spine. 
 		// Derived classes may wish to construct a different kind of XMLSpine
-		return new XMLSpineImpl(protocol);
+		return new XMLSpineImpl(protocol, getStyle());
 	}
 	
 	private void setConsumed(boolean consume) { 

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLPartImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLPartImpl.java?view=diff&rev=471123&r1=471122&r2=471123
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLPartImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLPartImpl.java Fri Nov  3 21:20:27 2006
@@ -99,7 +99,7 @@
 
 	@Override
 	protected XMLSpine _convertOM2Spine(OMElement om) throws MessageException {
-		return new XMLSpineImpl((org.apache.axiom.soap.SOAPEnvelope) om);
+		return new XMLSpineImpl((org.apache.axiom.soap.SOAPEnvelope) om, getStyle());
 	}
 
 	@Override

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?view=diff&rev=471123&r1=471122&r2=471123
==============================================================================
--- 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 Fri Nov  3 21:20:27 2006
@@ -16,7 +16,21 @@
  */
 package org.apache.axis2.jaxws.message.impl;
 
+import javax.jws.soap.SOAPBinding.Style;
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPEnvelope;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.jaxws.message.Block;
+import org.apache.axis2.jaxws.message.Message;
+import org.apache.axis2.jaxws.message.MessageException;
+import org.apache.axis2.jaxws.message.Protocol;
+import org.apache.axis2.jaxws.message.XMLFault;
 import org.apache.axis2.jaxws.message.XMLPart;
+import org.apache.axis2.jaxws.message.factory.BlockFactory;
 
 /**
  * XMLSpine
@@ -26,6 +40,182 @@
  * @see org.apache.axis2.jaxws.message.impl.XMLSpineImpl for more details
  *
  */
-interface XMLSpine extends XMLPart {
+interface XMLSpine {
+    /**
+     * Get the protocol for this Message (soap11, soap12, etc.)
+     * @return Protocl
+     */
+    public Protocol getProtocol();
+    
+    /**
+     * Write out the Message
+     * @param writer XMLStreamWriter
+     * @param consume true if this is the last request on the block.
+     * @throws MessageException
+     */
+    public void outputTo(XMLStreamWriter writer, boolean consume) throws XMLStreamException, MessageException;  
+    
+    /**
+     * Get the XMLStreamReader represented by this Message for the xml part
+     * @param consume true if this is the last request on the Message
+     * @return XMLStreamReader
+     * @throws MessageException
+     * @throws XMLStreamException
+     */
+    public XMLStreamReader getXMLStreamReader(boolean consume) throws MessageException;
+    
+    /**
+     * @return the Style (document or rpc)
+     */
+    public Style getStyle();
 
+    /**
+     * @return the QName of the operation element if Style.rpc.  Otherwise null
+     */
+    public QName getOperationElement() throws MessageException;
+    
+    /**
+     * Set the operation element qname.  The operation qname is only used if
+     * Style.rpc
+     * @param operationQName
+     */
+    public void setOperationElement(QName operationQName) throws MessageException;
+    
+    /**
+     * isConsumed
+     * Return true if the part is consumed.  Once consumed, the information in the 
+     * part is no longer available.
+     * @return true if the block is consumed (a method was called with consume=true)
+     */
+    public boolean isConsumed();
+    
+    /**
+     * Determines whether the XMLPart represents a Fault
+     * @return true if the message represents a fault
+     */
+    public boolean isFault() throws MessageException;
+    
+    /**
+     * If the XMLPart represents a fault, an XMLFault is returned
+     * which describes the fault in a protocol agnostic manner
+     * @return the XMLFault object or null
+     * @see XMLFault
+     */
+    public XMLFault getXMLFault() throws MessageException;
+    
+    /**
+     * Change the XMLPart so that it represents the fault described
+     * by XMLFault
+     * @param xmlfault
+     * @see XMLFault
+     */
+    public void setXMLFault(XMLFault xmlFault) throws MessageException;
+    
+    /**
+     * getAsOMElement
+     * Get the xml part as a read/write OM
+     * @return OMElement (probably OM SOAPEnvelope)
+     * @throws MessageException
+     */
+    public OMElement getAsOMElement() throws MessageException;
+    
+    /**
+     * getNumBodyBlocks
+     * @return number of body blocks
+     * @throws MessageException
+     */
+    public int getNumBodyBlocks() throws MessageException;
+    
+    /**
+     * getBodyBlock
+     * Get the body block as the specificed index.
+     * The BlockFactory and object context are passed in to help create the 
+     * proper kind of block.
+     * 
+     * @param index
+     * @param context
+     * @param blockFactory
+     * @return Block
+     * @throws MessageException
+     */
+    public Block getBodyBlock(int index, Object context, BlockFactory blockFactory)  
+        throws MessageException;
+    
+    /**
+     * setBodyBlock
+     * Set the block at the specified index
+     * Once set, the Message owns the block.  You must
+     * use the getBodyBlock method to access it.
+     * @param index
+     * @param block
+     * @throws MessageException
+     */
+    public void setBodyBlock(int index, Block block) throws MessageException;
+    
+    /**
+     * removePayload
+     * Removes the indicated BodyBlock
+     * @param index
+     * @throws MessageException
+     */
+    public void removeBodyBlock(int index) throws MessageException;
+    
+    
+    /**
+     * getNumHeaderBlocks
+     * @return number of header blocks
+     * @throws MessageException
+     */
+    public int getNumHeaderBlocks() throws MessageException;
+    
+    /**
+     * getHeaderBlock
+     * Get the header block with the specified name
+     * The BlockFactory and object context are passed in to help create the 
+     * proper kind of block.
+     * 
+     * @param namespace
+     * @param localPart
+     * @param context
+     * @param blockFactory
+     * @return Block
+     * @throws MessageException
+     */
+    public Block getHeaderBlock(String namespace, String localPart, 
+            Object context, 
+            BlockFactory blockFactory)  
+        throws MessageException;
+    
+    /**
+     * 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 MessageException
+     */
+    public void setHeaderBlock(String namespace, String localPart, Block block) 
+        throws MessageException;
+    
+    /**
+     * removePayload
+     * Removes the indicated block
+     * @param namespace
+     * @param localPart
+     * @throws MessageException
+     */
+    public void removeHeaderBlock(String namespace, String localPart) 
+        throws MessageException;
+    
+    
+    /**
+     * Get a traceString...the trace string dumps the contents of the Block without forcing an underlying
+     * ill-performant transformation of the message.
+     * @boolean indent String containing indent characters
+     * @return String containing trace information
+     */
+    public String traceString(String indent);
+    
 }

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?view=diff&rev=471123&r1=471122&r2=471123
==============================================================================
--- 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 Fri Nov  3 21:20:27 2006
@@ -20,12 +20,14 @@
 import java.util.Iterator;
 import java.util.List;
 
+import javax.jws.soap.SOAPBinding.Style;
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
 
 import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMNamespace;
 import org.apache.axiom.om.OMNode;
 import org.apache.axiom.om.impl.llom.OMSourcedElementImpl;
 import org.apache.axiom.soap.SOAP11Constants;
@@ -47,6 +49,7 @@
 import org.apache.axis2.jaxws.message.XMLFault;
 import org.apache.axis2.jaxws.message.factory.BlockFactory;
 import org.apache.axis2.jaxws.message.factory.OMBlockFactory;
+import org.apache.axis2.jaxws.message.util.MessageUtils;
 import org.apache.axis2.jaxws.message.util.Reader2Writer;
 import org.apache.axis2.jaxws.registry.FactoryRegistry;
 
@@ -67,6 +70,7 @@
 	private static OMBlockFactory obf = (OMBlockFactory) FactoryRegistry.getFactory(OMBlockFactory.class);
 	
 	private Protocol protocol = Protocol.unknown;
+    private Style style = Style.DOCUMENT;
 	private SOAPEnvelope root = null;
 	private SOAPFactory soapFactory = null;
 	private List<Block> headerBlocks = new ArrayList<Block>();
@@ -80,21 +84,27 @@
 	/**
 	 * Create a lightweight representation of this protocol
 	 * (i.e. the Envelope, Header and Body)
+     * @param protocol Protocol
+     * @param style Style
+     * @param opQName QName if the Style is RPC
 	 */
-	public XMLSpineImpl(Protocol protocol) {
+	public XMLSpineImpl(Protocol protocol, Style style) {
 		super();
 		this.protocol = protocol;
+        this.style = style;
 		soapFactory = getFactory(protocol);
-		root = createEmptyEnvelope(protocol, soapFactory);
+		root = createEmptyEnvelope(protocol, style, soapFactory);
 	}
 	
 	/**
 	 * Create spine from an existing OM tree
 	 * @param envelope
+     * @param style Style
 	 * @throws MessageException
 	 */
-	public XMLSpineImpl(SOAPEnvelope envelope) throws MessageException {
+	public XMLSpineImpl(SOAPEnvelope envelope, Style style) throws MessageException {
 		super();
+        this.style = style;
 		init(envelope);
 		if (root.getNamespace().getNamespaceURI().equals(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
 			protocol = Protocol.soap11;
@@ -113,6 +123,7 @@
 		detailBlocks.clear();
 		bodyIterator = null;
 		detailIterator = null;
+        soapFactory = MessageUtils.getSOAPFactory(root);
 		
 		
 		// If a header block exists, create an OMBlock for each element
@@ -126,13 +137,27 @@
 
 		
 		SOAPBody body = root.getBody();
-        // TODO if no body then please add one
+        if (body == null) {
+            // Create the body if one does not exist
+            body = soapFactory.createSOAPBody(root);
+        }
         
 		if (!body.hasFault()) {
 			// Normal processing
 			// Only create the first body block, this ensures that the StAX 
 			// cursor is not advanced beyond the tag of the first element
-			bodyIterator = body.getChildren();
+            if (style == Style.DOCUMENT) {
+                bodyIterator = body.getChildren();
+            } else {
+                // For RPC the blocks are within the operation element
+                OMElement op = body.getFirstElement();
+                if (op == null) {
+                    // Create one
+                    OMNamespace ns = soapFactory.createOMNamespace("", "");
+                    op = soapFactory.createOMElement("PLACEHOLDER_OPERATION", ns, body);
+                }
+                bodyIterator = op.getChildren();
+            }
 			advanceIterator(bodyIterator, bodyBlocks, false);
 		} else {
 			// Process the Fault
@@ -178,7 +203,6 @@
 					throw ExceptionFactory.makeMessageException(xse);
 				}
 				blocks.add(block);
-                block.setParent(this);
 			} else {
                 // TODO LOGGING ?
 				// A Non-element is found, it is probably whitespace text, but since
@@ -199,11 +223,17 @@
 		}
 		return soapFactory;
 	}
-	private static SOAPEnvelope createEmptyEnvelope(Protocol protocol, SOAPFactory factory) {
+	private static SOAPEnvelope createEmptyEnvelope(Protocol protocol, Style style, SOAPFactory factory) {
 		SOAPEnvelope env = factory.createSOAPEnvelope();
 		// Add an empty body and header
 		factory.createSOAPBody(env);
 		factory.createSOAPHeader(env);
+        
+        // Create a dummy operation element if this is an rpc message
+        if (style == Style.RPC) {
+            OMNamespace ns = factory.createOMNamespace("", "");
+            factory.createOMElement("PLACEHOLDER_OPERATION", ns, env.getBody());
+        }
 
 		return env;
 	}
@@ -298,10 +328,6 @@
 		return consumed;
 	}
 
-	public javax.xml.soap.SOAPEnvelope getAsSOAPEnvelope() throws MessageException {
-		throw ExceptionFactory.makeMessageInternalException(Messages.getMessage("NeverCalled", "XMLSpineImpl.getAsSOAPEnvelope()"), null);
-	}
-
 	public OMElement getAsOMElement() throws MessageException {
 	    if (headerBlocks != null) {        
 	        for (int i=0; i<headerBlocks.size(); i++) {                   
@@ -314,8 +340,16 @@
 	    if (bodyBlocks != null) {
 	        for (int i=0; i<bodyBlocks.size(); i++) {                   
 	            Block b = (Block) bodyBlocks.get(i);                  
-	            OMElement e = new OMSourcedElementImpl(b.getQName(),soapFactory, b);                  
-	            root.getBody().addChild(e);                  
+	            OMElement e = new OMSourcedElementImpl(b.getQName(),soapFactory, b);
+                
+                // The blocks are directly under the body if DOCUMENT.
+                // The blocks are under the operation element if RPC
+                if (style == Style.DOCUMENT) {
+                    root.getBody().addChild(e);    
+                } else {
+                    root.getBody().getFirstElement().addChild(e);   
+                }
+	                          
 	        }               
 	        bodyBlocks.clear();               
 	    }
@@ -329,12 +363,6 @@
 	    }
 	    return root;
 	}
-	
-	
-
-	public Block getAsBlock(Object context, BlockFactory blockFactory) throws MessageException, XMLStreamException {
-		throw ExceptionFactory.makeMessageInternalException(Messages.getMessage("NeverCalled", "XMLSpineImpl.getAsBlock()"), null);
-	}
 
 	/* (non-Javadoc)
 	 * @see org.apache.axis2.jaxws.message.XMLPart#getNumBodyBlocks()
@@ -369,7 +397,6 @@
 			advanceIterator(bodyIterator, bodyBlocks, true);
 		}
 		bodyBlocks.add(index, block);
-        block.setParent(this);
 	}
 
 	public void removeBodyBlock(int index) throws MessageException {
@@ -403,7 +430,6 @@
 		int index = getHeaderBlockIndex(namespace, localPart);
 		headerBlocks.add(block);
 		//headerBlocks.set(index, block);
-        block.setParent(this);
 	}
 
 	/**
@@ -441,5 +467,29 @@
     public boolean isFault() throws MessageException {
 		return XMLFaultUtils.isFault(root);
 	}
-	
+
+    public Style getStyle() {
+        return style;
+    }
+
+    public QName getOperationElement() {
+        if (style == style.DOCUMENT) {
+            return null;
+        } else {
+            return root.getBody().getFirstElement().getQName();
+        }
+    }
+
+    public void setOperationElement(QName operationQName) {
+        if (style == style.RPC) {
+            if (soapFactory == null) {
+                soapFactory = MessageUtils.getSOAPFactory(root);
+            }
+            OMNamespace ns = soapFactory.createOMNamespace(operationQName.getNamespaceURI(), operationQName.getPrefix());
+            OMElement opElement = root.getBody().getFirstElement();
+            opElement.setLocalName(operationQName.getLocalPart());
+            opElement.setNamespace(ns);
+        }
+    }
+    
 }

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/MessageRPCTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/MessageRPCTests.java?view=auto&rev=471123
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/MessageRPCTests.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/message/MessageRPCTests.java Fri Nov  3 21:20:27 2006
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2004,2005 The Apache Software Foundation.
+ * Copyright 2006 International Business Machines Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.axis2.jaxws.message;
+
+import java.io.ByteArrayOutputStream;
+import java.io.StringReader;
+
+import javax.jws.soap.SOAPBinding.Style;
+import javax.xml.bind.JAXBElement;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import junit.framework.TestCase;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMOutputFormat;
+import org.apache.axiom.om.impl.llom.OMSourcedElementImpl;
+import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
+import org.apache.axis2.jaxws.message.databinding.JAXBBlockContext;
+import org.apache.axis2.jaxws.message.factory.JAXBBlockFactory;
+import org.apache.axis2.jaxws.message.factory.MessageFactory;
+import org.apache.axis2.jaxws.registry.FactoryRegistry;
+import org.test.stock1.ObjectFactory;
+import org.test.stock1.StockPrice;
+
+/**
+ * MessageTests
+ * Tests to create and validate Message processing
+ * These are not client/server tests.  Instead the tests simulate the processing of a Message during
+ * client/server processing.
+ */
+public class MessageRPCTests extends TestCase {
+
+	// String test variables
+	private static final String soap11env = "http://schemas.xmlsoap.org/soap/envelope/";
+	private static final String soap12env = "http://www.w3.org/2003/05/soap-envelope";
+    private static final String sampleEnvelopeHead11 =
+        "<soapenv:Envelope xmlns:soapenv=\"" + soap11env + "\">" +
+        "<soapenv:Header /><soapenv:Body>";
+    
+    private static final String sampleEnvelopeHead12 =
+        "<soapenv:Envelope xmlns:soapenv=\"" + soap12env + "\">" +
+        "<soapenv:Header /><soapenv:Body>";
+    
+    private static final String sampleEnvelopeTail = 
+        "</soapenv:Body></soapenv:Envelope>";
+    
+    private static final String sampleText =
+        "<m:op xmlns:m='urn://sample'>" +
+		"<m:param xmlns:pre='urn://stock1.test.org' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:type='pre:StockPrice'>" +
+		"<price>100</price>" +
+		"</m:param>" +
+        "</m:op>";
+	
+    private static final String sampleEnvelope11 = 
+        sampleEnvelopeHead11 +
+        sampleText +
+        sampleEnvelopeTail;
+    
+    private static final String sampleEnvelope12 = 
+        sampleEnvelopeHead12 +
+        sampleText +
+        sampleEnvelopeTail;
+        
+	
+	private static XMLInputFactory inputFactory = XMLInputFactory.newInstance();
+	
+	public MessageRPCTests() {
+		super();
+	}
+
+	public MessageRPCTests(String arg0) {
+		super(arg0);
+	}
+	
+	
+    
+    /**
+     * Create a JAXBBlock containing a JAX-B business object 
+     * and simulate a normal Proxy output flow
+     * @throws Exception
+     */
+    public void testJAXBOutflow() throws Exception {
+        // Create a SOAP 1.1 Message
+        MessageFactory mf = (MessageFactory)
+            FactoryRegistry.getFactory(MessageFactory.class);
+        Message m = mf.create(Protocol.soap11);
+        
+        // Indicate that the style is RPC, Indicate the Operation QName
+        m.setStyle(Style.RPC);
+        QName opQName = new QName("urn://sample", "op", "m");
+        m.setOperationElement(opQName);
+        
+        // Get the BlockFactory
+        JAXBBlockFactory bf = (JAXBBlockFactory)
+            FactoryRegistry.getFactory(JAXBBlockFactory.class);
+        
+        // Create the JAXBContext
+        JAXBBlockContext context = new JAXBBlockContext(StockPrice.class, true);
+        
+        // Create the JAX-B object
+        ObjectFactory of = new ObjectFactory();
+        StockPrice obj = of.createStockPrice();
+        obj.setPrice("100");
+        
+        // Create the JAX-B Element
+        QName paramQName = new QName("urn://sample", "param", "m");
+        JAXBElement e = new JAXBElement(paramQName, StockPrice.class, obj);
+        
+        // Create a JAXBBlock using the param object as the content.  This simulates
+        // what occurs on the outbound JAX-WS Proxy client
+        Block block = bf.createFrom(e, context, null);
+        
+        // Add the block to the message as normal body content.
+        m.setBodyBlock(0, block);
+        
+        // Check to see if the message is a fault.  The client/server will always call this method.
+        // The Message must respond appropriately without doing a conversion.
+        boolean isFault = m.isFault();
+        assertTrue(!isFault);
+        assertTrue("XMLPart Representation is " + m.getXMLPartContentType(),
+                    "SPINE".equals(m.getXMLPartContentType()));
+        
+        // On an outbound flow, we need to convert the Message 
+        // to an OMElement, specifically an OM SOAPEnvelope, 
+        // so we can set it on the Axis2 MessageContext
+        org.apache.axiom.soap.SOAPEnvelope env = 
+            (org.apache.axiom.soap.SOAPEnvelope) m.getAsOMElement();
+        
+        // Check to see if the message is a fault.  The client/server will always call this method.
+        // The Message must respond appropriately without doing a conversion.
+        isFault = m.isFault();
+        assertTrue(!isFault);
+        assertTrue("XMLPart Representation is " + m.getXMLPartContentType(),
+                    "OM".equals(m.getXMLPartContentType()));
+        
+        // Serialize the Envelope using the same mechanism as the 
+        // HTTP client.
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        env.serializeAndConsume(baos, new OMOutputFormat());
+        
+        // To check that the output is correct, get the String contents of the 
+        // reader
+        String newText = baos.toString();
+        System.out.println(newText);
+        assertTrue(newText.contains("m:op"));
+        assertTrue(newText.contains("m:param"));
+        assertTrue(newText.contains("100"));
+        assertTrue(newText.contains("Envelope"));
+        assertTrue(newText.contains("Body"));
+    }
+    
+    /**
+     * Create a JAXBBlock containing a JAX-B business object 
+     * and simulate a normal Proxy output flow
+     * @throws Exception
+     */
+    public void testJAXBOutflowPerf() throws Exception {
+        // Create a SOAP 1.1 Message
+        MessageFactory mf = (MessageFactory)
+            FactoryRegistry.getFactory(MessageFactory.class);
+        Message m = mf.create(Protocol.soap11);
+        
+        // Indicate that the style is RPC, Indicate the Operation QName
+        m.setStyle(Style.RPC);
+        QName opQName = new QName("urn://sample", "op", "m");
+        m.setOperationElement(opQName);
+        
+        // Get the BlockFactory
+        JAXBBlockFactory bf = (JAXBBlockFactory)
+            FactoryRegistry.getFactory(JAXBBlockFactory.class);
+        
+        // Create the JAXBContext
+        JAXBBlockContext context = new JAXBBlockContext(StockPrice.class, false);
+        
+        // Create the JAX-B object
+        ObjectFactory of = new ObjectFactory();
+        StockPrice obj = of.createStockPrice();
+        obj.setPrice("100");
+        
+        // Create the JAX-B Element
+        QName paramQName = new QName("urn://sample", "param", "m");
+        JAXBElement e = new JAXBElement(paramQName, StockPrice.class, obj);
+        
+        // Create a JAXBBlock using the param object as the content.  This simulates
+        // what occurs on the outbound JAX-WS Proxy client
+        Block block = bf.createFrom(e, context, null);
+        
+        // Add the block to the message as normal body content.
+        m.setBodyBlock(0, block);
+        
+        // Check to see if the message is a fault.  The client/server will always call this method.
+        // The Message must respond appropriately without doing a conversion.
+        boolean isFault = m.isFault();
+        assertTrue(!isFault);
+        assertTrue("XMLPart Representation is " + m.getXMLPartContentType(),
+                    "SPINE".equals(m.getXMLPartContentType()));
+        
+        // On an outbound flow, we need to convert the Message 
+        // to an OMElement, specifically an OM SOAPEnvelope, 
+        // so we can set it on the Axis2 MessageContext
+        org.apache.axiom.soap.SOAPEnvelope env = 
+            (org.apache.axiom.soap.SOAPEnvelope) m.getAsOMElement();
+        
+        // Check to see if the message is a fault.  The client/server will always call this method.
+        // The Message must respond appropriately without doing a conversion.
+        isFault = m.isFault();
+        assertTrue(!isFault);
+        assertTrue("XMLPart Representation is " + m.getXMLPartContentType(),
+                    "OM".equals(m.getXMLPartContentType()));
+        
+        // PERFORMANCE CHECK:
+        // The param in the body should be an OMSourcedElement
+        OMElement o = env.getBody().getFirstElement().getFirstElement();
+        assertTrue(o instanceof OMSourcedElementImpl);
+        assertTrue(((OMSourcedElementImpl)o).isExpanded() == false);
+        
+        // Serialize the Envelope using the same mechanism as the 
+        // HTTP client.
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        env.serializeAndConsume(baos, new OMOutputFormat());
+        
+        // To check that the output is correct, get the String contents of the 
+        // reader
+        String newText = baos.toString();
+        System.out.println(newText);
+        assertTrue(newText.contains("m:op"));
+        assertTrue(newText.contains("m:param"));
+        assertTrue(newText.contains("100"));
+        assertTrue(newText.contains("Envelope"));
+        assertTrue(newText.contains("Body"));
+    }
+    
+    
+    public void testJAXBInflow_soap11() throws Exception {
+		_testJAXBInflow(sampleEnvelope11);
+	}
+	public void testJAXBInflow_soap12() throws Exception {
+		_testJAXBInflow(sampleEnvelope12);
+	}
+	public void _testJAXBInflow(String sampleJAXBEnvelope) throws Exception {
+        // Create a SOAP OM out of the sample incoming XML.  This
+        // simulates what Axis2 will be doing with the inbound message. 
+        StringReader sr = new StringReader(sampleJAXBEnvelope);
+        XMLStreamReader inflow = inputFactory.createXMLStreamReader(sr);
+        StAXSOAPModelBuilder builder = new StAXSOAPModelBuilder(inflow, null);
+        OMElement omElement = builder.getSOAPEnvelope();
+        
+        // Create a SOAP 1.1 Message from the sample incoming XML
+        MessageFactory mf = (MessageFactory)
+            FactoryRegistry.getFactory(MessageFactory.class);
+        Message m = mf.createFrom(omElement);
+        
+        // Check to see if the message is a fault.  The client/server will always call this method.
+        // The Message must respond appropriately without doing a conversion.
+        boolean isFault = m.isFault();
+        assertTrue(!isFault);
+        assertTrue("XMLPart Representation is " + m.getXMLPartContentType(),
+                    "OM".equals(m.getXMLPartContentType()));
+        
+        // Indicate that the message should be accessed as RPC
+        m.setStyle(Style.RPC);
+        
+        // Get the BlockFactory
+        JAXBBlockFactory bf = (JAXBBlockFactory)
+            FactoryRegistry.getFactory(JAXBBlockFactory.class);
+        
+        // Create the JAXBContext instance that will be used
+        // to deserialize the JAX-B object content in the message.
+        JAXBBlockContext context = new JAXBBlockContext(StockPrice.class, true);
+        
+        // Get the JAXBBlock that wraps the content
+        Block b = m.getBodyBlock(0, context, bf);
+     
+        // Check to see if the message is a fault.  The client/server will always call this method.
+        // The Message must respond appropriately without doing a conversion.
+        isFault = m.isFault();
+        assertTrue(!isFault);
+        assertTrue("XMLPart Representation is " + m.getXMLPartContentType(),
+                    "SPINE".equals(m.getXMLPartContentType()));
+        
+        // Get the business object from the block, which should be a 
+        // JAX-B object
+        Object bo = b.getBusinessObject(true);
+        
+        // Check to make sure the right object was returned
+        assertNotNull(bo);
+        assertTrue(bo instanceof StockPrice);
+        
+        // Check to make sure the content of that object is correct
+        StockPrice obj = (StockPrice) bo;
+        assertNotNull(obj);
+        assertTrue(obj.getPrice().equals("100"));
+    }
+    
+}



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