[jbossws-commits] JBossWS SVN: r1408 - in branches/jbossws-1.0/src: main/java/org/jboss/ws/server main/java/org/jboss/ws/soap main/java/org/jboss/ws/xop test/resources/jaxrpc/marshall-doclit/META-INF test/resources/jaxrpc/marshall-doclit/WEB-INF test/resources/jaxrpc/marshall-rpclit/META-INF test/resources/jaxrpc/marshall-rpclit/WEB-INF

jbossws-commits at lists.jboss.org jbossws-commits at lists.jboss.org
Tue Nov 7 08:42:36 EST 2006


Author: heiko.braun at jboss.com
Date: 2006-11-07 08:42:25 -0500 (Tue, 07 Nov 2006)
New Revision: 1408

Added:
   branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/CreateAttachmentVisitor.java
Modified:
   branches/jbossws-1.0/src/main/java/org/jboss/ws/server/ServiceEndpoint.java
   branches/jbossws-1.0/src/main/java/org/jboss/ws/soap/SOAPConnectionImpl.java
   branches/jbossws-1.0/src/main/java/org/jboss/ws/soap/SOAPMessageImpl.java
   branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/RestoreXOPElementVisitor.java
   branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPContext.java
   branches/jbossws-1.0/src/test/resources/jaxrpc/marshall-doclit/META-INF/jboss-client.xml
   branches/jbossws-1.0/src/test/resources/jaxrpc/marshall-doclit/WEB-INF/web.xml
   branches/jbossws-1.0/src/test/resources/jaxrpc/marshall-rpclit/META-INF/jboss-client.xml
   branches/jbossws-1.0/src/test/resources/jaxrpc/marshall-rpclit/WEB-INF/web.xml
Log:
Fix JBWS-1333

Modified: branches/jbossws-1.0/src/main/java/org/jboss/ws/server/ServiceEndpoint.java
===================================================================
--- branches/jbossws-1.0/src/main/java/org/jboss/ws/server/ServiceEndpoint.java	2006-11-07 10:12:54 UTC (rev 1407)
+++ branches/jbossws-1.0/src/main/java/org/jboss/ws/server/ServiceEndpoint.java	2006-11-07 13:42:25 UTC (rev 1408)
@@ -38,6 +38,7 @@
 
 import org.jboss.logging.Logger;
 import org.jboss.ws.Constants;
+import org.jboss.ws.xop.XOPContext;
 import org.jboss.ws.binding.BindingException;
 import org.jboss.ws.common.CommonMessageContext;
 import org.jboss.ws.jaxrpc.SOAPFaultExceptionHelper;
@@ -249,6 +250,7 @@
          // Set the outbound headers
          if (headerSource != null)
          {
+            XOPContext.eagerlyCreateAttachments();
             resMessage.saveChanges();
             headerSource.setMimeHeaders(resMessage.getMimeHeaders());
          }

Modified: branches/jbossws-1.0/src/main/java/org/jboss/ws/soap/SOAPConnectionImpl.java
===================================================================
--- branches/jbossws-1.0/src/main/java/org/jboss/ws/soap/SOAPConnectionImpl.java	2006-11-07 10:12:54 UTC (rev 1407)
+++ branches/jbossws-1.0/src/main/java/org/jboss/ws/soap/SOAPConnectionImpl.java	2006-11-07 13:42:25 UTC (rev 1408)
@@ -23,21 +23,6 @@
 
 // $Id$
 
-import java.net.MalformedURLException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.xml.rpc.Stub;
-import javax.xml.soap.MimeHeader;
-import javax.xml.soap.MimeHeaders;
-import javax.xml.soap.SOAPConnection;
-import javax.xml.soap.SOAPEnvelope;
-import javax.xml.soap.SOAPException;
-import javax.xml.soap.SOAPMessage;
-import javax.xml.ws.addressing.EndpointReference;
-
 import org.jboss.logging.Logger;
 import org.jboss.remoting.Client;
 import org.jboss.remoting.InvokerLocator;
@@ -45,7 +30,17 @@
 import org.jboss.ws.binding.soap.SOAPMessageMarshaller;
 import org.jboss.ws.binding.soap.SOAPMessageUnMarshaller;
 import org.jboss.ws.jaxrpc.StubExt;
+import org.jboss.ws.xop.XOPContext;
 
+import javax.xml.rpc.Stub;
+import javax.xml.soap.*;
+import javax.xml.ws.addressing.EndpointReference;
+import java.net.MalformedURLException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
 /**
  * SOAPConnection implementation
  *
@@ -113,14 +108,11 @@
          throw new IllegalArgumentException("Given SOAPMessage cannot be null");
       if (endpoint == null)
          throw new IllegalArgumentException("Given endpoint cannot be null");
-
       if (closed)
          throw new SOAPException("SOAPConnection is already closed");
 
-      InvokerLocator locator;
-      Client remotingClient;
       String targetAddress;
-      Map callProps;
+      Map callProps = null;
 
       if (endpoint instanceof EndpointInfo)
       {
@@ -139,83 +131,92 @@
       {
          EndpointReference epr = (EndpointReference)endpoint;
          targetAddress = epr.getAddress().toString();
-         callProps = null;
       }
       else
       {
          targetAddress = endpoint.toString();
-         callProps = null;
       }
 
-      try
-      {
-         // Get the invoker from Remoting for a given endpoint address
-         log.debug("Get locator for: " + endpoint);
-         locator = new InvokerLocator(targetAddress);
-      }
-      catch (MalformedURLException e)
-      {
-         throw new SOAPException("Malformed endpoint address", e);
-      }
+      // enforce xop transitions
+      // TODO: there should be a clear transition to an immutable object model
+      XOPContext.eagerlyCreateAttachments();
 
-      Map metadata = getRemotingMetaData(reqMessage, targetAddress, callProps);
+      // save object model changes
+      if (reqMessage.saveRequired()) reqMessage.saveChanges();
 
-      try
-      {
-         remotingClient = new Client(locator, "saaj", config);
-         remotingClient.setMarshaller(new SOAPMessageMarshaller());
-         remotingClient.setUnMarshaller(oneway == false ? new SOAPMessageUnMarshaller() : null);
-      }
-      catch (RuntimeException rte)
-      {
-         throw rte;
-      }
-      catch (Exception e)
-      {
-         throw new SOAPException("Could not setup remoting client", e);
-      }
+      // setup remoting client
+      Map metadata = createRemotingMetaData(reqMessage, callProps);
+      Client client = createRemotingClient(endpoint, targetAddress, oneway);
 
       try
       {
          // debug the outgoing message
-         if(msgLog.isTraceEnabled())
-         {
-            SOAPEnvelope soapReqEnv = reqMessage.getSOAPPart().getEnvelope();
-            String envStr = SOAPElementWriter.writeElement((SOAPElementImpl)soapReqEnv, true);
-            msgLog.trace("Remoting meta data: " + metadata);
-            msgLog.trace("Outgoing SOAPMessage\n" + envStr);
-         }
+         traceRequest(reqMessage, metadata);
 
          SOAPMessage resMessage = null;
          if (oneway == true)
          {
-            remotingClient.invokeOneway(reqMessage, metadata, false);
+            client.invokeOneway(reqMessage, metadata, false);
          }
          else
          {
-            resMessage = (SOAPMessage)remotingClient.invoke(reqMessage, metadata);
+            resMessage = (SOAPMessage)client.invoke(reqMessage, metadata);
          }
 
          // debug the incomming response message
-         if (resMessage != null && msgLog.isTraceEnabled())
-         {
-            SOAPEnvelope soapResEnv = resMessage.getSOAPPart().getEnvelope();
-            String envStr = SOAPElementWriter.writeElement((SOAPElementImpl)soapResEnv, true);
-            msgLog.trace("Incoming Response SOAPMessage\n" + envStr);
-         }
+         traceResponse(resMessage);
 
          return resMessage;
+
       }
-      catch (RuntimeException rte)
-      {
-         throw rte;
-      }
       catch (Throwable t)
       {
          throw new SOAPException("Could not transmit message", t);
       }
    }
 
+   private void traceResponse(SOAPMessage resMessage) throws SOAPException {
+      if (resMessage != null && msgLog.isTraceEnabled())
+      {
+         SOAPEnvelope soapResEnv = resMessage.getSOAPPart().getEnvelope();
+         String envStr = SOAPElementWriter.writeElement((SOAPElementImpl)soapResEnv, true);
+         msgLog.trace("Incoming Response SOAPMessage\n" + envStr);
+      }
+   }
+
+   private void traceRequest(SOAPMessage reqMessage, Map metadata) throws SOAPException {
+      if(msgLog.isTraceEnabled())
+      {
+         SOAPEnvelope soapReqEnv = reqMessage.getSOAPPart().getEnvelope();
+         String envStr = SOAPElementWriter.writeElement((SOAPElementImpl)soapReqEnv, true);
+         msgLog.trace("Remoting meta data: " + metadata);
+         msgLog.trace("Outgoing SOAPMessage\n" + envStr);
+      }
+   }
+
+   private Client createRemotingClient(Object endpoint, String targetAddress, boolean oneway) throws SOAPException {
+      Client remotingClient;
+      try
+      {
+         // Get the invoker from Remoting for a given endpoint address
+         log.debug("Get locator for: " + endpoint);
+         InvokerLocator locator = new InvokerLocator(targetAddress);
+
+         remotingClient = new Client(locator, "saaj", config);
+         remotingClient.setMarshaller(new SOAPMessageMarshaller());
+         remotingClient.setUnMarshaller(oneway == false ? new SOAPMessageUnMarshaller() : null);
+      }
+      catch (MalformedURLException e)
+      {
+         throw new SOAPException("Malformed endpoint address", e);
+      }
+      catch (Exception e)
+      {
+         throw new SOAPException("Could not setup remoting client", e);
+      }
+      return remotingClient;
+   }
+
    /** Closes this SOAPConnection
     */
    public void close() throws SOAPException
@@ -226,7 +227,7 @@
       closed = true;
    }
 
-   private Map getRemotingMetaData(SOAPMessage reqMessage, String targetAddress, Map callProps) throws SOAPException
+   private Map createRemotingMetaData(SOAPMessage reqMessage, Map callProps) throws SOAPException
    {
       // R2744 A HTTP request MESSAGE MUST contain a SOAPAction HTTP header field
       // with a quoted value equal to the value of the soapAction attribute of
@@ -236,7 +237,7 @@
       // with a quoted empty string value, if in the corresponding WSDL description,
       // the soapAction attribute of soapbind:operation is either not present, or
       // present with an empty string as its value.
-	   
+
       MimeHeaders mimeHeaders = reqMessage.getMimeHeaders();
       String[] action = mimeHeaders.getHeader("SOAPAction");
       if (action != null && action.length > 0)
@@ -254,9 +255,6 @@
          mimeHeaders.setHeader("SOAPAction", "\"\"");
       }
 
-      if (reqMessage.saveRequired())
-         reqMessage.saveChanges();
-
       Map<String, Object> metadata = new HashMap<String, Object>();
       Properties props = new Properties();
       metadata.put("HEADER", props);

Modified: branches/jbossws-1.0/src/main/java/org/jboss/ws/soap/SOAPMessageImpl.java
===================================================================
--- branches/jbossws-1.0/src/main/java/org/jboss/ws/soap/SOAPMessageImpl.java	2006-11-07 10:12:54 UTC (rev 1407)
+++ branches/jbossws-1.0/src/main/java/org/jboss/ws/soap/SOAPMessageImpl.java	2006-11-07 13:42:25 UTC (rev 1408)
@@ -129,8 +129,8 @@
          String contentId = part.getContentId();
          if (contentId.equals(cid))
          {
-           attachments.remove(part);
-           return part;
+            attachments.remove(part);
+            return part;
          }
       }
 
@@ -213,27 +213,32 @@
       {
          try
          {
-            if (isXOPMessage() && !XOPContext.isMTOMEnabled() && attachments.size() > 0)
+            boolean hasAttachments = attachments.size() > 0;
+
+            if (isXOPMessage() && !XOPContext.isMTOMEnabled() && hasAttachments)
                throw new IllegalStateException("XOP parameter not properly inlined");
-            
-            String contentType;
-            if (isXOPMessage() && XOPContext.isMTOMEnabled())
+
+            // default content-type
+            String contentType = MimeConstants.TYPE_SOAP11 + "; charset=" + getCharSetEncoding();
+
+            if (hasAttachments)
             {
-               multipartRelatedEncoder = new MultipartRelatedXOPEncoder(this);
-               multipartRelatedEncoder.encodeMultipartRelatedMessage();
-               contentType = multipartRelatedEncoder.getContentType();
+               if (isXOPMessage() && XOPContext.isMTOMEnabled())
+               {
+                  multipartRelatedEncoder = new MultipartRelatedXOPEncoder(this);
+                  multipartRelatedEncoder.encodeMultipartRelatedMessage();
+                  contentType = multipartRelatedEncoder.getContentType();
+               }
+               else
+               {
+                  multipartRelatedEncoder = new MultipartRelatedSwAEncoder(this);
+                  multipartRelatedEncoder.encodeMultipartRelatedMessage();
+                  contentType = multipartRelatedEncoder.getContentType();
+               }
             }
-            else if (attachments.size() > 0)
-            {
-               multipartRelatedEncoder = new MultipartRelatedSwAEncoder(this);
-               multipartRelatedEncoder.encodeMultipartRelatedMessage();
-               contentType = multipartRelatedEncoder.getContentType();
-            }
-            else
-            {
-               contentType = MimeConstants.TYPE_SOAP11 + "; charset=" + getCharSetEncoding();
-            }
+
             mimeHeaders.setHeader(MimeConstants.CONTENT_TYPE, contentType);
+
          }
          catch (MessagingException ex)
          {

Added: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/CreateAttachmentVisitor.java
===================================================================
--- branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/CreateAttachmentVisitor.java	2006-11-07 10:12:54 UTC (rev 1407)
+++ branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/CreateAttachmentVisitor.java	2006-11-07 13:42:25 UTC (rev 1408)
@@ -0,0 +1,89 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.ws.xop;
+
+import org.jboss.ws.soap.SAAJVisitor;
+import org.jboss.ws.soap.SOAPElementImpl;
+import org.jboss.ws.soap.SOAPContentElement;
+
+import java.util.Iterator;
+import java.io.Writer;
+import java.io.IOException;
+
+/**
+ * @author Heiko Braun <heiko.braun at jboss.com>
+ * @version $Id$
+ * @since Nov 7, 2006
+ */
+public class CreateAttachmentVisitor implements SAAJVisitor {
+    public void visitXOPElements(SOAPElementImpl root)
+   {
+      boolean isSCE = (root instanceof SOAPContentElement);
+
+      // don't expand SOAPContentElements
+      if(isSCE)
+      {
+         root.accept(this);
+      }
+      else
+      {
+         Iterator it = root.getChildElements();
+         while(it.hasNext())
+         {
+            final Object o = it.next();
+            if(o instanceof SOAPElementImpl)
+               visitXOPElements((SOAPElementImpl)o);
+         }
+      }
+   }
+
+   public void visitSOAPElement(SOAPElementImpl soapElement) {
+      // nada
+   }
+
+   public void visitSOAPContentElement(SOAPContentElement scElement) {
+      // Calling writeElement will enforce marshalling of this object
+      // Any attachment will be created while doiong this.
+      try
+      {
+         scElement.writeElement( new NoopWriter() );
+      }
+      catch (IOException e)
+      {
+         //
+      }
+   }
+
+   class NoopWriter extends Writer {
+      public void write(char cbuf[], int off, int len) throws IOException {
+
+      }
+
+      public void flush() throws IOException {
+
+      }
+
+      public void close() throws IOException {
+
+      }
+   }
+}


Property changes on: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/CreateAttachmentVisitor.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Modified: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/RestoreXOPElementVisitor.java
===================================================================
--- branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/RestoreXOPElementVisitor.java	2006-11-07 10:12:54 UTC (rev 1407)
+++ branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/RestoreXOPElementVisitor.java	2006-11-07 13:42:25 UTC (rev 1408)
@@ -58,7 +58,9 @@
          Iterator it = root.getChildElements();
          while(it.hasNext())
          {
-            visitXOPElements((SOAPElementImpl)it.next());
+            final Object o = it.next();
+            if(o instanceof SOAPElementImpl)
+               visitXOPElements((SOAPElementImpl)o);
          }
       }
    }

Modified: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPContext.java
===================================================================
--- branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPContext.java	2006-11-07 10:12:54 UTC (rev 1407)
+++ branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPContext.java	2006-11-07 13:42:25 UTC (rev 1408)
@@ -40,10 +40,7 @@
 
 import javax.activation.DataHandler;
 import javax.xml.namespace.QName;
-import javax.xml.soap.AttachmentPart;
-import javax.xml.soap.SOAPBody;
-import javax.xml.soap.SOAPElement;
-import javax.xml.soap.SOAPException;
+import javax.xml.soap.*;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.util.Iterator;
@@ -176,6 +173,38 @@
    }
 
    /**
+    * The XOP attachments need to be created before the actual message is written
+    * to an output stream. This is necessary because it changes the overall message content-type.
+    * If we would do this lazily (i.e. upon remoting callback) the previous content-type
+    * would already have been written.
+    *
+    * @see org.jboss.ws.soap.SOAPConnectionImpl#callInternal(javax.xml.soap.SOAPMessage, Object, boolean)
+    * @see org.jboss.ws.binding.soap.SOAPMessageMarshaller#write(Object, java.io.OutputStream)
+    */
+   public static void eagerlyCreateAttachments()
+   {
+      if(!isXOPMessage())
+         return;
+      
+      try
+      {
+         CommonMessageContext msgContext = MessageContextAssociation.peekMessageContext();
+         SOAPMessage soapMessage = msgContext != null ? msgContext.getSOAPMessage() : null;
+         SOAPBody body = soapMessage!=null ? soapMessage.getSOAPBody() : null;
+
+         if(body!=null)
+         {
+            CreateAttachmentVisitor visitor = new CreateAttachmentVisitor();
+            visitor.visitXOPElements((SOAPElementImpl)body);
+         }
+      }
+      catch (SOAPException e)
+      {
+         throw new WSException("Failed to eagerly create XOP attachments", e);
+      }
+   }
+
+   /**
     * Visit the soap object model elements and restore xop data.
     */
    public static void visitAndRestoreXOPData()

Modified: branches/jbossws-1.0/src/test/resources/jaxrpc/marshall-doclit/META-INF/jboss-client.xml
===================================================================
--- branches/jbossws-1.0/src/test/resources/jaxrpc/marshall-doclit/META-INF/jboss-client.xml	2006-11-07 10:12:54 UTC (rev 1407)
+++ branches/jbossws-1.0/src/test/resources/jaxrpc/marshall-doclit/META-INF/jboss-client.xml	2006-11-07 13:42:25 UTC (rev 1408)
@@ -8,8 +8,7 @@
   <jndi-name>jbossws-client</jndi-name>
 
   <service-ref>
-    <service-ref-name>service/StandardTypes</service-ref-name>
-    <config-name>Standard MTOM disabled client</config-name>
+    <service-ref-name>service/StandardTypes</service-ref-name>    
     <wsdl-override>http://@jbosstest.host.name@:8080/jaxrpc-marshall-doclit?wsdl</wsdl-override>
   </service-ref>
 

Modified: branches/jbossws-1.0/src/test/resources/jaxrpc/marshall-doclit/WEB-INF/web.xml
===================================================================
--- branches/jbossws-1.0/src/test/resources/jaxrpc/marshall-doclit/WEB-INF/web.xml	2006-11-07 10:12:54 UTC (rev 1407)
+++ branches/jbossws-1.0/src/test/resources/jaxrpc/marshall-doclit/WEB-INF/web.xml	2006-11-07 13:42:25 UTC (rev 1408)
@@ -5,11 +5,6 @@
   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
   version="2.4">
 
-   <context-param>
-      <param-name>jbossws-config-name</param-name>
-      <param-value>Standard MTOM disabled endpoint</param-value>
-   </context-param>
-
   <servlet>
     <servlet-name>StandardTypes</servlet-name>
     <servlet-class>org.jboss.test.ws.jaxrpc.marshall.StandardTypesBean</servlet-class>

Modified: branches/jbossws-1.0/src/test/resources/jaxrpc/marshall-rpclit/META-INF/jboss-client.xml
===================================================================
--- branches/jbossws-1.0/src/test/resources/jaxrpc/marshall-rpclit/META-INF/jboss-client.xml	2006-11-07 10:12:54 UTC (rev 1407)
+++ branches/jbossws-1.0/src/test/resources/jaxrpc/marshall-rpclit/META-INF/jboss-client.xml	2006-11-07 13:42:25 UTC (rev 1408)
@@ -8,8 +8,7 @@
   <jndi-name>jbossws-client</jndi-name>
 
   <service-ref>
-    <service-ref-name>service/StandardTypes</service-ref-name>
-     <config-name>Standard MTOM disabled client</config-name>
+    <service-ref-name>service/StandardTypes</service-ref-name>     
     <wsdl-override>http://@jbosstest.host.name@:8080/jaxrpc-marshall-rpclit?wsdl</wsdl-override>
   </service-ref>
 

Modified: branches/jbossws-1.0/src/test/resources/jaxrpc/marshall-rpclit/WEB-INF/web.xml
===================================================================
--- branches/jbossws-1.0/src/test/resources/jaxrpc/marshall-rpclit/WEB-INF/web.xml	2006-11-07 10:12:54 UTC (rev 1407)
+++ branches/jbossws-1.0/src/test/resources/jaxrpc/marshall-rpclit/WEB-INF/web.xml	2006-11-07 13:42:25 UTC (rev 1408)
@@ -5,11 +5,6 @@
   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
   version="2.4">
 
-   <context-param>
-      <param-name>jbossws-config-name</param-name>
-      <param-value>Standard MTOM disabled endpoint</param-value>
-   </context-param>
-
    <servlet>
     <servlet-name>StandardTypes</servlet-name>
     <servlet-class>org.jboss.test.ws.jaxrpc.marshall.StandardTypesBean</servlet-class>




More information about the jbossws-commits mailing list