You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by di...@apache.org on 2007/04/26 07:19:33 UTC

svn commit: r532615 [5/13] - in /webservices/axis2/branches/java/1_2/modules: jaxws-api/src/javax/xml/ws/handler/soap/ jaxws-api/src/javax/xml/ws/soap/ jaxws/ jaxws/src/org/apache/axis2/jaxws/ jaxws/src/org/apache/axis2/jaxws/binding/ jaxws/src/org/apa...

Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/Message.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/Message.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/Message.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/Message.java Wed Apr 25 22:19:23 2007
@@ -16,6 +16,7 @@
  */
 package org.apache.axis2.jaxws.message;
 
+import org.apache.axis2.jaxws.core.MessageContext;
 import org.apache.axis2.jaxws.message.factory.BlockFactory;
 
 import javax.activation.DataHandler;
@@ -23,6 +24,7 @@
 import javax.xml.soap.SOAPMessage;
 import javax.xml.ws.WebServiceException;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Message
@@ -52,54 +54,49 @@
     public SOAPMessage getAsSOAPMessage() throws WebServiceException;
 
     /**
-     * Adds an attachment part to the message
-     *
-     * @param Attachment - the content to add
-     */
-    public void addAttachment(Attachment a);
-
-    /**
-     * Create an Attachment. After the Attachment is created, it must be added with addAttachment()
-     *
+     * Add Attachment
      * @param dh DataHandler (type of Attachment is inferred from dh.getContentType)
-     * @param id String which is the Attachment id
-     * @return Attachment
+     * @param id String which is the Attachment content id
      * @see addAttachment(Attachment)
      */
-    public Attachment createAttachment(DataHandler dh, String id);
-
+    public void addDataHandler(DataHandler dh, String id);
+    
     /**
-     * Get the list of attachments for the message
-     *
-     * @return List<Attachments>
+     * Get the list of attachment content ids for the message
+     * @return Set<String>
      */
-    public List<Attachment> getAttachments();
-
+    public Set<String> getAttachmentIDs();
+    
     /**
-     * Get the attachment identified by the contentID
-     *
+     * Get the attachment identified by the contentID 
      * @param cid
      * @return
      */
-    public Attachment getAttachment(String cid);
-
-    /**
+    public DataHandler getDataHandler(String cid);
+    
+    /** 
      * Get the attachment and remove it from the Message
-     *
      * @param cid
-     * @return
      */
-    public Attachment removeAttachment(String cid);
-
-    /** @return if this is an MTOM message */
+    public DataHandler removeDataHandler(String cid);
+    
+    /**
+     * A message is MTOM enabled if the 
+     * associated dispatch/client/impl/provider has a binding type 
+     * that enables MTOM.
+     * @return if this is an MTOM message
+     */
     public boolean isMTOMEnabled();
 
-    /**
+    /** 
+     * A message is MTOM enabled if the 
+     * associated dispatch/client/impl/provider has a binding type 
+     * that enables MTOM.
      * Indicate whether this is an MTOM message
-     *
      * @param b
      */
     public void setMTOMEnabled(boolean b);
+    
 
     /** @return get the MimeHeaders */
     public MimeHeaders getMimeHeaders();
@@ -119,6 +116,17 @@
 
     /** @return true if post pivot */
     public boolean isPostPivot();
+
+    /**
+     * JAX-WS Message Context that owns the Message
+     * @param messageContext
+     */
+    public void setMessageContext(MessageContext messageContext);
+    
+    /**
+     * @return JAX-WS MessageContext
+     */
+    public MessageContext getMessageContext();
 
     /* 
     * Get the entire message rendered in a certain type of value (i.e. String, Source, SOAPMessage, etc.)

Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/attachments/AttachmentUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/attachments/AttachmentUtils.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/attachments/AttachmentUtils.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/attachments/AttachmentUtils.java Wed Apr 25 22:19:23 2007
@@ -22,10 +22,10 @@
 import org.apache.axiom.om.OMText;
 import org.apache.axiom.om.impl.llom.OMNavigator;
 import org.apache.axiom.soap.SOAPEnvelope;
-import org.apache.axis2.jaxws.message.Attachment;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import javax.activation.DataHandler;
 import javax.xml.namespace.QName;
 import java.util.ArrayList;
 
@@ -203,9 +203,9 @@
      * @param data
      * @return
      */
-    public static OMText makeBinaryOMNode(OMElement xop, Attachment data) {
+    public static OMText makeBinaryOMNode(OMElement xop, DataHandler dh) {
         OMFactory factory = xop.getOMFactory();
-        OMText binaryNode = factory.createOMText(data.getDataHandler(), true);
+        OMText binaryNode = factory.createOMText(dh, true);
         return binaryNode;
     }
 

Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/attachments/JAXBAttachmentMarshaller.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/attachments/JAXBAttachmentMarshaller.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/attachments/JAXBAttachmentMarshaller.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/attachments/JAXBAttachmentMarshaller.java Wed Apr 25 22:19:23 2007
@@ -16,20 +16,22 @@
  */
 package org.apache.axis2.jaxws.message.attachments;
 
+import org.apache.axiom.om.OMText;
+import org.apache.axiom.om.impl.MTOMXMLStreamWriter;
+import org.apache.axiom.om.impl.llom.OMTextImpl;
 import org.apache.axiom.om.util.UUIDGenerator;
 import org.apache.axis2.jaxws.ExceptionFactory;
-import org.apache.axis2.jaxws.i18n.Messages;
-import org.apache.axis2.jaxws.message.Attachment;
 import org.apache.axis2.jaxws.message.Message;
+import org.apache.axis2.transport.http.HTTPConstants;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import javax.activation.DataHandler;
-import javax.mail.MessagingException;
 import javax.mail.internet.InternetHeaders;
 import javax.mail.internet.MimeBodyPart;
 import javax.mail.internet.MimePartDataSource;
 import javax.xml.bind.attachment.AttachmentMarshaller;
+import javax.xml.stream.XMLStreamWriter;
 
 /**
  * An implementation of the JAXB AttachmentMarshaller that is used to handle binary data from JAXB
@@ -40,93 +42,107 @@
     private static final Log log = LogFactory.getLog(JAXBAttachmentMarshaller.class);
 
     private Message message;
-
-    public JAXBAttachmentMarshaller() {
-        super();
-    }
-
-    public void setMessage(Message msg) {
-        message = msg;
+    private XMLStreamWriter writer;
+    private final String APPLICATION_OCTET = "application/octet-stream";
+    
+    public JAXBAttachmentMarshaller(Message message, XMLStreamWriter writer) {
+        this.message = message;
+        this.writer = writer;
     }
 
     @Override
     public boolean isXOPPackage() {
-
-        // FIXME: This should really be set based on whether or not the 
-        // we want to send MTOM for this message.  In such cases the
-        // transport must identify the message as application/xop+xml
-        // (or an equivalent).  Please update this code to match the javadoc.
-        // FIXME: This should really be set based on whether or not we
-        // the SOAP 1.1 or SOAP 1.2 MTOM binding is set.
-        boolean value = true;
-        if (log.isDebugEnabled()) {
+        boolean value = false;
+        
+        // For outbound messages, only trigger MTOM if
+        // the message is mtom enabled (which indicates that
+        // the api dispatch/provider/proxy/impl has an MTOM binding)
+        if (message != null) {
+          value = message.isMTOMEnabled();
+        }
+    
+        if (log.isDebugEnabled()){ 
             log.debug("isXOPPackage returns " + value);
         }
         return value;
+
     }
 
     @Override
     public String addMtomAttachment(byte[] data, int offset, int length,
                                     String mimeType, String namespace, String localPart) {
 
-        String cid = UUIDGenerator.getUUID();
-        if (log.isDebugEnabled()) {
-            log.debug("Adding MTOM/XOP byte array attachment for element: " + "{" + namespace +
-                    "}" + localPart);
-            log.debug("   content id=" + cid);
-            log.debug("   mimeType  =" + mimeType);
+        if (mimeType == null || mimeType.length() == 0) {
+            mimeType = APPLICATION_OCTET;
         }
-
-        DataHandler dataHandler = null;
-        MimeBodyPart mbp = null;
-
+        
+        if (log.isDebugEnabled()){ 
+            log.debug("Adding MTOM/XOP byte array attachment for element: " + "{" + namespace + "}" + localPart);
+        }
+        
+        String cid;
         try {
-            //Create mime parts
+            // Create MIME Body Part
             InternetHeaders ih = new InternetHeaders();
-            ih.setHeader(Attachment.CONTENT_TYPE, mimeType);
-            ih.setHeader(Attachment.CONTENT_ID, cid);
-            mbp = new MimeBodyPart(ih, data);
+            ih.setHeader(HTTPConstants.HEADER_CONTENT_TYPE, mimeType);
+            MimeBodyPart mbp = new MimeBodyPart(ih, data);
+            
+            //Create a data source for the MIME Body Part
+            MimePartDataSource mpds = new MimePartDataSource(mbp);
+            
+            DataHandler dataHandler = new DataHandler(mpds);
+            cid = addDataHandler(dataHandler);
+            
+            // Add the content id to the mime body part
+            mbp.setHeader(HTTPConstants.HEADER_CONTENT_ID, cid);
+        } catch (Throwable t) {
+            throw ExceptionFactory.makeWebServiceException(t);
         }
-        catch (MessagingException me) {
-            throw ExceptionFactory
-                    .makeWebServiceException(Messages.getMessage("mimeBodyPartError"), me);
-        }
-
-        //Create a data source for the byte array
-        MimePartDataSource mpds = new MimePartDataSource(mbp);
 
-        dataHandler = new DataHandler(mpds);
-        Attachment a = message.createAttachment(dataHandler, cid);
-        message.addAttachment(a);
+        return "cid:" + cid;
 
-        return cid;
     }
-
+    
     @Override
     public String addMtomAttachment(DataHandler data, String namespace, String localPart) {
-        String cid = UUIDGenerator.getUUID();
-        if (log.isDebugEnabled()) {
-            log.debug("Adding MTOM/XOP datahandler attachment for element: " + "{" + namespace +
-                    "}" + localPart);
-            log.debug("   content id=" + cid);
-            log.debug("   dataHandler  =" + data);
+        if (log.isDebugEnabled()){ 
+            log.debug("Adding MTOM/XOP datahandler attachment for element: " + "{" + namespace + "}" + localPart);
         }
-        Attachment a = message.createAttachment(data, cid);
-        message.addAttachment(a);
-        return cid;
+        String cid = addDataHandler(data);
+        return "cid:" + cid;
     }
-
+    
     @Override
     public String addSwaRefAttachment(DataHandler data) {
-        String cid = UUIDGenerator.getUUID();
-        if (log.isDebugEnabled()) {
+        if (log.isDebugEnabled()){ 
             log.debug("Adding SWAREF attachment");
+        }
+        
+        String cid = addDataHandler(data);
+        return "cid:" + cid;
+    }
+    
+    private String addDataHandler(DataHandler dh) {
+        String cid = null;
+        OMText textNode = null;
+        
+        // If this is an MTOMXMLStreamWriter then inform the writer 
+        // that it must write out this attchment (I guess we should do this
+        // even if the attachment is SWAREF ?)
+        if (writer instanceof MTOMXMLStreamWriter) {
+            textNode = new OMTextImpl(dh, null);
+            cid = textNode.getContentID();
+            ((MTOMXMLStreamWriter) writer).writeOptimized(textNode);
+        } else {
+            cid = UUIDGenerator.getUUID();
+        }
+        
+        if (log.isDebugEnabled()){ 
             log.debug("   content id=" + cid);
-            log.debug("   dataHandler  =" + data);
+            log.debug("   dataHandler  =" + dh);
         }
-
-        Attachment a = message.createAttachment(data, cid);
-        message.addAttachment(a);
+        // Remember the attachment on the message.
+        message.addDataHandler(dh, cid);
         return cid;
     }
 

Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/attachments/JAXBAttachmentUnmarshaller.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/attachments/JAXBAttachmentUnmarshaller.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/attachments/JAXBAttachmentUnmarshaller.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/attachments/JAXBAttachmentUnmarshaller.java Wed Apr 25 22:19:23 2007
@@ -17,8 +17,8 @@
 package org.apache.axis2.jaxws.message.attachments;
 
 import org.apache.axis2.jaxws.ExceptionFactory;
-import org.apache.axis2.jaxws.message.Attachment;
 import org.apache.axis2.jaxws.message.Message;
+import org.apache.axis2.jaxws.utility.JavaUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -27,8 +27,6 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.Iterator;
-import java.util.List;
 
 /**
  * JAXBAttachmentUnmarshaller
@@ -42,13 +40,18 @@
 
     private Message message;
 
+    public JAXBAttachmentUnmarshaller(Message message) {
+        this.message = message;
+    }
+
     @Override
     public boolean isXOPPackage() {
-        // FIXME: This should really be set based on whether or not the 
-        // incoming message is "application/xop+xml".  Please read the
-        // javadoc for this method.
+        
+        // Any message that is received might contain MTOM.
+        // So always return true.
         boolean value = true;
-        if (log.isDebugEnabled()) {
+    
+        if (log.isDebugEnabled()){ 
             log.debug("isXOPPackage returns " + value);
         }
         return value;
@@ -82,12 +85,17 @@
             log.debug("Attempting to retrieve attachment [" + cid + "] as a DataHandler");
         }
 
-        List<Attachment> attachments = message.getAttachments();
-        Iterator<Attachment> itr = attachments.iterator();
-        while (itr.hasNext()) {
-            Attachment a = itr.next();
-            if (a.getContentID().equals(cid)) {
-                return a.getDataHandler();
+        DataHandler dh = message.getDataHandler(cid);
+        if (dh != null) {
+            return dh;
+        } else {
+            String cid2 = getNewCID(cid);
+            if (log.isDebugEnabled()) {
+                log.debug("A dataHandler was not found for [" + cid + "] trying [" + cid2 + "]");
+            }
+            dh = message.getDataHandler(cid2);
+            if (dh != null) {
+                return dh;
             }
         }
 
@@ -96,14 +104,18 @@
         }
         return null;
     }
-
+    
     /**
-     * Set the message that holds the attachment data.
-     *
-     * @param msg
+     * @param cid
+     * @return cid with translated characters
      */
-    public void setMessage(Message msg) {
-        message = msg;
+    private String getNewCID(String cid) {
+        // TODO This method only converts : and /
+        // A more complete fix is needed.
+        String cid2 = cid;
+        cid2 = JavaUtils.replace(cid2, "%3A", ":");
+        cid2 = JavaUtils.replace(cid2, "%2F", "/");
+        return cid2;
     }
 
     /**

Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/JAXBUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/JAXBUtils.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/JAXBUtils.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/JAXBUtils.java Wed Apr 25 22:19:23 2007
@@ -139,12 +139,10 @@
             adjustPoolSize(innerMap);
 
             // A pooled context was not found, so create one and put it in the map.
-
-            // A copy is made of the original list of packages because createJAXBContext may 
-            // prune the list.
-            TreeSet<String> origContextPackages = new TreeSet<String>(contextPackages);
-            contextValue = createJAXBContextValue(contextPackages, cl);
-
+            synchronized(contextPackages) {
+               // synchronized on contextPackages because this method may prune the contextPackages
+               contextValue = createJAXBContextValue(contextPackages, cl);
+            }
             // Put the new context in the map keyed by both the original and current list of packages
             innerMap.put(key, contextValue);
             innerMap.put(contextPackages.toString(), contextValue);

Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/XSDListUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/XSDListUtils.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/XSDListUtils.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/XSDListUtils.java Wed Apr 25 22:19:23 2007
@@ -77,7 +77,7 @@
             IllegalArgumentException, InstantiationException, IllegalAccessException,
             InvocationTargetException {
         // TODO only supports arrays right now.  Need to implement this for List
-        if (container.getClass().isArray()) {
+    	if (container !=null && container.getClass().isArray()) {
             String xsdString = "";
             for (int i = 0; i < Array.getLength(container); i++) {
                 Object component = Array.get(container, i);
@@ -87,7 +87,20 @@
                 xsdString += getAsText(component);
             }
             return xsdString;
-        } else {
+            
+        } else if(container!=null && List.class.isAssignableFrom(container.getClass())){
+            String xsdString = "";
+            List containerAsList = (List)container;
+            for (Object component:containerAsList) {
+                if (xsdString.length() != 0) {
+                    xsdString += " ";
+                }
+                xsdString += getAsText(component);
+            }
+            return xsdString;
+            
+        }
+        else {
             throw new IllegalArgumentException(container.getClass().toString());
         }
     }
@@ -129,7 +142,7 @@
             }
             Object array = Array.newInstance(arrayType, list.size());
             return list.toArray((Object[])array);
-        } else {
+        }else {
             throw new IllegalArgumentException(type.toString());
         }
     }

Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/JAXBBlockImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/JAXBBlockImpl.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/JAXBBlockImpl.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/JAXBBlockImpl.java Wed Apr 25 22:19:23 2007
@@ -18,6 +18,7 @@
 
 import org.apache.axiom.om.OMElement;
 import org.apache.axiom.om.util.StAXUtils;
+import org.apache.axis2.java.security.AccessController;
 import org.apache.axis2.jaxws.ExceptionFactory;
 import org.apache.axis2.jaxws.message.Message;
 import org.apache.axis2.jaxws.message.attachments.JAXBAttachmentMarshaller;
@@ -43,6 +44,10 @@
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.ws.WebServiceException;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.security.PrivilegedAction;
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.util.List;
@@ -56,8 +61,7 @@
 public class JAXBBlockImpl extends BlockImpl implements JAXBBlock {
 
     private static final Log log = LogFactory.getLog(JAXBBlockImpl.class);
-    private static final String XMLNS = "xmlns=\"\" xmlns:xmlns=\"http://www.w3.org/2000/xmlns/\"";
-
+    
     /**
      * Called by JAXBBlockFactory
      *
@@ -97,18 +101,15 @@
             // TODO Re-evaluate Unmarshall construction w/ MTOM
             Unmarshaller u = JAXBUtils.getJAXBUnmarshaller(ctx.getJAXBContext());
 
-            // If MTOM is enabled, add in the AttachmentUnmarshaller
-            if (isMTOMEnabled()) {
-                if (log.isDebugEnabled())
-                    log.debug("Adding JAXBAttachmentUnmarshaller to Unmarshaller");
-
-                Message msg = getParent();
-
-                // TODO Pool ?
-                JAXBAttachmentUnmarshaller aum = new JAXBAttachmentUnmarshaller();
-                aum.setMessage(msg);
-                u.setAttachmentUnmarshaller(aum);
+            if (log.isDebugEnabled()) {
+                log.debug("Adding JAXBAttachmentUnmarshaller to Unmarshaller");
             }
+            
+            Message msg = getParent();
+            
+            JAXBAttachmentUnmarshaller aum = new JAXBAttachmentUnmarshaller(msg);
+            u.setAttachmentUnmarshaller(aum);
+            
             Object jaxb = null;
 
             // Unmarshal into the business object.
@@ -119,15 +120,7 @@
                 jaxb = unmarshalByType(u, reader, ctx.getProcessType());
             }
 
-            /* QNAME should already be known at this point
-            QName qName = XMLRootElementUtil.getXmlRootElementQName(jaxb);
-            if (qName != null) {  // qname should always be non-null
-                setQName(qName); 
-            }
-            */
-
             // Successfully unmarshalled the object
-            // TODO remove attachment unmarshaller ?
             JAXBUtils.releaseJAXBUnmarshaller(ctx.getJAXBContext(), u);
             reader.close();
             return jaxb;
@@ -141,45 +134,35 @@
             throw ExceptionFactory.makeWebServiceException(je);
         }
     }
-
-    @Override
-    protected XMLStreamReader _getReaderFromBO(Object busObj, Object busContext)
-            throws XMLStreamException, WebServiceException {
-        // TODO Review and determine if there is a better solution
-
-        // This is hard because JAXB does not expose a reader from the business object.
-        // The solution is to write out the object and use a reader to read it back in.
-        // First create an XMLStreamWriter backed by a writer
-        StringWriter sw = new StringWriter();
-        XMLStreamWriter writer = StAXUtils.createXMLStreamWriter(sw);
-
+    
+    /**
+     * @param busObj
+     * @param busContext
+     * @return
+     * @throws XMLStreamException
+     * @throws WebServiceException
+     */
+    private byte[] _getBytesFromBO(Object busObj, Object busContext, String encoding)
+        throws XMLStreamException, WebServiceException {
+        ByteArrayOutputStream baos = new  ByteArrayOutputStream();
+        
+        XMLStreamWriter writer = StAXUtils.createXMLStreamWriter(baos, encoding);
+        
         // Write the business object to the writer
         _outputFromBO(busObj, busContext, writer);
-
-        // Flush the writer and get the String
+        
+        // Flush the writer
         writer.flush();
-        sw.flush();
-        String str = sw.toString();
-
-        // REVIEW ALERT
-        // Sometimes JAXB emits xmlns="" xmlns:xmlns..., which is invalid.
-        // The following lines of code removes this attribute.
-        // This seems to be related to MTOM..it has never failed in
-        // other cases
-        if (isMTOMEnabled()) {
-            if (log.isDebugEnabled()) {
-                log.debug("JAXB marshalled the xml as: " + str);
-            }
-            str = JavaUtils.replace(str, XMLNS, "");
-            if (log.isDebugEnabled()) {
-                log.debug("XML text after inspection: " + str);
-            }
-        }
         writer.close();
+        return baos.toByteArray();
+    }
+
 
-        // Return a reader backed by the string
-        StringReader sr = new StringReader(str);
-        return StAXUtils.createXMLStreamReader(sr);
+    @Override
+    protected XMLStreamReader _getReaderFromBO(Object busObj, Object busContext)
+            throws XMLStreamException, WebServiceException {
+        ByteArrayInputStream baos = new ByteArrayInputStream(_getBytesFromBO(busObj, busContext, "utf-8"));
+        return StAXUtils.createXMLStreamReader(baos, "utf-8");
     }
 
     @Override
@@ -190,34 +173,27 @@
             // Very easy, use the Context to get the Marshaller.
             // Use the marshaller to write the object.
             Marshaller m = JAXBUtils.getJAXBMarshaller(ctx.getJAXBContext());
-
-            // TODO Should MTOM be inside getMarshaller ?
-            // If MTOM is enabled, add in the AttachmentMarshaller.
-            if (isMTOMEnabled()) {
-                if (log.isDebugEnabled())
-                    log.debug("Adding JAXBAttachmentMarshaller to Marshaller");
-
-                Message msg = getParent();
-
-                // Pool
-                JAXBAttachmentMarshaller am = new JAXBAttachmentMarshaller();
-                am.setMessage(msg);
-                m.setAttachmentMarshaller(am);
+            
+            
+            if (log.isDebugEnabled()) {
+                log.debug("Adding JAXBAttachmentMarshaller to Marshaller");
             }
-
-            // Wrap the writer in our JAXBXMLStreamWriterFilter.
-            // This is necessary to correct any JAXB xml marshalling problems
-            JAXBXMLStreamWriterFilter filter = new JAXBXMLStreamWriterFilter(writer);
-
+            
+            Message msg = getParent();
+            
+            // Pool
+            JAXBAttachmentMarshaller am = new JAXBAttachmentMarshaller(msg, writer);
+            m.setAttachmentMarshaller(am);
+            
+            
             // Marshal the object
             if (ctx.getProcessType() == null) {
-                marshalByElement(busObject, m, filter);
+                marshalByElement(busObject, m, writer);
             } else {
-                marshalByType(busObject, m, filter, ctx.getProcessType());
+                marshalByType(busObject, m, writer, ctx.getProcessType());
             }
 
             // Successfully marshalled the data
-            // TODO remove attachment marshaller ?
             JAXBUtils.releaseJAXBMarshaller(ctx.getJAXBContext(), m);
         } catch (JAXBException je) {
             if (log.isDebugEnabled()) {
@@ -244,14 +220,6 @@
         return qName;
     }
 
-    private boolean isMTOMEnabled() {
-        Message msg = getParent();
-        if (msg != null && msg.isMTOMEnabled()) {
-            return true;
-        }
-        return false;
-    }
-
     /**
      * Preferred way to marshal objects.
      *
@@ -278,11 +246,23 @@
      * @return Object that represents an element
      * @throws WebServiceException
      */
-    private static Object unmarshalByElement(Unmarshaller u, XMLStreamReader reader)
+    private static Object unmarshalByElement(final Unmarshaller u, final XMLStreamReader reader)
             throws WebServiceException {
         // TODO Log and trace here would be helpful
         try {
-            return u.unmarshal(reader);
+        	 if(log.isDebugEnabled()){
+        	    log.debug("Invoking unMarshalByElement");
+        	 }
+        	 return AccessController.doPrivileged(new PrivilegedAction() {
+        		 public Object run() {
+        			 try {
+        				 return u.unmarshal(reader);
+        			 } catch (Exception e) {
+        				 throw ExceptionFactory.makeWebServiceException(e);
+        			 }
+        		 }
+        	 });
+
         } catch (Exception e) {
             throw ExceptionFactory.makeWebServiceException(e);
         }
@@ -423,4 +403,5 @@
         }
         return obj;
     }
+    
 }

Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageFactoryImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageFactoryImpl.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageFactoryImpl.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageFactoryImpl.java Wed Apr 25 22:19:23 2007
@@ -21,7 +21,6 @@
 import org.apache.axiom.soap.SOAPEnvelope;
 import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
 import org.apache.axis2.jaxws.ExceptionFactory;
-import org.apache.axis2.jaxws.message.Attachment;
 import org.apache.axis2.jaxws.message.Block;
 import org.apache.axis2.jaxws.message.Message;
 import org.apache.axis2.jaxws.message.Protocol;
@@ -89,8 +88,7 @@
                 Iterator it = message.getAttachments();
                 while (it.hasNext()) {
                     AttachmentPart ap = (AttachmentPart)it.next();
-                    Attachment a = MessageUtils.createAttachment(ap, m);
-                    m.addAttachment(a);
+                    m.addDataHandler(ap.getDataHandler(), ap.getContentId());
                 }
             }
             return m;

Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/MessageImpl.java Wed Apr 25 22:19:23 2007
@@ -16,11 +16,33 @@
  */
 package org.apache.axis2.jaxws.message.impl;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.Set;
+
+import javax.activation.DataHandler;
+import javax.jws.soap.SOAPBinding.Style;
+import javax.xml.namespace.QName;
+import javax.xml.soap.AttachmentPart;
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.MimeHeaders;
+import javax.xml.soap.SOAPConstants;
+import javax.xml.soap.SOAPEnvelope;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.ws.WebServiceException;
+
+import org.apache.axiom.attachments.Attachments;
 import org.apache.axiom.om.OMElement;
 import org.apache.axiom.om.OMNamespace;
+import org.apache.axiom.om.impl.MTOMConstants;
+import org.apache.axis2.Constants.Configuration;
+import org.apache.axis2.client.Options;
 import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.core.MessageContext;
 import org.apache.axis2.jaxws.i18n.Messages;
-import org.apache.axis2.jaxws.message.Attachment;
 import org.apache.axis2.jaxws.message.Block;
 import org.apache.axis2.jaxws.message.Message;
 import org.apache.axis2.jaxws.message.Protocol;
@@ -34,25 +56,9 @@
 import org.apache.axis2.jaxws.message.util.MessageUtils;
 import org.apache.axis2.jaxws.message.util.SAAJConverter;
 import org.apache.axis2.jaxws.registry.FactoryRegistry;
-
-import javax.activation.DataHandler;
-import javax.jws.soap.SOAPBinding.Style;
-import javax.xml.namespace.QName;
-import javax.xml.soap.AttachmentPart;
-import javax.xml.soap.MessageFactory;
-import javax.xml.soap.MimeHeaders;
-import javax.xml.soap.SOAPConstants;
-import javax.xml.soap.SOAPEnvelope;
-import javax.xml.soap.SOAPMessage;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import javax.xml.stream.XMLStreamWriter;
-import javax.xml.ws.WebServiceException;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
+import org.apache.axis2.transport.http.HTTPConstants;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 /**
  * MessageImpl
@@ -62,82 +68,81 @@
  * NOTE: For XML/HTTP (REST), a SOAP 1.1. Envelope is built and the rest payload is placed
  * in the body.  This purposely mimics the Axis2 implementation.
  */
-
-/** @author scheu */
 public class MessageImpl implements Message {
-
+    private static final Log log = LogFactory.getLog(MessageImpl.class);
+    
     Protocol protocol = Protocol.unknown; // the protocol, defaults to unknown
     XMLPart xmlPart = null; // the representation of the xmlpart
-    List<Attachment> attachments = new ArrayList<Attachment>(); // non-xml parts
+    
     boolean mtomEnabled;
-    private MimeHeaders mimeHeaders = new MimeHeaders();
-
+    private MimeHeaders mimeHeaders = new MimeHeaders(); 
+    
+    // The Message is connected to a MessageContext.
+    // Prior to that connection, attachments are stored locally
+    // After the connection, attachments are obtained from the MessageContext
+    Attachments attachments = new Attachments();  // Local Attachments
+    private MessageContext messageContext;
+    
+    // Set after we have past the pivot point when the message is consumed
     private boolean postPivot = false;
-
+    
     /**
-     * MessageImpl should be constructed via the MessageFactory. This constructor constructs an empty
-     * message with the specified protocol
-     *
+     * MessageImpl should be constructed via the MessageFactory.
+     * This constructor constructs an empty message with the specified protocol
      * @param protocol
      */
     MessageImpl(Protocol protocol) throws WebServiceException, XMLStreamException {
         createXMLPart(protocol);
     }
-
+    
     /**
-     * Message is constructed by the MessageFactory. This constructor creates a message from the
-     * specified root.
-     *
+     * Message is constructed by the MessageFactory.
+     * This constructor creates a message from the specified root.
      * @param root
      * @param protocol or null
      */
-    MessageImpl(OMElement root, Protocol protocol) throws WebServiceException, XMLStreamException {
+    MessageImpl(OMElement root, Protocol protocol) throws WebServiceException, XMLStreamException  {
         createXMLPart(root, protocol);
     }
-
+    
     /**
-     * Message is constructed by the MessageFactory. This constructor creates a message from the
-     * specified root.
-     *
+     * Message is constructed by the MessageFactory.
+     * This constructor creates a message from the specified root.
      * @param root
      * @param protocol or null
      */
-    MessageImpl(SOAPEnvelope root) throws WebServiceException, XMLStreamException {
+    MessageImpl(SOAPEnvelope root) throws WebServiceException, XMLStreamException  {
         createXMLPart(root);
     }
-
+    
     /**
      * Create a new XMLPart and Protocol from the root
-     *
      * @param root SOAPEnvelope
      * @throws WebServiceException
      * @throws XMLStreamException
      */
     private void createXMLPart(SOAPEnvelope root) throws WebServiceException, XMLStreamException {
-        XMLPartFactory factory = (XMLPartFactory)FactoryRegistry.getFactory(XMLPartFactory.class);
+        XMLPartFactory factory = (XMLPartFactory) FactoryRegistry.getFactory(XMLPartFactory.class);
         xmlPart = factory.createFrom(root);
         this.protocol = xmlPart.getProtocol();
-        xmlPart.setParent(this);
+        xmlPart.setParent(this); 
     }
-
+    
     /**
      * Create a new XMLPart and Protocol from the root
-     *
      * @param root OMElement
      * @throws WebServiceException
      * @throws XMLStreamException
      */
-    private void createXMLPart(OMElement root, Protocol protocol)
-            throws WebServiceException, XMLStreamException {
-        XMLPartFactory factory = (XMLPartFactory)FactoryRegistry.getFactory(XMLPartFactory.class);
+    private void createXMLPart(OMElement root, Protocol protocol) throws WebServiceException, XMLStreamException {
+        XMLPartFactory factory = (XMLPartFactory) FactoryRegistry.getFactory(XMLPartFactory.class);
         xmlPart = factory.createFrom(root, protocol);
         this.protocol = xmlPart.getProtocol();
         xmlPart.setParent(this);
     }
-
+    
     /**
      * Create a new empty XMLPart from the Protocol
-     *
      * @param protocol
      * @throws WebServiceException
      * @throws XMLStreamException
@@ -145,20 +150,19 @@
     private void createXMLPart(Protocol protocol) throws WebServiceException, XMLStreamException {
         this.protocol = protocol;
         if (protocol.equals(Protocol.unknown)) {
-            throw ExceptionFactory
-                    .makeWebServiceException(Messages.getMessage("ProtocolIsNotKnown"));
-        }
-        XMLPartFactory factory = (XMLPartFactory)FactoryRegistry.getFactory(XMLPartFactory.class);
+            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("ProtocolIsNotKnown"));
+        } 
+        XMLPartFactory factory = (XMLPartFactory) FactoryRegistry.getFactory(XMLPartFactory.class);
         xmlPart = factory.create(protocol);
         xmlPart.setParent(this);
     }
-
+    
     /* (non-Javadoc)
-      * @see org.apache.axis2.jaxws.message.Message#getAsSOAPMessage()
-      */
+     * @see org.apache.axis2.jaxws.message.Message#getAsSOAPMessage()
+     */
     public SOAPMessage getAsSOAPMessage() throws WebServiceException {
-
-        // TODO:
+        
+        // TODO: 
         // This is a non performant way to create SOAPMessage. I will serialize
         // the xmlpart content and then create an InputStream of byte.
         // Finally create SOAPMessage using this InputStream.
@@ -167,26 +171,26 @@
         try {
             // Get OMElement from XMLPart.
             OMElement element = xmlPart.getAsOMElement();
-
+            
             // Get the namespace so that we can determine SOAP11 or SOAP12
             OMNamespace ns = element.getNamespace();
-
+            
             ByteArrayOutputStream outStream = new ByteArrayOutputStream();
             element.serialize(outStream);
-
+            
             // Create InputStream
             ByteArrayInputStream inStream = new ByteArrayInputStream(outStream
                     .toByteArray());
-
+            
             // Create MessageFactory that supports the version of SOAP in the om element
             MessageFactory mf = getSAAJConverter().createMessageFactory(ns.getNamespaceURI());
-
+            
             // Create soapMessage object from Message Factory using the input
             // stream created from OM.
-
+            
             // Get the MimeHeaders
             MimeHeaders defaultHeaders = this.getMimeHeaders();
-
+            
             // Toggle based on SOAP 1.1 or SOAP 1.2
             String contentType = null;
             if (ns.getNamespaceURI().equals(SOAPConstants.URI_NS_SOAP_1_1_ENVELOPE)) {
@@ -194,33 +198,53 @@
             } else {
                 contentType = SOAPConstants.SOAP_1_2_CONTENT_TYPE;
             }
-
+            
             // Override the content-type
-            defaultHeaders.setHeader("Content-type", contentType + "; charset=UTF-8");
+            defaultHeaders.setHeader("Content-type", contentType +"; charset=UTF-8");
             SOAPMessage soapMessage = mf.createMessage(defaultHeaders, inStream);
-
+            
             // At this point the XMLPart is still an OMElement.  We need to change it to the new SOAPEnvelope.
             createXMLPart(soapMessage.getSOAPPart().getEnvelope());
-
-            // Now add the attachments to the SOAPMessage
-            Iterator it = getAttachments().iterator();
-            while (it.hasNext()) {
-                AttachmentPart ap =
-                        MessageUtils.createAttachmentPart((Attachment)it.next(), soapMessage);
-                soapMessage.addAttachmentPart(ap);
+            
+            // If axiom read the message from the input stream, 
+            // then one of the attachments is a SOAPPart.  Ignore this attachment
+            String soapPartContentID = getSOAPPartContentID();  // This may be null
+            
+            // Add the attachments
+            for (String cid:getAttachmentIDs()) {
+                DataHandler dh = attachments.getDataHandler(cid);
+                boolean isSOAPPart = cid.equals(soapPartContentID);
+                if (!isSOAPPart) {
+                    AttachmentPart ap = MessageUtils.createAttachmentPart(cid, dh, soapMessage);
+                    soapMessage.addAttachmentPart(ap);
+                }
             }
-
+            
             return soapMessage;
         } catch (Exception e) {
             throw ExceptionFactory.makeWebServiceException(e);
         }
-
+        
     }
-
-
+    
+    private String getSOAPPartContentID() {
+        String contentID = null;
+        if (messageContext == null) {
+            return null;  // Attachments set up programmatically...so there is no SOAPPart
+        }
+        try {
+            contentID = attachments.getSOAPPartContentID();
+        } catch (RuntimeException e) {
+            // OM will kindly throw an OMException or NPE if the attachments is set up programmatically. 
+            return null;
+        }
+        return contentID;
+    }
+    
+    
     /* (non-Javadoc)
-    * @see org.apache.axis2.jaxws.message.Message#getValue(java.lang.Object, org.apache.axis2.jaxws.message.factory.BlockFactory)
-    */
+     * @see org.apache.axis2.jaxws.message.Message#getValue(java.lang.Object, org.apache.axis2.jaxws.message.factory.BlockFactory)
+     */
     public Object getValue(Object context, BlockFactory blockFactory) throws WebServiceException {
         try {
             Object value = null;
@@ -231,7 +255,7 @@
                 if (block != null) {
                     value = block.getBusinessObject(true);
                 }
-
+                
             } else {
                 // Must be SOAP
                 if (blockFactory instanceof SOAPEnvelopeBlockFactory) {
@@ -240,16 +264,13 @@
                     // TODO: This doesn't seem right to me. We should not have an intermediate StringBlock.  
                     // This is not performant. Scheu 
                     OMElement messageOM = getAsOMElement();
-                    String stringValue = messageOM.toString();
-                    String soapNS = (protocol == Protocol.soap11) ?
-                            SOAPConstants.URI_NS_SOAP_1_1_ENVELOPE :
-                            SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE;
+                    String stringValue = messageOM.toString();  
+                    String soapNS = (protocol == Protocol.soap11) ? SOAPConstants.URI_NS_SOAP_1_1_ENVELOPE : SOAPConstants.URI_NS_SOAP_1_2_ENVELOPE; 
                     QName soapEnvQname = new QName(soapNS, "Envelope");
-
-
-                    XMLStringBlockFactory stringFactory = (XMLStringBlockFactory)FactoryRegistry
-                            .getFactory(XMLStringBlockFactory.class);
-                    Block stringBlock = stringFactory.createFrom(stringValue, null, soapEnvQname);
+                    
+                    
+                    XMLStringBlockFactory stringFactory = (XMLStringBlockFactory) FactoryRegistry.getFactory(XMLStringBlockFactory.class);
+                    Block stringBlock = stringFactory.createFrom(stringValue, null, soapEnvQname);   
                     Block block = blockFactory.createFrom(stringBlock, context);
                     value = block.getBusinessObject(true);
                 }
@@ -259,126 +280,113 @@
             throw ExceptionFactory.makeWebServiceException(e);
         }
     }
-
+    
+    
     /* (non-Javadoc)
-      * @see org.apache.axis2.jaxws.message.XMLPart#getAttachments()
-      */
-    public List<Attachment> getAttachments() {
-        return attachments;
-    }
-
-    /*
-    * (non-Javadoc)
-    * @see org.apache.axis2.jaxws.message.Message#getAttachment(java.lang.String)
-    */
-    public Attachment getAttachment(String cid) {
-        if (attachments != null) {
-            Iterator<Attachment> itr = attachments.iterator();
-            while (itr.hasNext()) {
-                Attachment a = itr.next();
-                if (a.getContentID().equals(cid)) {
-                    return a;
-                }
-            }
-        }
-
-        return null;
+     * @see org.apache.axis2.jaxws.message.Message#getAttachmentIDs()
+     */
+    public Set<String> getAttachmentIDs() {
+        return attachments.getContentIDSet();
     }
-
-
+    
+    
     /* (non-Javadoc)
-      * @see org.apache.axis2.jaxws.message.Message#removeAttachment(java.lang.String)
-      */
-    public Attachment removeAttachment(String cid) {
-        if (attachments != null) {
-            Iterator<Attachment> itr = attachments.iterator();
-            while (itr.hasNext()) {
-                Attachment a = itr.next();
-                if (a.getContentID().equals(cid)) {
-                    itr.remove();
-                    return a;
-                }
-            }
+     * @see org.apache.axis2.jaxws.message.Message#getDataHandler(java.lang.String)
+     */
+    public DataHandler getDataHandler(String cid) {
+        String bcid = getBlobCID(cid);
+        return attachments.getDataHandler(bcid);
+    }
+    
+    
+    
+    /* (non-Javadoc)
+     * @see org.apache.axis2.jaxws.message.Message#removeDataHandler(java.lang.String)
+     */
+    public DataHandler removeDataHandler(String cid) {
+        String bcid = getBlobCID(cid);
+        DataHandler dh = attachments.getDataHandler(bcid);
+        attachments.removeDataHandler(bcid);
+        return dh;
+    }
+    
+    private String getBlobCID(String cid) {
+        String blobCID = cid;
+        if (cid.startsWith("cid:")) {
+            blobCID = cid.substring(4);  // Skip over cid:
         }
-
-        return null;
+        return blobCID;
     }
-
+    
     /* (non-Javadoc)
-	 * @see org.apache.axis2.jaxws.message.XMLPart#getProtocol()
-	 */
+     * @see org.apache.axis2.jaxws.message.XMLPart#getProtocol()
+     */
     public Protocol getProtocol() {
         return protocol;
     }
-
-
+    
+    
     public OMElement getAsOMElement() throws WebServiceException {
         return xmlPart.getAsOMElement();
     }
-
+    
     public javax.xml.soap.SOAPEnvelope getAsSOAPEnvelope() throws WebServiceException {
         return xmlPart.getAsSOAPEnvelope();
     }
-
-    public Block getBodyBlock(int index, Object context, BlockFactory blockFactory)
-            throws WebServiceException {
+    
+    public Block getBodyBlock(int index, Object context, BlockFactory blockFactory) throws WebServiceException {
         return xmlPart.getBodyBlock(index, context, blockFactory);
     }
-
-    public Block getHeaderBlock(String namespace, String localPart, Object context,
-                                BlockFactory blockFactory) throws WebServiceException {
+    
+    public Block getHeaderBlock(String namespace, String localPart, Object context, BlockFactory blockFactory) throws WebServiceException {
         return xmlPart.getHeaderBlock(namespace, localPart, context, blockFactory);
     }
-
+    
     public int getNumBodyBlocks() throws WebServiceException {
         return xmlPart.getNumBodyBlocks();
     }
-
+    
     public int getNumHeaderBlocks() throws WebServiceException {
         return xmlPart.getNumHeaderBlocks();
     }
-
+    
     public XMLStreamReader getXMLStreamReader(boolean consume) throws WebServiceException {
         return xmlPart.getXMLStreamReader(consume);
     }
-
+    
     public boolean isConsumed() {
         return xmlPart.isConsumed();
     }
-
-    public void outputTo(XMLStreamWriter writer, boolean consume)
-            throws XMLStreamException, WebServiceException {
+    
+    public void outputTo(XMLStreamWriter writer, boolean consume) throws XMLStreamException, WebServiceException {
         xmlPart.outputTo(writer, consume);
     }
-
+    
     public void removeBodyBlock(int index) throws WebServiceException {
         xmlPart.removeBodyBlock(index);
     }
-
+    
     public void removeHeaderBlock(String namespace, String localPart) throws WebServiceException {
         xmlPart.removeHeaderBlock(namespace, localPart);
     }
-
+    
     public void setBodyBlock(int index, Block block) throws WebServiceException {
         xmlPart.setBodyBlock(index, block);
     }
-
-    public void setHeaderBlock(String namespace, String localPart, Block block)
-            throws WebServiceException {
+    
+    public void setHeaderBlock(String namespace, String localPart, Block block) throws WebServiceException {
         xmlPart.setHeaderBlock(namespace, localPart, block);
     }
-
+    
     public String traceString(String indent) {
         return xmlPart.traceString(indent);
     }
-
+    
     /**
      * Load the SAAJConverter
-     *
      * @return SAAJConverter
      */
     SAAJConverter converter = null;
-
     private SAAJConverter getSAAJConverter() {
         if (converter == null) {
             SAAJConverterFactory factory = (
@@ -387,75 +395,76 @@
         }
         return converter;
     }
-
-    public void addAttachment(Attachment data) {
-        attachments.add(data);
-    }
-
-
-    /* (non-Javadoc)
-    * @see org.apache.axis2.jaxws.message.Message#createAttachment(javax.activation.DataHandler, java.lang.String)
-    */
-    public Attachment createAttachment(DataHandler dh, String id) {
-        return new AttachmentImpl(dh, id);
+    
+    public void addDataHandler(DataHandler dh, String id) {
+        if (id.startsWith("<")  && id.endsWith(">")) {
+            id = id.substring(1, id.length()-1);
+        }
+        attachments.addDataHandler(id, dh);
     }
-
+    
     public Message getParent() {
         return null;
     }
-
-    public void setParent(Message msg) {
+    
+    public void setParent(Message msg) { 
         // A Message does not have a parent
         throw new UnsupportedOperationException();
     }
-
+    
+    /**
+     * @return true if the binding for this message indicates mtom
+     */
     public boolean isMTOMEnabled() {
         return mtomEnabled;
     }
-
+    
+    /**
+     * @param true if the binding for this message indicates mtom
+     */
     public void setMTOMEnabled(boolean b) {
         mtomEnabled = b;
     }
-
+    
     public XMLFault getXMLFault() throws WebServiceException {
         return xmlPart.getXMLFault();
     }
-
+    
     public void setXMLFault(XMLFault xmlFault) throws WebServiceException {
         xmlPart.setXMLFault(xmlFault);
     }
-
+    
     public boolean isFault() throws WebServiceException {
         return xmlPart.isFault();
     }
-
+    
     public String getXMLPartContentType() {
         return xmlPart.getXMLPartContentType();
     }
-
+    
     public Style getStyle() {
         return xmlPart.getStyle();
     }
-
+    
     public void setStyle(Style style) throws WebServiceException {
         xmlPart.setStyle(style);
     }
-
+    
     public QName getOperationElement() throws WebServiceException {
         return xmlPart.getOperationElement();
     }
-
+    
     public void setOperationElement(QName operationQName) throws WebServiceException {
         xmlPart.setOperationElement(operationQName);
     }
-
+    
     /* (non-Javadoc)
      * @see org.apache.axis2.jaxws.message.Attachment#getMimeHeaders()
      */
     public MimeHeaders getMimeHeaders() {
         return mimeHeaders;
     }
-
+    
     /* (non-Javadoc)
      * @see org.apache.axis2.jaxws.message.Attachment#setMimeHeaders(javax.xml.soap.MimeHeaders)
      */
@@ -465,30 +474,62 @@
             mimeHeaders = new MimeHeaders();
         }
     }
-
-    public Block getBodyBlock(Object context, BlockFactory blockFactory)
-            throws WebServiceException {
+    
+    public Block getBodyBlock(Object context, BlockFactory blockFactory) throws WebServiceException {
         return xmlPart.getBodyBlock(context, blockFactory);
     }
-
+    
     public void setBodyBlock(Block block) throws WebServiceException {
         xmlPart.setBodyBlock(block);
     }
-
+    
     public void setPostPivot() {
         this.postPivot = true;
     }
-
+    
     public boolean isPostPivot() {
         return postPivot;
     }
-
+    
     public int getIndirection() {
         return xmlPart.getIndirection();
     }
-
+    
     public void setIndirection(int indirection) {
         xmlPart.setIndirection(indirection);
     }
-
+    
+    public MessageContext getMessageContext() {
+        return messageContext;
+    }
+    
+    public void setMessageContext(MessageContext messageContext) {
+        if (this.messageContext != messageContext) {
+            // Copy attachments to the new map
+            Attachments newMap = messageContext.getAxisMessageContext().getAttachmentMap();
+            Attachments oldMap = attachments;
+            for (String cid:oldMap.getAllContentIDs()) {
+                DataHandler dh = oldMap.getDataHandler(cid);
+                if (dh != null) {
+                    newMap.addDataHandler(cid, dh);
+                }
+            }
+            // If not MTOM and there are attachments, set SWA style
+            if (!isMTOMEnabled()) {
+                String[] cids = newMap.getAllContentIDs();
+                if (cids.length > 0) {
+                    Options opts = messageContext.getAxisMessageContext().getOptions();
+                    opts.setProperty(Configuration.ENABLE_SWA, "true");
+                }
+            }
+            if (log.isDebugEnabled()) {
+                for (String cid:newMap.getAllContentIDs()) {
+                    log.debug("Message has an attachment with content id= " + cid);
+                }
+            }
+            attachments = newMap;
+        }
+        this.messageContext = messageContext;
+    }
+    
 }

Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/impl/XMLSpineImpl.java Wed Apr 25 22:19:23 2007
@@ -21,6 +21,7 @@
 import org.apache.axiom.om.OMNamespace;
 import org.apache.axiom.om.OMNode;
 import org.apache.axiom.om.impl.OMContainerEx;
+import org.apache.axiom.om.impl.llom.OMElementImpl;
 import org.apache.axiom.om.impl.llom.OMSourcedElementImpl;
 import org.apache.axiom.soap.SOAP11Constants;
 import org.apache.axiom.soap.SOAP12Constants;
@@ -44,11 +45,13 @@
 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;
@@ -499,9 +502,31 @@
 
             // We want to set the om element and its parents to complete to 
             // shutdown the parsing.  
-            // TODO It would also be nice to close the input XMLStreamReader connected
-            // to the builder.
             if (setComplete) {
+                
+                // Get the root of the document
+                OMElementImpl root = (OMElementImpl) om;
+                while(root.getParent() instanceof OMElementImpl) {
+                    root = (OMElementImpl) 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.debug(JavaUtils.stackToString(e));
+                    }
+                    
+                }
+                
+
                 OMContainer o = om;
                 while (o != null && o instanceof OMContainerEx) {
                     ((OMContainerEx)o).setComplete(true);

Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/util/MessageUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/util/MessageUtils.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/util/MessageUtils.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/util/MessageUtils.java Wed Apr 25 22:19:23 2007
@@ -29,16 +29,17 @@
 import org.apache.axiom.soap.SOAPEnvelope;
 import org.apache.axiom.soap.SOAPFactory;
 import org.apache.axis2.AxisFault;
+import org.apache.axis2.Constants;
 import org.apache.axis2.Constants.Configuration;
 import org.apache.axis2.client.Options;
 import org.apache.axis2.context.MessageContext;
 import org.apache.axis2.jaxws.ExceptionFactory;
-import org.apache.axis2.jaxws.message.Attachment;
 import org.apache.axis2.jaxws.message.Message;
 import org.apache.axis2.jaxws.message.Protocol;
 import org.apache.axis2.jaxws.message.attachments.AttachmentUtils;
 import org.apache.axis2.jaxws.message.factory.MessageFactory;
 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;
 
@@ -101,57 +102,25 @@
     }
 
     /**
-     * Create a JAXWS Message Attachment object from an SAAJ AttachmentPart
-     *
-     * @param ap      AttachmentPart
-     * @param message Message
-     * @return Attachment
-     * @throws SOAPException
-     */
-    public static Attachment createAttachment(AttachmentPart ap, Message message)
-            throws SOAPException {
-        // Create the attachment
-        Attachment a = message.createAttachment(ap.getDataHandler(), ap.getContentId());
-
-        // Copy over all of the headers
-        MimeHeaders mhs = new MimeHeaders();
-        Iterator it = ap.getAllMimeHeaders();
-        while (it.hasNext()) {
-            MimeHeader mh = (MimeHeader)it.next();
-            mhs.addHeader(mh.getName(), mh.getValue());
-        }
-        a.setMimeHeaders(mhs);
-
-        // Make sure content id is preserved
-        String contentID = ap.getContentId();
-        a.setContentID(contentID);
-        return a;
-    }
-
-    /**
      * Create an SAAJ AttachmentPart from a JAXWS Attachment
-     *
-     * @param a       Attachment
+     * @param cid String content id
+     * @param dh DataHandler
      * @param message SOAPMessage
      * @return AttachmentPart
      */
-    public static AttachmentPart createAttachmentPart(Attachment a, SOAPMessage message) {
+    public static AttachmentPart createAttachmentPart(String cid, DataHandler dh, SOAPMessage message) {
         // Create the Attachment Part
-        AttachmentPart ap = message.createAttachmentPart(a.getDataHandler());
-
-        // Copy over all of the Headers
-        Iterator it = a.getMimeHeaders().getAllHeaders();
-        while (it.hasNext()) {
-            MimeHeader mh = (MimeHeader)it.next();
-            ap.addMimeHeader(mh.getName(), mh.getValue());
-        }
-
+        AttachmentPart ap = message.createAttachmentPart(dh);
+        
+        // REVIEW
+        // Do we need to copy the content type from the datahandler ?
+        
         // Preserve the original content id
-        String contentID = a.getContentID();
-        ap.setContentId(contentID);
+        ap.setContentId(cid);
         return ap;
     }
 
+
     /**
      * Create a JAX-WS Message from the information on an Axis 2 Message Context
      *
@@ -178,6 +147,11 @@
                 throw ExceptionFactory.makeWebServiceException("Could not create new Message");
             }
 
+            Object property = msgContext.getProperty(Constants.Configuration.ENABLE_MTOM);
+            if (property != null && JavaUtils.isTrueExplicitly(property)) {
+                message.setMTOMEnabled(true);
+            }
+
             // Add all the MimeHeaders from the Axis2 MessageContext
             MimeHeaders mhs = message.getMimeHeaders();
             Map headerMap = (Map)msgContext.getProperty(MessageContext.TRANSPORT_HEADERS);
@@ -190,72 +164,9 @@
                 }
             }
 
-            // FIXME: This should be revisited when we re-work the MTOM support.
-            //This destroys performance by forcing a double pass through the message.
-            //If attachments are found on the MessageContext, then that means
-            //the inbound message has more than just the normal XML payload
-            Attachments as = (Attachments)msgContext.getProperty(MTOMConstants.ATTACHMENTS);
-            if (as != null) {
-                if (log.isDebugEnabled()) {
-                    log.debug("Found Axis MTOM Attachments");
-                }
-
-                //Walk the tree and find all of the optimized binary nodes.
-                ArrayList<OMText> binaryNodes =
-                        AttachmentUtils.findBinaryNodes((SOAPEnvelope)message.getAsOMElement());
-                if (binaryNodes != null && binaryNodes.size() > 0) {
-
-                    if (log.isDebugEnabled()) {
-                        log.debug("Found " + binaryNodes.size() + "MTOM Binary Nodes");
-                    }
-
-                    // Mark the JAX-WS Message as MTOM enabled
-                    message.setMTOMEnabled(true);
-
-                    //Replace each of the nodes with it's corresponding <xop:include>
-                    //element, so JAXB can process it correctly.
-                    Iterator<OMText> itr = binaryNodes.iterator();
-                    while (itr.hasNext()) {
-                        OMText node = itr.next();
-                        OMElement xop = AttachmentUtils.makeXopElement(node);
-                        node.getParent().addChild(xop);
-                        node.detach();
-
-                        //We have to add the individual attachments in their raw
-                        //binary form, so we can access them later.
-                        if (log.isDebugEnabled()) {
-                            log.debug("Create MTOM Message Attachment for " + node.getContentID());
-                        }
-                        Attachment a = message.createAttachment(
-                                (DataHandler)node.getDataHandler(),
-                                node.getContentID());
-                        message.addAttachment(a);
-                    }
-                }
-            }
-
-            // Get SWA Attachments from the Axis2 MessageContext
-            Attachments attachments = msgContext.getAttachmentMap();
-            if (attachments != null) {
-                String[] ids = attachments.getAllContentIDs();
-                if (ids != null) {
-                    // Axis2 stores the SOAP Part as one of the Attachments.
-                    // For now we will assume that the SOAPPart is the first attachment, and skip it.
-                    for (int i = 1; i < ids.length; i++) {
-                        // The Attachment may already be added as an MTOM attachment (by the processing above)
-                        if (message.getAttachment(ids[i]) == null) {
-                            DataHandler dh = attachments.getDataHandler(ids[i]);
-                            Attachment a = message.createAttachment(dh, ids[i]);
-                            message.addAttachment(a);
-                            if (log.isDebugEnabled()) {
-                                log.debug("Create JAXWS Attachment for SWA Attachment:" +
-                                        a.getContentID() + " " + a.getContentType());
-                            }
-                        }
-                    }
-                }
+            if (false) {
+                makeXOPIncludeNodes(msgContext, message);
             }
-
         }
         return message;
     }
@@ -287,63 +198,103 @@
 
         // Enable MTOM Attachments 
         if (message.isMTOMEnabled()) {
+            // Enable MTOM on the Axis2 MessageContext
+            Options opts = msgContext.getOptions();
+            opts.setProperty(Configuration.ENABLE_MTOM, "true");
+            if (false) {
+                makeBinaryNodes(message);
+            }
+        }
+    }
+    
+    /**
+     * Used to expand the tree and create binary nodes
+     * @param msg
+     * @deprecated
+     */
+    private static void makeBinaryNodes(Message msg) {
+        if (log.isDebugEnabled()) {
+            log.debug("MTOM is enabled on the JAX-WS Message...look for XOP Includes");
+        }
+        // If we have MTOM attachments, we need to replace the <xop:include>
+        // elements with OMText binary nodes.
+        
+        // First find all of the <xop:include> elements
+        SOAPEnvelope envelope = (SOAPEnvelope) msg.getAsOMElement();
+        ArrayList<OMElement> xops = AttachmentUtils.findXopElements(envelope);
+        
+        if (xops != null && xops.size() > 0) {
             if (log.isDebugEnabled()) {
-                log.debug("MTOM is enabled on the JAX-WS Message...look for XOP Includes");
+                log.debug("Found XOP:Include Elements");
             }
-            // If we have MTOM attachments, we need to replace the <xop:include>
-            // elements with OMText binary nodes.
-
-            // First find all of the <xop:include> elements
-            ArrayList<OMElement> xops = AttachmentUtils.findXopElements(envelope);
-
-            if (xops != null && xops.size() > 0) {
+            
+            QName href = new QName("","href");
+            Iterator<OMElement> itr = xops.iterator();
+            
+            
+            while (itr.hasNext()) {
+                OMElement xop = itr.next();
+                String cid = xop.getAttributeValue(href);
+                
+                // Find and remove the Attachment from the JAX-WS Message
+                // (It is removed so that it is not considered a SWA Attachment ...see below)
+                DataHandler dh = msg.removeDataHandler(cid);
                 if (log.isDebugEnabled()) {
-                    log.debug("Found XOP:Include Elements");
-                }
-                // Enable MTOM on the Axis2 MessageContext
-                Options opts = msgContext.getOptions();
-                opts.setProperty(Configuration.ENABLE_MTOM, "true");
-
-                QName href = new QName("", "href");
-                Iterator<OMElement> itr = xops.iterator();
-
-
-                while (itr.hasNext()) {
-                    OMElement xop = itr.next();
-                    String cid = xop.getAttributeValue(href);
-
-                    // Find and remove the Attachment from the JAX-WS Message
-                    // (It is removed so that it is not considered a SWA Attachment ...see below)
-                    Attachment a = message.removeAttachment(cid);
-                    if (log.isDebugEnabled()) {
-                        log.debug("Create Binary OMNode for attachment:" + cid);
-                    }
-
-                    // Convert the <xop:include> OMElement into an OMText
-                    // binary node and replace it in the tree.                    
-                    OMText binaryNode = AttachmentUtils.makeBinaryOMNode(xop, a);
-                    xop.insertSiblingAfter(binaryNode);
-                    xop.detach();
+                    log.debug("Create Binary OMNode for attachment:" + cid);
                 }
+                
+                // Convert the <xop:include> OMElement into an OMText
+                // binary node and replace it in the tree.                    
+                OMText binaryNode = AttachmentUtils.makeBinaryOMNode(xop, dh);
+                xop.insertSiblingAfter(binaryNode);
+                xop.detach();
             }
-
         }
-
-        // Any remaining attachments must be SWA attachments
-        List attachments = message.getAttachments();
-        if (attachments != null && attachments.size() > 0) {
-            // Indicate SWA Attachments are present
-            Options opts = msgContext.getOptions();
-            opts.setProperty(Configuration.ENABLE_SWA, "true");
-
-            for (int i = 0; i < attachments.size(); i++) {
-                Attachment a = (Attachment)attachments.get(i);
-                msgContext.addAttachment(a.getContentID(), a.getDataHandler());
+    }
+    
+    /**
+     * Expand the tree and create XOP nodes
+     * @param msg
+     * @deprecated
+     */
+    private static void makeXOPIncludeNodes(MessageContext msgContext, Message message) {
+        // This destroys performance by forcing a double pass through the message.
+        //If attachments are found on the MessageContext, then that means
+        //the inbound message has more than just the normal XML payload
+        Attachments as = (Attachments) msgContext.getProperty(MTOMConstants.ATTACHMENTS); 
+        if (as != null) { 
+            if (log.isDebugEnabled()) {
+                log.debug("Found Axis MTOM Attachments");
+            }
+            
+            //Walk the tree and find all of the optimized binary nodes.
+            ArrayList<OMText> binaryNodes = AttachmentUtils.findBinaryNodes((SOAPEnvelope) message.getAsOMElement());
+            if (binaryNodes != null  && binaryNodes.size() > 0) {
+                
                 if (log.isDebugEnabled()) {
-                    log.debug("Add SWA Attachment for:" + a.getContentID() + " " +
-                            a.getContentType());
+                    log.debug("Found " + binaryNodes.size() +"MTOM Binary Nodes");
+                }
+                
+                
+                //Replace each of the nodes with it's corresponding <xop:include>
+                //element, so JAXB can process it correctly.
+                Iterator<OMText> itr = binaryNodes.iterator();
+                while (itr.hasNext()) {
+                    OMText node = itr.next();
+                    OMElement xop = AttachmentUtils.makeXopElement(node);
+                    node.getParent().addChild(xop);
+                    node.detach();
+                    
+                    //We have to add the individual attachments in their raw
+                    //binary form, so we can access them later.
+                    if (log.isDebugEnabled()) {
+                        log.debug("Create MTOM Message Attachment for " + node.getContentID());
+                    }
+                    message.addDataHandler(
+                            (DataHandler) node.getDataHandler(), 
+                            node.getContentID());
                 }
             }
-        }
+        } 
     }
 }

Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/util/Reader2Writer.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/util/Reader2Writer.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/util/Reader2Writer.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/util/Reader2Writer.java Wed Apr 25 22:19:23 2007
@@ -57,7 +57,11 @@
         Iterator it = omDocument.getChildren();
         while (it.hasNext()) {
             OMNode omNode = (OMNode)it.next();
-            omNode.serializeAndConsume(writer);
+            // TODO Using serialize and consume
+            // caused an axiom bug...falling back to serialize
+            // (which is less performant due to om caching)
+            //omNode.serializeAndConsume(writer);
+            omNode.serialize(writer);
         }
         // Close the reader
         reader.close();

Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/util/impl/SAAJConverterImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/util/impl/SAAJConverterImpl.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/util/impl/SAAJConverterImpl.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/message/util/impl/SAAJConverterImpl.java Wed Apr 25 22:19:23 2007
@@ -18,6 +18,8 @@
 
 import org.apache.axiom.om.OMElement;
 import org.apache.axiom.om.OMNamespace;
+import org.apache.axiom.om.OMException;
+import org.apache.axiom.om.util.StAXUtils;
 import org.apache.axiom.om.impl.builder.StAXOMBuilder;
 import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
 import org.apache.axis2.jaxws.ExceptionFactory;
@@ -25,6 +27,9 @@
 import org.apache.axis2.jaxws.message.util.SAAJConverter;
 import org.apache.axis2.jaxws.message.util.SOAPElementReader;
 import org.apache.axis2.jaxws.utility.SAAJFactory;
+import org.apache.axis2.util.XMLUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 import javax.xml.namespace.QName;
 import javax.xml.soap.Detail;
@@ -42,11 +47,22 @@
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.ws.WebServiceException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.transform.stream.StreamResult;
 import java.util.Iterator;
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
 
 /** SAAJConverterImpl Provides an conversion methods between OM<->SAAJ */
 public class SAAJConverterImpl implements SAAJConverter {
 
+    private static final Log log = LogFactory.getLog(SAAJConverterImpl.class);
+
     /** Constructed via SAAJConverterFactory */
     SAAJConverterImpl() {
         super();
@@ -104,9 +120,50 @@
         StAXSOAPModelBuilder builder = new StAXSOAPModelBuilder(reader, null);
         // Create and return the OM Envelope
         org.apache.axiom.soap.SOAPEnvelope omEnvelope = builder.getSOAPEnvelope();
+        
+        // TODO The following statement expands the OM tree.  This is 
+        // a brute force workaround to get around an apparent bug in the om serialization
+        // (the pull stream parsing was not pulling the final tag).
+        // Four things need to occur:
+        //   a) analyze fix the serialization/pull stream problem.
+        //   b) add a method signature to allow the caller to request build or no build
+        //   c) add a method signature to allow the caller to enable/disable caching
+        //   d) possibly add an optimization to use OMSE for the body elements...to flatten the tree.
+        try {
+            omEnvelope.build();
+        } catch (OMException ex){
+            try {
+                // Let's try to see if we can save the envelope as a string
+                // and then make it into axiom SOAPEnvelope
+                return toOM(toString(saajEnvelope));
+            } catch (TransformerException e) {
+                throw ExceptionFactory.makeWebServiceException(e);
+            }
+        }
         return omEnvelope;
     }
 
+    private org.apache.axiom.soap.SOAPEnvelope toOM(String xml)
+            throws WebServiceException {
+        XMLStreamReader reader;
+        try {
+            reader = StAXUtils.createXMLStreamReader(new ByteArrayInputStream(xml.getBytes()));
+        } catch (XMLStreamException e) {
+            throw ExceptionFactory.makeWebServiceException(e);
+        }
+        // Get a SOAP OM Builder.  Passing null causes the version to be automatically triggered
+        StAXSOAPModelBuilder builder = new StAXSOAPModelBuilder(reader, null);
+        // Create and return the OM Envelope
+        return builder.getSOAPEnvelope();
+    }
+
+    private String toString(SOAPEnvelope saajEnvelope) throws TransformerException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Transformer tf;
+            tf = TransformerFactory.newInstance().newTransformer();
+            tf.transform(new DOMSource(saajEnvelope.getOwnerDocument()), new StreamResult(baos));
+        return new String(baos.toByteArray());
+    }
 
     /* (non-Javadoc)
       * @see org.apache.axis2.jaxws.message.util.SAAJConverter#toOM(javax.xml.soap.SOAPElement)
@@ -118,6 +175,14 @@
         StAXOMBuilder builder = new StAXOMBuilder(reader);
         // Create and return the Element
         OMElement om = builder.getDocumentElement();
+        // TODO The following statement expands the OM tree.  This is 
+        // a brute force workaround to get around an apparent bug in the om serialization
+        // (the pull stream parsing was not pulling the final tag).
+        // Three things need to occur:
+        //   a) analyze fix the serialization/pull stream problem.
+        //   b) add a method signature to allow the caller to request build or no build
+        //   c) add a method signature to allow the caller to enable/disable caching
+        om.build();
         return om;
     }
 
@@ -195,7 +260,7 @@
 
                         // The first START_ELEMENT defines the prefix and attributes of the root
                         if (parent == null) {
-                            updateTagData(nc, root, reader);
+                            updateTagData(nc, root, reader, false);
                             parent = root;
                         } else {
                             parent = createElementFromTag(nc, parent, reader);
@@ -294,12 +359,10 @@
         // All element children of a SOAPBody must be object's that are SOAPBodyElements.
         // createElement creates the proper child element.
         QName qName = reader.getName();
-        String prefix = reader.getPrefix();
-        Name name = nc.createName(qName.getLocalPart(), prefix, qName.getNamespaceURI());
-        SOAPElement child = createElement(parent, name);
+        SOAPElement child = createElement(parent, qName);
 
         // Update the tag data on the child
-        updateTagData(nc, child, reader);
+        updateTagData(nc, child, reader, true);
         return child;
     }
 
@@ -310,36 +373,36 @@
      * @param name   Name
      * @return
      */
-    protected SOAPElement createElement(SOAPElement parent, Name name)
+    protected SOAPElement createElement(SOAPElement parent, QName qName)
             throws SOAPException {
         SOAPElement child;
         if (parent instanceof SOAPEnvelope) {
-            if (name.getURI().equals(parent.getNamespaceURI())) {
-                if (name.getLocalName().equals("Body")) {
+            if (qName.getNamespaceURI().equals(parent.getNamespaceURI())) {
+                if (qName.getLocalPart().equals("Body")) {
                     child = ((SOAPEnvelope)parent).addBody();
                 } else {
                     child = ((SOAPEnvelope)parent).addHeader();
                 }
             } else {
-                child = parent.addChildElement(name);
+                child = parent.addChildElement(qName);
             }
         } else if (parent instanceof SOAPBody) {
-            if (name.getURI().equals(parent.getNamespaceURI()) &&
-                    name.getLocalName().equals("Fault")) {
+            if (qName.getNamespaceURI().equals(parent.getNamespaceURI()) &&
+                    qName.getLocalPart().equals("Fault")) {
                 child = ((SOAPBody)parent).addFault();
             } else {
-                child = ((SOAPBody)parent).addBodyElement(name);
+                child = ((SOAPBody)parent).addBodyElement(qName);
             }
         } else if (parent instanceof SOAPHeader) {
-            child = ((SOAPHeader)parent).addHeaderElement(name);
+            child = ((SOAPHeader)parent).addHeaderElement(qName);
         } else if (parent instanceof SOAPFault) {
             // This call assumes that the addChildElement implementation
             // is smart enough to add "Detail" or "SOAPFaultElement" objects.
-            child = parent.addChildElement(name);
+            child = parent.addChildElement(qName);
         } else if (parent instanceof Detail) {
-            child = ((Detail)parent).addDetailEntry(name);
+            child = ((Detail)parent).addDetailEntry(qName);
         } else {
-            child = parent.addChildElement(name);
+            child = parent.addChildElement(qName);
         }
 
         return child;
@@ -354,30 +417,42 @@
      */
     protected void updateTagData(NameCreator nc,
                                  SOAPElement element,
-                                 XMLStreamReader reader) throws SOAPException {
+                                 XMLStreamReader reader, 
+                                 boolean newElement) throws SOAPException {
         String prefix = reader.getPrefix();
         prefix = (prefix == null) ? "" : prefix;
 
         // Make sure the prefix is correct
         if (prefix.length() > 0 && !element.getPrefix().equals(prefix)) {
-            element.setPrefix(prefix);
-        }
+            // Due to a bug in Axiom DOM or in the reader...not sure where yet,
+            // there may be a non-null prefix and no namespace
+            String ns = reader.getNamespaceURI();
+            if (ns != null && ns.length() != 0) {
+                element.setPrefix(prefix);
+            }
 
-        //Remove all of the namespace declarations on the element
-        Iterator it = element.getNamespacePrefixes();
-        while (it.hasNext()) {
-            String aPrefix = (String)it.next();
-            element.removeNamespaceDeclaration(aPrefix);
         }
-
-        // Add the namespace declarations from the reader
-        int size = reader.getNamespaceCount();
-        for (int i = 0; i < size; i++) {
-            element.addNamespaceDeclaration(reader.getNamespacePrefix(i),
-                                            reader.getNamespaceURI(i));
+        
+        if (!newElement) {    
+            // Add the namespace declarations from the reader for the missing namespaces
+            int size = reader.getNamespaceCount();
+            for (int i=0; i<size; i++) {
+                String pre = reader.getNamespacePrefix(i);
+                String ns = reader.getNamespaceURI(i);
+                String existingNS = element.getNamespaceURI(pre);
+                if (!ns.equals(existingNS)) {
+                    element.removeNamespaceDeclaration(pre);  // Is it necessary to remove the existing prefix/ns
+                    element.addNamespaceDeclaration(pre, ns);
+                }
+            }
+        } else {
+            // Add the namespace declarations from the reader
+            int size = reader.getNamespaceCount();
+            for (int i=0; i<size; i++) {
+                element.addNamespaceDeclaration(reader.getNamespacePrefix(i), reader.getNamespaceURI(i));
+            }
         }
 
-        // Add attributes
         addAttributes(nc, element, reader);
 
         return;

Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/runtime/description/injection/impl/ResourceInjectionServiceRuntimeDescriptionBuilder.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/runtime/description/injection/impl/ResourceInjectionServiceRuntimeDescriptionBuilder.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/runtime/description/injection/impl/ResourceInjectionServiceRuntimeDescriptionBuilder.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/runtime/description/injection/impl/ResourceInjectionServiceRuntimeDescriptionBuilder.java Wed Apr 25 22:19:23 2007
@@ -53,7 +53,7 @@
         Method method = getPostConstructMethod(implClass);
         desc.setPostConstructMethod(method);
 
-        method = getPostConstructMethod(implClass);
+        method = getPreDestroyMethod(implClass);
         desc.setPreDestroyMethod(method);
 
         return desc;
@@ -95,7 +95,7 @@
         return null;
     }
 
-    static private Method getPreDestoryMethod(Class implClass) {
+    static private Method getPreDestroyMethod(Class implClass) {
         List<Method> methods = getMethods(implClass);
         for (Method method : methods) {
             if (method.getAnnotation(PreDestroy.class) != null) {



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