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