Author: heiko.braun(a)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(a)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>