You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by xu...@apache.org on 2011/07/11 10:57:25 UTC

svn commit: r1145074 [2/2] - in /geronimo/bundles/trunk/axis2: ./ src/main/java/org/apache/axis2/jaxws/message/ src/main/java/org/apache/axis2/jaxws/message/databinding/impl/ src/main/java/org/apache/axis2/jaxws/message/impl/

Added: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/message/impl/BlockImpl.java
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/message/impl/BlockImpl.java?rev=1145074&view=auto
==============================================================================
--- geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/message/impl/BlockImpl.java (added)
+++ geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/message/impl/BlockImpl.java Mon Jul 11 08:57:25 2011
@@ -0,0 +1,603 @@
+/*
+ * 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.message.impl;
+
+import org.apache.axiom.om.OMDataSourceExt;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMException;
+import org.apache.axiom.om.OMOutputFormat;
+import org.apache.axiom.om.ds.ByteArrayDataSource;
+import org.apache.axiom.om.impl.MTOMXMLStreamWriter;
+import org.apache.axiom.om.impl.builder.StAXOMBuilder;
+import org.apache.axiom.om.util.StAXUtils;
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.axis2.jaxws.message.Block;
+import org.apache.axis2.jaxws.message.Message;
+import org.apache.axis2.jaxws.message.factory.BlockFactory;
+import org.apache.axis2.jaxws.message.util.Reader2Writer;
+import org.apache.axis2.jaxws.spi.Constants;
+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 javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.ws.WebServiceException;
+import java.io.OutputStream;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.HashMap;
+
+/**
+ * BlockImpl Abstract Base class for various Block Implementations.
+ * <p/>
+ * The base class takes care of controlling the transformations between BusinessObject,
+ * XMLStreamReader and SOAPElement A derived class must minimally define the following:
+ * _getBOFromReader _getReaderFromBO _outputFromBO
+ * <p/>
+ * In addtion, the derived class may want to override the following: _getBOFromBO ...if the
+ * BusinessObject is consumed when read (i.e. it is an InputSource)
+ * <p/>
+ * The derived classes don't have direct access to the instance data. This ensures that BlockImpl
+ * controls the transformations.
+ */
+public abstract class BlockImpl implements Block {
+
+    private static Log log = LogFactory.getLog(BlockImpl.class);
+
+    protected Object busObject;
+    protected Object busContext;
+
+    protected OMElement omElement = null;
+
+    protected QName qName;
+    private boolean noQNameAvailable = false;
+    
+    protected BlockFactory factory;
+    protected boolean consumed = false;
+    protected Message parent;
+    
+    private HashMap map = null; // OMDataSourceExt properties
+
+    /**
+     * A Block has the following components
+     *
+     * @param busObject
+     * @param busContext or null
+     * @param qName      or null if unknown
+     * @param factory    that creates the Block
+     */
+    protected BlockImpl(Object busObject, Object busContext, QName qName, BlockFactory factory) {
+        this.busObject = busObject;
+        this.busContext = busContext;
+        this.qName = qName;
+        this.factory = factory;
+    }
+
+    /**
+     * A Block has the following components
+     *
+     * @param reader
+     * @param busContext or null
+     * @param qName      or null if unknown
+     * @param factory    that creates the Block
+     */
+    protected BlockImpl(OMElement omElement, Object busContext, QName qName, BlockFactory factory) {
+        this.omElement = omElement;
+        this.busContext = busContext;
+        this.qName = qName;
+        this.factory = factory;
+    }
+
+    /* (non-Javadoc)
+      * @see org.apache.axis2.jaxws.message.Block#getBlockFactory()
+      */
+    public BlockFactory getBlockFactory() {
+        return factory;
+    }
+
+    /* (non-Javadoc)
+      * @see org.apache.axis2.jaxws.message.Block#getBusinessContext()
+      */
+    public Object getBusinessContext() {
+        return busContext;
+    }
+
+    public Message getParent() {
+        return parent;
+    }
+
+    public void setParent(Message p) {
+        parent = p;
+    }
+
+    /* (non-Javadoc)
+      * @see org.apache.axis2.jaxws.message.Block#getBusinessObject(boolean)
+      */
+    public Object getBusinessObject(boolean consume)
+            throws XMLStreamException, WebServiceException {
+        if (consumed) {
+            throw ExceptionFactory.makeWebServiceException(
+                    Messages.getMessage("BlockImplErr1", this.getClass().getName()));
+        }
+        if (busObject != null) {
+            busObject = _getBOFromBO(busObject, busContext, consume);
+        } else {
+            // Transform reader into business object
+            busObject = _getBOFromOM(omElement, busContext);
+            omElement = null;
+        }
+
+        // Save the businessObject in a local variable
+        // so that we can reset the Block if consume was indicated
+        Object newBusObject = busObject;
+        setConsumed(consume);
+        return newBusObject;
+    }
+    
+
+    /* (non-Javadoc)
+      * @see org.apache.axis2.jaxws.message.Block#getQName()
+      */
+    public QName getQName() throws WebServiceException {
+        // If the QName is not known, find it
+        try {
+            if (qName == null) {
+                // If a prior call discovered that this content has no QName, then return null
+                if (noQNameAvailable) {
+                    return null;
+                }
+                if (omElement == null) {
+                    try {
+                        XMLStreamReader newReader = _getReaderFromBO(busObject, busContext);
+                        busObject = null;
+                        StAXOMBuilder builder = new StAXOMBuilder(newReader);
+                        omElement = builder.getDocumentElement();
+                        omElement.close(true);
+                    } catch (Exception e) {
+                        // Some blocks may represent non-element data
+                        if (log.isDebugEnabled()) {
+                            log.debug("Exception occurred while obtaining QName:" + e);
+                        } 
+                        if (!isXMLData() && !isElementData()) {
+                            // If this block can hold non-element data, then accept
+                            // the fact that there is no qname and continue
+                            if (log.isDebugEnabled()) {
+                                log.debug("The block does not contain an xml element. Processing continues.");
+                            }
+                            // Indicate that the content has no QName
+                            // The exception is swallowed.
+                            noQNameAvailable = true;
+                            return null;
+                        }  else {
+                            // The content should contain xml.  
+                            // Rethrowing the exception.
+                            throw ExceptionFactory.makeWebServiceException(e);
+                        }
+                    }
+                }
+                qName = omElement.getQName();
+            }
+            return qName;
+        } catch (Exception xse) {
+            setConsumed(true);
+            throw ExceptionFactory.makeWebServiceException(xse);
+        }
+    }
+
+    /**
+     * This method is intended for derived objects to set the qName
+     *
+     * @param qName
+     */
+    protected void setQName(QName qName) {
+        this.qName = qName;
+    }
+
+    /* (non-Javadoc)
+      * @see org.apache.axis2.jaxws.message.Block#getXMLStreamReader(boolean)
+      */
+    public XMLStreamReader getXMLStreamReader(boolean consume)
+            throws XMLStreamException, WebServiceException {
+        XMLStreamReader newReader = null;
+        if (consumed) {
+            // In some scenarios, the message is written out after the service instance is invoked.
+            // In these situations, it is preferable to simply ignore this block.
+            if (this.getParent() != null && getParent().isPostPivot()) {
+                return _postPivot_getXMLStreamReader();
+            }
+            throw ExceptionFactory.makeWebServiceException(
+                    Messages.getMessage("BlockImplErr1", this.getClass().getName()));
+        }
+        if (omElement != null) {
+            if (consume) {
+                if (omElement.getBuilder() != null && !omElement.getBuilder().isCompleted()) {
+                    newReader = omElement.getXMLStreamReaderWithoutCaching();
+                } else {
+                    newReader = omElement.getXMLStreamReader();
+                }
+                omElement = null;
+            } else {
+                newReader = omElement.getXMLStreamReader();
+            }
+        } else if (busObject != null) {
+            // Getting the reader does not destroy the BusinessObject
+            busObject = _getBOFromBO(busObject, busContext, consume);
+            newReader = _getReaderFromBO(busObject, busContext);
+        }
+        setConsumed(consume);
+        return newReader;
+    }
+
+    /* (non-Javadoc)
+      * @see org.apache.axiom.om.OMDataSource#getReader()
+      */
+    public XMLStreamReader getReader() throws XMLStreamException {
+        return getXMLStreamReader(true);
+    }
+
+    /* (non-Javadoc)
+      * @see org.apache.axiom.om.OMDataSource#serialize(java.io.OutputStream, org.apache.axiom.om.OMOutputFormat)
+      */
+    public void serialize(OutputStream output, OMOutputFormat format) throws XMLStreamException {
+        MTOMXMLStreamWriter writer = new MTOMXMLStreamWriter(output, format);
+        serialize(writer);
+        writer.flush();
+        try {
+            writer.close();
+        } catch (XMLStreamException e) {
+            // An exception can occur if nothing is written to the 
+            // writer.  This is possible if the underlying data source
+            // writers to the output stream directly.
+            if (log.isDebugEnabled()) {
+                log.debug("Catching and swallowing exception " + e);
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+      * @see org.apache.axiom.om.OMDataSource#serialize(java.io.Writer, org.apache.axiom.om.OMOutputFormat)
+      */
+    public void serialize(Writer writerTarget, OMOutputFormat format) throws XMLStreamException {
+        MTOMXMLStreamWriter writer =
+                new MTOMXMLStreamWriter(StAXUtils.createXMLStreamWriter(writerTarget));
+        writer.setOutputFormat(format);
+        serialize(writer);
+        writer.flush();
+        writer.close();
+    }
+
+    /* (non-Javadoc)
+      * @see org.apache.axiom.om.OMDataSource#serialize(javax.xml.stream.XMLStreamWriter)
+      */
+    public void serialize(XMLStreamWriter writer) throws XMLStreamException {
+        outputTo(writer, isDestructiveWrite());
+    }
+
+    public OMElement getOMElement() throws XMLStreamException, WebServiceException {
+        OMElement newOMElement = null;
+        boolean consume = true;  // get the OM consumes the message
+        if (consumed) {
+            throw ExceptionFactory.makeWebServiceException(
+                    Messages.getMessage("BlockImplErr1", this.getClass().getName()));
+        }
+        if (omElement != null) {
+            newOMElement = omElement;
+        } else if (busObject != null) {
+            // Getting the reader does not destroy the BusinessObject
+            busObject = _getBOFromBO(busObject, busContext, consume);
+            newOMElement = _getOMFromBO(busObject, busContext);
+        }
+        setConsumed(consume);
+        return newOMElement;
+    }
+    
+
+    /* (non-Javadoc)
+      * @see org.apache.axis2.jaxws.message.Block#isConsumed()
+      */
+    public boolean isConsumed() {
+        return consumed;
+    }
+
+    /**
+     * Once consumed, all instance data objects are nullified to prevent subsequent access
+     *
+     * @param consume
+     * @return
+     */
+    public void setConsumed(boolean consume) {
+        if (consume) {
+            this.consumed = true;
+            busObject = null;
+            busContext = null;
+            omElement = null;
+            if (log.isDebugEnabled()) {
+                // The following stack trace consumes indicates where the message is consumed
+                log.debug("Message Block Monitor: Action=Consumed");
+                log.trace(JavaUtils.stackToString());
+            }
+        } else {
+            consumed = false;
+        }
+    }
+
+    public boolean isQNameAvailable() {
+        return (qName != null);
+    }
+
+    public void outputTo(XMLStreamWriter writer, boolean consume)
+            throws XMLStreamException, WebServiceException {
+        if (log.isDebugEnabled()) {
+            log.debug("Start outputTo");
+        }
+        if (consumed) {
+            // In some scenarios, the message is written out after the service instance is invoked.
+            // In these situations, it is preferable to simply ignore this block.
+            if (this.getParent() != null && getParent().isPostPivot()) {
+                _postPivot_outputTo(writer);
+            }
+            throw ExceptionFactory.makeWebServiceException(
+                    Messages.getMessage("BlockImplErr1", this.getClass().getName()));
+        }
+        if (omElement != null) {
+            _outputFromOM(omElement, writer, consume);
+        } else if (busObject != null) {
+            if (log.isDebugEnabled()) {
+                log.debug("Write business object");
+            }
+            busObject = _getBOFromBO(busObject, busContext, consume);
+            _outputFromBO(busObject, busContext, writer);
+        }
+        setConsumed(consume);
+        if (log.isDebugEnabled()) {
+            log.debug("End outputTo");
+        }
+        return;
+    }
+
+    /**
+     * Called if we have passed the pivot point but someone wants to output the block. The actual
+     * block implementation may choose to override this setting
+     */
+    protected void _postPivot_outputTo(XMLStreamWriter writer)
+            throws XMLStreamException, WebServiceException {
+        if (log.isDebugEnabled()) {
+            QName theQName = isQNameAvailable() ? getQName() : new QName("unknown");
+            log.debug("The Block for " + theQName +
+                    " is already consumed and therefore it is not written.");
+            log.debug("If you need this block preserved, please set the " + Constants
+                    .SAVE_REQUEST_MSG + " property on the MessageContext.");
+        }
+        return;
+    }
+
+    /**
+     * Called if we have passed the pivot point but someone wants to output the block. The actual
+     * block implementation may choose to override this setting.
+     */
+    protected XMLStreamReader _postPivot_getXMLStreamReader()
+            throws XMLStreamException, WebServiceException {
+        if (log.isDebugEnabled()) {
+            QName theQName = isQNameAvailable() ? getQName() : new QName("unknown");
+            log.debug("The Block for " + theQName +
+                    " is already consumed and therefore it is only partially read.");
+            log.debug("If you need this block preserved, please set the " + Constants
+                    .SAVE_REQUEST_MSG + " property on the MessageContext.");
+        }
+        QName qName = getQName();
+        String text = "";
+        if (qName.getNamespaceURI().length() > 0) {
+            text = "<prefix:" + qName.getLocalPart() + " xmlns:prefix='" + qName.getNamespaceURI() +
+                    "'/>";
+        } else {
+            text = "<" + qName.getLocalPart() + "/>";
+        }
+        StringReader sr = new StringReader(text);
+        return StAXUtils.createXMLStreamReader(sr);
+    }
+
+    /**
+     * @return true if the representation of the block is currently a business object. Derived classes
+     *         may use this information to get information in a performant way.
+     */
+    protected boolean isBusinessObject() {
+        return busObject != null;
+    }
+
+    public String traceString(String indent) {
+        // TODO add trace string
+        return null;
+    }
+
+    /**
+     * The default implementation is to return the business object. A derived block may want to
+     * override this class if the business object is consumed when read (thus the dervived block may
+     * want to make a buffered copy) (An example use case for overriding this method is the
+     * businessObject is an InputSource)
+     *
+     * @param busObject
+     * @param busContext
+     * @param consume
+     * @return
+     */
+    protected Object _getBOFromBO(Object busObject, Object busContext, boolean consume) {
+        return busObject;
+    }
+
+
+    /**
+     * The derived class must provide an implementation that builds the business object from the
+     * reader
+     *
+     * @param reader     XMLStreamReader, which is consumed
+     * @param busContext
+     * @return
+     */
+    protected abstract Object _getBOFromReader(XMLStreamReader reader, Object busContext)
+            throws XMLStreamException, WebServiceException;
+
+    
+    /**
+     * Default method for getting business object from OM.
+     * Derived classes may override this method to get the business object from a
+     * data source.
+     * 
+     * @param om
+     * @param busContext
+     * @return Business Object
+     * @throws XMLStreamException
+     * @throws WebServiceException
+     */
+    protected Object _getBOFromOM(OMElement omElement, Object busContext)
+        throws XMLStreamException, WebServiceException {
+        XMLStreamReader reader = _getReaderFromOM(omElement);
+        return _getBOFromReader(reader, busContext);
+    }
+    
+    /**
+     * Get an XMLStreamReader for the BusinessObject The derived Block must implement this method
+     *
+     * @param busObj
+     * @param busContext
+     * @return
+     */
+    protected abstract XMLStreamReader _getReaderFromBO(Object busObj, Object busContext)
+            throws XMLStreamException, WebServiceException;
+    
+    /**
+     * @param omElement
+     * @return XMLStreamReader
+     */
+    protected XMLStreamReader _getReaderFromOM(OMElement omElement) {
+        XMLStreamReader reader;
+        if (omElement.getBuilder() != null && !omElement.getBuilder().isCompleted()) {
+            reader = omElement.getXMLStreamReaderWithoutCaching();
+        } else {
+            reader = omElement.getXMLStreamReader();
+        }
+        return reader;
+    }
+    
+    /**
+     * @param busObject
+     * @param busContext
+     * @return OMElement
+     * @throws XMLStreamException
+     * @throws WebServiceException
+     */
+    protected OMElement _getOMFromBO(Object busObject, Object busContext)
+        throws XMLStreamException, WebServiceException {
+        // Getting the reader does not destroy the BusinessObject
+        XMLStreamReader newReader = _getReaderFromBO(busObject, busContext);
+        StAXOMBuilder builder = new StAXOMBuilder(newReader);
+        return builder.getDocumentElement();
+    }
+
+    /**
+     * Output Reader contents to a Writer. The default implementation is probably sufficient for most
+     * derived classes.
+     *
+     * @param reader
+     * @param writer
+     * @throws XMLStreamException
+     */
+    protected void _outputFromReader(XMLStreamReader reader, XMLStreamWriter writer)
+            throws XMLStreamException {
+        Reader2Writer r2w = new Reader2Writer(reader);
+        r2w.outputTo(writer);
+    }
+    
+    /**
+     * Output OMElement contents to a Writer. The default implementation is probably sufficient for most
+     * derived classes.
+     *
+     * @param om
+     * @param writer
+     * @throws XMLStreamException
+     */
+    protected void _outputFromOM(OMElement omElement, XMLStreamWriter writer, boolean consume)
+            throws XMLStreamException {
+        if (consume) {
+            if (log.isDebugEnabled()) {
+                log.debug("Write using OMElement.serializeAndConsume");
+            }
+            omElement.serializeAndConsume(writer);
+        } else {
+            if (log.isDebugEnabled()) {
+                log.debug("Write Using OMElement.serialize");
+            }
+            omElement.serialize(writer);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.apache.axiom.om.OMDataSourceExt#copy()
+     */
+    public OMDataSourceExt copy() throws OMException {
+        // TODO: This is a default implementation.  Much
+        // more refactoring needs to occur to account for attachments.
+        try {
+            String encoding = "utf-8"; // Choose a common encoding
+            byte[] bytes = this.getXMLBytes(encoding);
+            return new ByteArrayDataSource(bytes, encoding);
+        } catch (UnsupportedEncodingException e) {
+            throw new OMException(e);
+        }
+    }
+
+    /**
+     * Output BusinessObject contents to a Writer.
+     * Derived classes must provide this implementation
+     * @param busObject
+     * @param busContext
+     * @param writer
+     * @throws XMLStreamException
+     * @throws WebServiceException
+     */
+    protected abstract void _outputFromBO(Object busObject, Object busContext,
+                                          XMLStreamWriter writer)
+            throws XMLStreamException, WebServiceException;
+	
+    public Object getProperty(String key) {
+        if (map == null) {
+            return null;
+        }
+        return map.get(key);
+    }
+
+    public Object setProperty(String key, Object value) {
+        if (map == null) {
+            map = new HashMap();
+        }
+        return map.put(key, value);
+    }
+
+    public boolean hasProperty(String key) {
+        if (map == null) {
+            return false;
+        } 
+        return map.containsKey(key);
+    }
+}

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/message/impl/BlockImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/message/impl/BlockImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/message/impl/BlockImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java?rev=1145074&view=auto
==============================================================================
--- geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java (added)
+++ geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java Mon Jul 11 08:57:25 2011
@@ -0,0 +1,812 @@
+/*
+ * 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.message.impl;
+
+import org.apache.axiom.om.OMContainer;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMNamespace;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.impl.OMContainerEx;
+import org.apache.axiom.soap.RolePlayer;
+import org.apache.axiom.soap.SOAP11Constants;
+import org.apache.axiom.soap.SOAP12Constants;
+import org.apache.axiom.soap.SOAPBody;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.SOAPFactory;
+import org.apache.axiom.soap.SOAPFault;
+import org.apache.axiom.soap.SOAPFaultDetail;
+import org.apache.axiom.soap.SOAPHeader;
+import org.apache.axiom.soap.SOAPHeaderBlock;
+import org.apache.axiom.soap.impl.llom.soap11.SOAP11Factory;
+import org.apache.axiom.soap.impl.llom.soap12.SOAP12Factory;
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.axis2.jaxws.message.Block;
+import org.apache.axis2.jaxws.message.Message;
+import org.apache.axis2.jaxws.message.Protocol;
+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.message.util.XMLFaultUtils;
+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.jws.soap.SOAPBinding.Style;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+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
+ * <p/>
+ * An XMLSpine consists is an OMEnvelope (either a default one or one create from an incoming
+ * message). As Blocks are added or requested, they are placed in the tree as OMSourcedElements.
+ * <p/>
+ * NOTE: For XML/HTTP (REST) messages, a SOAP 1.1 envelope is built and the xml payload is 
+ * placed in the body.  This purposely mimics the implementation used by Axis2.
+ */
+class XMLSpineImpl implements XMLSpine {
+
+    private static Log log = LogFactory.getLog(XMLSpineImpl.class);
+    private static OMBlockFactory obf =
+            (OMBlockFactory)FactoryRegistry.getFactory(OMBlockFactory.class);
+
+    private Protocol protocol = Protocol.unknown;
+    private Style style = Style.DOCUMENT;
+    private int indirection = 0;
+    private SOAPEnvelope root = null;
+    private SOAPFactory soapFactory = null;
+
+    private boolean consumed = false;
+    private Message parent = null;
+
+    /**
+     * Create a lightweight representation of this protocol (i.e. the Envelope, Header and Body)
+     *
+     * @param protocol       Protocol
+     * @param style          Style
+     * @param indirection    (0 or 1) indicates location of body blocks
+     * @param initialPayload (OMElement or null...used to add rest payload)
+     */
+    public XMLSpineImpl(Protocol protocol, Style style, int indirection, OMElement payload) {
+        super();
+        this.protocol = protocol;
+        this.style = style;
+        this.indirection = indirection;
+        soapFactory = _getFactory(protocol);
+        root = _createEmptyEnvelope(style, soapFactory);
+        if (payload != null) {
+            ((SOAPEnvelope)root).getBody().addChild(payload);
+        }
+    }
+
+    /**
+     * Create spine from an existing OM tree
+     *
+     * @param envelope
+     * @param style       Style
+     * @param indirection (0 or 1) indicates location of body blocks
+     * @throws WebServiceException
+     */
+    public XMLSpineImpl(SOAPEnvelope envelope, Style style, int indirection, Protocol protocol)
+            throws WebServiceException {
+        super();
+        this.style = style;
+        this.indirection = indirection;
+        this.protocol = protocol;
+        init(envelope);
+        // If null, detect protocol from soap namespace
+        if (protocol == null) {
+            if (root.getNamespace().getNamespaceURI()
+                    .equals(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
+                this.protocol = Protocol.soap11;
+            } else if (root.getNamespace().getNamespaceURI()
+                    .equals(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI)) {
+                this.protocol = Protocol.soap12;
+            }
+        }
+    }
+
+    /**
+     * @param envelope
+     * @throws WebServiceException
+     */
+    private void init(SOAPEnvelope envelope) throws WebServiceException {
+        root = envelope;
+        soapFactory = MessageUtils.getSOAPFactory(root);
+
+        // Advance past the header
+        SOAPHeader header = root.getHeader();
+        if (header == null) {
+            header = soapFactory.createSOAPHeader(root);
+        }
+
+        // Now advance the parser to the body element
+        SOAPBody body = root.getBody();
+        if (body == null) {
+            // Create the body if one does not exist
+            body = soapFactory.createSOAPBody(root);
+        }
+    }
+
+
+    /* (non-Javadoc)
+      * @see org.apache.axis2.jaxws.message.XMLPart#getProtocol()
+      */
+    public Protocol getProtocol() {
+        return protocol;
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see org.apache.axis2.jaxws.message.XMLPart#getParent()
+    */
+    public Message getParent() {
+        return parent;
+    }
+
+    /*
+    * Set the backpointer to this XMLPart's parent Message
+    */
+    public void setParent(Message p) {
+        parent = p;
+    }
+
+    /* (non-Javadoc)
+      * @see org.apache.axis2.jaxws.message.XMLPart#outputTo(javax.xml.stream.XMLStreamWriter, 
+      * boolean)
+      */
+    public void outputTo(XMLStreamWriter writer, boolean consume)
+            throws XMLStreamException, WebServiceException {
+        Reader2Writer r2w = new Reader2Writer(getXMLStreamReader(consume));
+        r2w.outputTo(writer);
+    }
+
+    public XMLStreamReader getXMLStreamReader(boolean consume) throws WebServiceException {
+        if (consume) {
+            if (root.getBuilder() != null && !root.getBuilder().isCompleted()) {
+                return root.getXMLStreamReaderWithoutCaching();
+            } else {
+                return root.getXMLStreamReader();
+            }
+        } else {
+            return root.getXMLStreamReader();
+        }
+    }
+
+    /* (non-Javadoc)
+      * @see org.apache.axis2.jaxws.message.impl.XMLSpine#getXMLFault()
+      */
+    public XMLFault getXMLFault() throws WebServiceException {
+        if (!isFault()) {
+            return null;
+        }
+
+        // Advance through all of the detail blocks
+        int numDetailBlocks = getNumDetailBlocks();
+
+        Block[] blocks = null;
+        if (numDetailBlocks > 0) {
+            blocks = new Block[numDetailBlocks];
+            SOAPFaultDetail detail = root.getBody().getFault().getDetail();
+            for (int i = 0; i < numDetailBlocks; i++) {
+                OMElement om = this._getChildOMElement(detail, i);
+                blocks[i] = this._getBlockFromOMElement(om, null, obf, false);
+
+            }
+        }
+
+        XMLFault xmlFault = XMLFaultUtils.createXMLFault(root.getBody().getFault(), blocks);
+        return xmlFault;
+    }
+
+    private int getNumDetailBlocks() throws WebServiceException {
+        if (isFault()) {
+            SOAPFault fault = root.getBody().getFault();
+            return _getNumChildElements(fault.getDetail());
+        }
+        return 0;
+    }
+
+    public void setXMLFault(XMLFault xmlFault) throws WebServiceException {
+
+        // Clear out the existing body and detail blocks
+        SOAPBody body = root.getBody();
+        getNumDetailBlocks(); // Forces parse of existing detail blocks
+        getNumBodyBlocks();  // Forces parse over body
+        OMNode child = body.getFirstOMChild();
+        while (child != null) {
+            child.detach();
+            child = body.getFirstOMChild();
+        }
+
+        // Add a SOAPFault to the body.
+        SOAPFault soapFault = XMLFaultUtils.createSOAPFault(xmlFault, body, false);
+    }
+
+    public boolean isConsumed() {
+        return consumed;
+    }
+
+    public OMElement getAsOMElement() throws WebServiceException {
+        return root;
+    }
+
+
+    /* (non-Javadoc)
+      * @see org.apache.axis2.jaxws.message.XMLPart#getNumBodyBlocks()
+      */
+    public int getNumBodyBlocks() throws WebServiceException {
+        return _getNumChildElements(_getBodyBlockParent());
+    }
+    
+    /**
+     * getBodyBlockQNames 
+     * Calling this method will cache the OM.  Avoid it in performant situations.
+     *
+     * @return List of QNames
+     * @throws WebServiceException
+     */
+    public List<QName> getBodyBlockQNames() throws WebServiceException {
+        int numBlocks = getNumBodyBlocks();
+        List<QName> qNames = new ArrayList<QName>();
+        
+        for (int i =0; i< numBlocks; i++ ) {
+            OMElement omElement = _getChildOMElement(_getBodyBlockParent(), i);
+            if (omElement != null) {
+                qNames.add(omElement.getQName());
+            } 
+        }
+        return qNames;
+    }
+
+
+    /* (non-Javadoc)
+      * @see org.apache.axis2.jaxws.message.impl.XMLSpine#getBodyBlock(int, java.lang.Object, 
+      * org.apache.axis2.jaxws.message.factory.BlockFactory)
+      */
+    public Block getBodyBlock(int index, Object context, BlockFactory blockFactory)
+            throws WebServiceException {
+
+        if (log.isDebugEnabled()) {
+            log.debug("getBodyBlock: Get the " + index + "block using the block factory, " +
+                    blockFactory);
+        }
+
+        // Forces the parser to read all of the blocks
+        getNumBodyBlocks();
+
+        // Get the indicated block
+        OMElement omElement = _getChildOMElement(_getBodyBlockParent(), index);
+        if (omElement == null) {
+            // Null indicates that no block is available
+            if (log.isDebugEnabled()) {
+                log.debug("getBodyBlock: The block was not found ");
+            }
+            return null;
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("getBodyBlock: Found omElement " + omElement.getQName());
+        }
+        return this._getBlockFromOMElement(omElement, context, blockFactory, false);
+    }
+
+    /* (non-Javadoc)
+    * @see org.apache.axis2.jaxws.message.impl.XMLSpine#getBodyBlock(int, java.lang.Object, 
+    * org.apache.axis2.jaxws.message.factory.BlockFactory)
+    */
+    public Block getBodyBlock(Object context, BlockFactory blockFactory)
+            throws WebServiceException {
+
+        if (log.isDebugEnabled()) {
+            log.debug("getBodyBlock PERFORMANT: Get the block using the block factory, " +
+                    blockFactory);
+        }
+
+        // TODO Need to upgrade the code to get Blocks that represent text and elements.
+
+        // Calling getBodyBlock assumes that there is only one or zero body blocks in the message.
+        // Subsequent Blocks are lost.  If the caller needs access to multiple body blocks, 
+        // then getBodyBlocks(index,...) should be used
+
+        // Get the indicated block
+        OMElement omElement = _getChildOMElement(_getBodyBlockParent(), 0);
+        if (omElement == null) {
+            // Null indicates that no block is available
+            if (log.isDebugEnabled()) {
+                log.debug("getBodyBlock: The block was not found ");
+            }
+            return null;
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("getBodyBlock: Found omElement " + omElement.getQName());
+        }
+        return this._getBlockFromOMElement(omElement, context, blockFactory, true);
+    }
+
+    public void setBodyBlock(int index, Block block) throws WebServiceException {
+
+        // Forces the parser to read all of the blocks
+        getNumBodyBlocks();
+
+        block.setParent(getParent());
+        OMElement bElement = _getBodyBlockParent();
+        OMElement om = this._getChildOMElement(bElement, index);
+
+        // The block is supposed to represent a single element.  
+        // But if it does not represent an element , the following will fail.
+        QName qName = block.getQName();
+        OMNamespace ns = soapFactory.createOMNamespace(qName.getNamespaceURI(), 
+                                                       qName.getPrefix());
+
+        OMElement newOM = _createOMElementFromBlock(qName.getLocalPart(), ns, block, 
+                                                    soapFactory, false);
+        if (om == null) {
+            bElement.addChild(newOM);
+        } else {
+            om.insertSiblingBefore(newOM);
+            om.detach();
+        }
+    }
+
+    public void setBodyBlock(Block block) throws WebServiceException {
+
+        // Forces the parser to read all of the blocks
+        getNumBodyBlocks();
+
+        block.setParent(getParent());
+
+        // Remove all of the children
+        OMElement bElement = _getBodyBlockParent();
+        Iterator it = bElement.getChildren();
+        while (it.hasNext()) {
+            it.next();
+            it.remove();
+        }
+
+        if (block.isElementData()) {
+            // If the block is element data then  it is safe to create
+            // an OMElement representing the block
+
+            // The block is supposed to represent a single element.  
+            // But if it does not represent an element , the following will fail.
+            QName qName = block.getQName();
+            OMNamespace ns = soapFactory.createOMNamespace(qName.getNamespaceURI(), 
+                                                           qName.getPrefix());
+
+            OMElement newOM = _createOMElementFromBlock(qName.getLocalPart(), ns,
+                                                        block, soapFactory, false);
+            bElement.addChild(newOM);
+        } else {
+            // This needs to be fixed, but for now we will require that there must be an 
+            // element...otherwise no block is added
+            try {
+                QName qName = block.getQName();
+                OMNamespace ns = soapFactory.createOMNamespace(qName.getNamespaceURI(), 
+                                                               qName.getPrefix());
+
+                OMElement newOM = _createOMElementFromBlock(qName.getLocalPart(), ns,
+                                                            block, soapFactory, false);
+                bElement.addChild(newOM);
+            } catch (Throwable t) {
+                if((t instanceof WebServiceException) && block.isXMLData()) {
+                    throw (WebServiceException)t;
+                }
+                if (log.isDebugEnabled()) {
+                    log.debug(
+                            "An attempt was made to pass a Source or String that does not " +
+                            "have an xml element. Processing continues with an empty payload.");
+                }
+            }
+        }
+    }
+
+    public void removeBodyBlock(int index) throws WebServiceException {
+        // Forces the parser to read all of the blocks
+        getNumBodyBlocks();
+
+        OMElement om = this._getChildOMElement(_getBodyBlockParent(), index);
+        if (om != null) {
+            om.detach();
+        }
+    }
+
+    public int getNumHeaderBlocks() throws WebServiceException {
+        return _getNumChildElements(root.getHeader());
+    }
+
+    public Block getHeaderBlock(String namespace, String localPart, Object context,
+                                BlockFactory blockFactory) throws WebServiceException {
+        OMElement om = _getChildOMElement(root.getHeader(), namespace, localPart);
+        if (om == null) {
+            return null;
+        }
+        return this._getBlockFromOMElement(om, context, blockFactory, false);
+    }
+
+    public List<Block> getHeaderBlocks(String namespace, 
+                                       String localPart, 
+                                       Object context, 
+                                       BlockFactory blockFactory, 
+                                       RolePlayer rolePlayer) throws WebServiceException {
+        List<Block> blocks = new ArrayList<Block>();
+        
+        // Get the list of OMElements that have the same header name
+        SOAPHeader header = root.getHeader();
+        if (header == null) {
+            return blocks;
+        }
+        
+        // Get an iterator over the headers that have a acceptable role
+        Iterator it = null;
+        if (rolePlayer == null) {
+            it = header.getChildElements();
+        } else {
+            it = header.getHeadersToProcess(rolePlayer);
+        }
+        while (it.hasNext()) {
+            OMElement om = (OMElement) it.next();
+            // Create a block out of each header that matches 
+            // the requested namespace/localPart
+            if (om.getNamespace().getNamespaceURI().equals(namespace) &&
+                om.getLocalName().equals(localPart)) {
+                Block block = _getBlockFromOMElement(om, context, blockFactory, false);
+                blocks.add(block);
+            }
+        }
+        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());
+        OMNamespace ns = soapFactory.createOMNamespace(namespace, null);
+        OMElement newOM =
+                _createOMElementFromBlock(localPart, ns, block, soapFactory, true);
+        OMElement om = this._getChildOMElement(root.getHeader(), namespace, localPart);
+        if (om == null) {
+            if (root.getHeader() == null) {
+                soapFactory.createSOAPHeader(root);
+            }
+            root.getHeader().addChild(newOM);
+        } else {
+            om.insertSiblingBefore(newOM);
+            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);
+        while (om != null) {
+            om.detach();
+            om = this._getChildOMElement(root.getHeader(), namespace, localPart);
+        }
+    }
+
+    public String traceString(String indent) {
+        // TODO Trace String Support
+        return null;
+    }
+
+    public String getXMLPartContentType() {
+        return "SPINE";
+    }
+
+    public boolean isFault() throws WebServiceException {
+        return XMLFaultUtils.isFault(root);
+    }
+
+    public Style getStyle() {
+        return style;
+    }
+
+    public QName getOperationElement() {
+        OMElement omElement = this._getBodyBlockParent();
+        if (omElement instanceof SOAPBody) {
+            return null;
+        } else {
+            return omElement.getQName();
+        }
+    }
+
+    public void setOperationElement(QName operationQName) {
+        OMElement opElement = this._getBodyBlockParent();
+        if (!(opElement instanceof SOAPBody)) {
+            OMNamespace ns = soapFactory.createOMNamespace(operationQName.getNamespaceURI(),
+                                                           operationQName.getPrefix());
+            opElement.setLocalName(operationQName.getLocalPart());
+            opElement.setNamespace(ns);
+            
+            // Necessary to avoid duplicate namespaces later.
+            opElement.declareNamespace("http://www.w3.org/2001/XMLSchema-instance", "xsi");
+        }
+    }
+
+    private Block _getBlockFromOMElement(OMElement om, Object context, BlockFactory blockFactory,
+                                         boolean setComplete) throws WebServiceException {
+        try {
+            QName qName = om.getQName();
+            OMNamespace ns = om.getNamespace();
+            
+            // Save the ROLE
+            // TODO Need to do the same for RELAY and MUSTUNDERSTAND
+            String role = null;
+            if (om instanceof SOAPHeaderBlock) {
+                role = ((SOAPHeaderBlock)om).getRole();
+            }
+            
+            /* TODO We could gain performance if OMSourcedElement exposed a getDataSource method 
+             if (om instanceof OMSourcedElementImpl &&
+             ((OMSourcedElementImpl) om).getDataSource() instanceof Block) {
+             Block oldBlock = (Block) ((OMSourcedElementImpl) om).getDataSource();
+             Block newBlock = blockFactory.createFrom(oldBlock, context);
+             newBlock.setParent(getParent());
+             if (newBlock != oldBlock) {
+             // Replace the OMElement with the OMSourcedElement that delegates to the block
+              OMSourcedElementImpl newOM = new OMSourcedElementImpl(qName, soapFactory, newBlock);
+              om.insertSiblingBefore(newOM);
+              om.detach();
+              }
+              return newBlock;
+              } 
+              */
+
+            // Create the block
+            Block block = blockFactory.createFrom(om, context, qName);
+            block.setParent(getParent());
+            if (om instanceof SOAPHeaderBlock) {
+                block.setProperty(SOAPHeaderBlock.ROLE_PROPERTY, role);
+            }
+
+            // Get the business object to force a parse
+            block.getBusinessObject(false);
+
+            // Replace the OMElement with the OMSourcedElement that delegates to the block
+            OMElement newOM = _createOMElementFromBlock(qName.getLocalPart(), ns, block, soapFactory, 
+                                                            (om.getParent() instanceof SOAPHeader));
+            om.insertSiblingBefore(newOM);
+
+            // We want to set the om element and its parents to complete to 
+            // shutdown the parsing.  
+            if (setComplete) {
+                
+                // Get the root of the document
+                OMElement root = om;
+                while(root.getParent() instanceof OMElement) {
+                    root = (OMElement) root.getParent();
+                }
+                
+                try {   
+                    if (!root.isComplete() && root.getBuilder() != null && 
+                            !root.getBuilder().isCompleted()) {
+                        // Forward the parser to the end so it will close
+                        while (root.getBuilder().next() != XMLStreamConstants.END_DOCUMENT) {
+                            //do nothing
+                        }                    
+                    }
+                } catch (Exception e) {
+                    // Log and continue
+                    if (log.isDebugEnabled()) {
+                        log.debug("Builder next error:" + e.getMessage());
+                        log.trace(JavaUtils.stackToString(e));
+                    }
+                    
+                }
+                
+
+                OMContainer o = om;
+                while (o != null && o instanceof OMContainerEx) {
+                    ((OMContainerEx)o).setComplete(true);
+                    if ((o instanceof OMNode) &&
+                            (((OMNode)o).getParent()) instanceof OMContainer) {
+                        o = ((OMNode)o).getParent();
+                    } else {
+                        o = null;
+                    }
+                }
+            }
+
+
+            om.detach();
+            return block;
+        } catch (XMLStreamException xse) {
+            throw ExceptionFactory.makeWebServiceException(xse);
+        }
+    }
+
+    private static OMElement _createOMElementFromBlock(String localName, OMNamespace ns, Block b,
+                                                       SOAPFactory soapFactory, boolean isHeaderBlock) {
+        if (isHeaderBlock) {
+            return soapFactory.createSOAPHeaderBlock(localName, ns, b);
+        } else {
+            return soapFactory.createOMElement(b, localName, ns);
+        }
+        
+    }
+
+    /**
+     * Gets the OMElement that is the parent of where the the body blocks are located
+     *
+     * @return
+     */
+    private OMElement _getBodyBlockParent() {
+        SOAPBody body = root.getBody();
+        if (!body.hasFault() && indirection == 1) {
+            //  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);
+            }
+            return op;
+        }
+        return body;
+    }
+
+    /**
+     * Create a factory for the specified protocol
+     *
+     * @param protocol
+     * @return
+     */
+    private static SOAPFactory _getFactory(Protocol protocol) {
+        SOAPFactory soapFactory;
+        if (protocol == Protocol.soap11) {
+            soapFactory = new SOAP11Factory();
+        } else if (protocol == Protocol.soap12) {
+            soapFactory = new SOAP12Factory();
+        } else if (protocol == Protocol.rest) {
+            // For REST, create a SOAP 1.1 Envelope to contain the message
+            // This is consistent with Axis2.
+            soapFactory = new SOAP11Factory();
+        } else {
+            throw ExceptionFactory
+                    .makeWebServiceException(Messages.getMessage("RESTIsNotSupported"), null);
+        }
+        return soapFactory;
+    }
+
+    /**
+     * Create an emtpy envelope
+     *
+     * @param protocol
+     * @param style
+     * @param factory
+     * @return
+     */
+    private static SOAPEnvelope _createEmptyEnvelope(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;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.axis2.jaxws.message.XMLPart#getNumBodyBlocks()
+     */
+    private static int _getNumChildElements(OMElement om) throws WebServiceException {
+        // Avoid calling this method.  It advances the parser.
+        if (om == null) {
+            return 0;
+        }
+        int num = 0;
+        Iterator iterator = om.getChildElements();
+        while (iterator.hasNext()) {
+            num++;
+            iterator.next();
+        }
+        return num;
+    }
+
+    /**
+     * Get the child om at the indicated index
+     *
+     * @param om
+     * @param index
+     * @return child om or null
+     */
+    private static OMElement _getChildOMElement(OMElement om, int index) {
+        if (om == null) {
+            return null;
+        }
+        int i = 0;
+        for (OMNode child = om.getFirstOMChild();
+             child != null;
+             child = child.getNextOMSibling()) {
+            if (child instanceof OMElement) {
+                if (i == index) {
+                    return (OMElement)child;
+                }
+                i++;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Get the child om at the indicated index
+     *
+     * @param om
+     * @param namespace,
+     * @param localPart
+     * @return child om or null
+     */
+    private static OMElement _getChildOMElement(OMElement om, String namespace, 
+                                                String localPart) {
+        if (om == null) {
+            return null;
+        }
+        QName qName = new QName(namespace, localPart);
+        Iterator it = om.getChildrenWithName(qName);
+        if (it != null && it.hasNext()) {
+            return (OMElement)it.next();
+        }
+        return null;
+    }
+}

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain