null, no fault resolving is performed.
*
- * This template uses the following algorithm for sending and receiving. Source, marshalling, etc.true if this WebServiceMessageSender supports the supplied URI
*/
- boolean supports(String uri);
+ boolean supports(URI uri);
}
diff --git a/core/src/main/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSender.java b/core/src/main/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSender.java
index 50bfb797..81a2d311 100644
--- a/core/src/main/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSender.java
+++ b/core/src/main/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSender.java
@@ -16,7 +16,8 @@
package org.springframework.ws.transport.http;
-import org.springframework.util.StringUtils;
+import java.net.URI;
+
import org.springframework.ws.transport.WebServiceMessageSender;
/**
@@ -30,14 +31,6 @@ public abstract class AbstractHttpWebServiceMessageSender implements WebServiceM
private boolean acceptGzipEncoding = true;
- protected static final String HTTP_HEADER_ACCEPT_ENCODING = "Accept-Encoding";
-
- protected static final String ENCODING_GZIP = "gzip";
-
- protected static final String HTTP_SCHEME = "http://";
-
- protected static final String HTTPS_SCHEME = "https://";
-
/**
* Return whether to accept GZIP encoding, that is, whether to send the HTTP Accept-Encoding header
* with gzip as value.
@@ -57,7 +50,8 @@ public abstract class AbstractHttpWebServiceMessageSender implements WebServiceM
this.acceptGzipEncoding = acceptGzipEncoding;
}
- public boolean supports(String uri) {
- return StringUtils.hasLength(uri) && (uri.startsWith(HTTP_SCHEME) || uri.startsWith(HTTPS_SCHEME));
+ public boolean supports(URI uri) {
+ return uri.getScheme().equals(HttpTransportConstants.HTTP_URI_SCHEME) ||
+ uri.getScheme().equals(HttpTransportConstants.HTTPS_URI_SCHEME);
}
}
diff --git a/core/src/main/java/org/springframework/ws/transport/http/CommonsHttpMessageSender.java b/core/src/main/java/org/springframework/ws/transport/http/CommonsHttpMessageSender.java
index c3e9dfa0..63df369e 100644
--- a/core/src/main/java/org/springframework/ws/transport/http/CommonsHttpMessageSender.java
+++ b/core/src/main/java/org/springframework/ws/transport/http/CommonsHttpMessageSender.java
@@ -17,6 +17,12 @@
package org.springframework.ws.transport.http;
import java.io.IOException;
+import java.net.URI;
+
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.util.Assert;
+import org.springframework.ws.transport.WebServiceConnection;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
@@ -26,10 +32,6 @@ import org.apache.commons.httpclient.NTCredentials;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.PostMethod;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.util.Assert;
-import org.springframework.ws.transport.WebServiceConnection;
/**
* WebServiceMessageSender implementation that uses Jakarta
@@ -130,10 +132,11 @@ public class CommonsHttpMessageSender extends AbstractHttpWebServiceMessageSende
}
}
- public WebServiceConnection createConnection(String uri) throws IOException {
- PostMethod postMethod = new PostMethod(uri);
+ public WebServiceConnection createConnection(URI uri) throws IOException {
+ PostMethod postMethod = new PostMethod(uri.toString());
if (isAcceptGzipEncoding()) {
- postMethod.addRequestHeader(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
+ postMethod.addRequestHeader(HttpTransportConstants.HEADER_ACCEPT_ENCODING,
+ HttpTransportConstants.CONTENT_ENCODING_GZIP);
}
return new CommonsHttpConnection(getHttpClient(), postMethod);
}
diff --git a/core/src/main/java/org/springframework/ws/transport/http/HttpTransportConstants.java b/core/src/main/java/org/springframework/ws/transport/http/HttpTransportConstants.java
index 3c598ffc..6a46c6a9 100644
--- a/core/src/main/java/org/springframework/ws/transport/http/HttpTransportConstants.java
+++ b/core/src/main/java/org/springframework/ws/transport/http/HttpTransportConstants.java
@@ -29,6 +29,9 @@ public interface HttpTransportConstants extends TransportConstants {
/** The "Content-Encoding" header. */
String HEADER_CONTENT_ENCODING = "Content-Encoding";
+ /** The "Accept-Encoding" header. */
+ String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
+
/** Header value that indicates a compressed "Content-Encoding". */
String CONTENT_ENCODING_GZIP = "gzip";
@@ -43,4 +46,10 @@ public interface HttpTransportConstants extends TransportConstants {
/** The "500 Server Error" status code. */
int STATUS_INTERNAL_SERVER_ERROR = 500;
+
+ /** The "http" URI scheme. */
+ String HTTP_URI_SCHEME = "http";
+
+ /** The "https" URI scheme. */
+ String HTTPS_URI_SCHEME = "https";
}
diff --git a/core/src/main/java/org/springframework/ws/transport/http/HttpUrlConnectionMessageSender.java b/core/src/main/java/org/springframework/ws/transport/http/HttpUrlConnectionMessageSender.java
index 13d5e256..f91ad4f4 100644
--- a/core/src/main/java/org/springframework/ws/transport/http/HttpUrlConnectionMessageSender.java
+++ b/core/src/main/java/org/springframework/ws/transport/http/HttpUrlConnectionMessageSender.java
@@ -18,6 +18,7 @@ package org.springframework.ws.transport.http;
import java.io.IOException;
import java.net.HttpURLConnection;
+import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
@@ -39,8 +40,8 @@ public class HttpUrlConnectionMessageSender extends AbstractHttpWebServiceMessag
private static final String HTTP_METHOD_POST = "POST";
- public WebServiceConnection createConnection(String uri) throws IOException {
- URL url = new URL(uri);
+ public WebServiceConnection createConnection(URI uri) throws IOException {
+ URL url = uri.toURL();
URLConnection connection = url.openConnection();
if (!(connection instanceof HttpURLConnection)) {
throw new HttpTransportException("URI [" + uri + "] is not an HTTP URL");
@@ -52,7 +53,8 @@ public class HttpUrlConnectionMessageSender extends AbstractHttpWebServiceMessag
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
if (isAcceptGzipEncoding()) {
- httpURLConnection.setRequestProperty(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
+ httpURLConnection.setRequestProperty(HttpTransportConstants.HEADER_ACCEPT_ENCODING,
+ HttpTransportConstants.CONTENT_ENCODING_GZIP);
}
return new HttpUrlConnection(httpURLConnection);
}
diff --git a/core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateTest.java b/core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateTest.java
index d923c363..d57b66a2 100644
--- a/core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateTest.java
+++ b/core/src/test/java/org/springframework/ws/client/core/WebServiceTemplateTest.java
@@ -17,14 +17,12 @@
package org.springframework.ws.client.core;
import java.io.IOException;
+import java.net.URI;
-import org.custommonkey.xmlunit.XMLTestCase;
-import org.easymock.MockControl;
import org.springframework.oxm.Marshaller;
import org.springframework.oxm.Unmarshaller;
import org.springframework.ws.MockWebServiceMessage;
import org.springframework.ws.MockWebServiceMessageFactory;
-import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.client.WebServiceTransportException;
import org.springframework.ws.transport.FaultAwareWebServiceConnection;
import org.springframework.ws.transport.WebServiceConnection;
@@ -32,6 +30,9 @@ import org.springframework.ws.transport.WebServiceMessageSender;
import org.springframework.xml.transform.StringResult;
import org.springframework.xml.transform.StringSource;
+import org.custommonkey.xmlunit.XMLTestCase;
+import org.easymock.MockControl;
+
public class WebServiceTemplateTest extends XMLTestCase {
private WebServiceTemplate template;
@@ -42,27 +43,25 @@ public class WebServiceTemplateTest extends XMLTestCase {
private MockWebServiceMessageFactory messageFactory;
- private static final String URI = "uri";
-
protected void setUp() throws Exception {
template = new WebServiceTemplate();
messageFactory = new MockWebServiceMessageFactory();
template.setMessageFactory(messageFactory);
connectionControl = MockControl.createStrictControl(FaultAwareWebServiceConnection.class);
connectionMock = (FaultAwareWebServiceConnection) connectionControl.getMock();
+ final URI expectedUri = new URI("http://www.springframework.org/spring-ws");
template.setMessageSender(new WebServiceMessageSender() {
- public WebServiceConnection createConnection(String uri) throws IOException {
+ public WebServiceConnection createConnection(URI uri) throws IOException {
return connectionMock;
}
- public boolean supports(String uri) {
- assertEquals("Invalid uri", URI, uri);
+ public boolean supports(URI uri) {
+ assertEquals("Invalid uri", expectedUri, uri);
return true;
}
});
-
- template.setDefaultUri(URI);
+ template.setDefaultUri(expectedUri.toString());
}
public void testMarshalAndSendNoMarshallerSet() throws Exception {
@@ -131,7 +130,7 @@ public class WebServiceTemplateTest extends XMLTestCase {
connectionMock.close();
connectionControl.replay();
- Object result = (WebServiceMessage) template.sendAndReceive(null, extractorMock);
+ Object result = template.sendAndReceive(null, extractorMock);
assertNull("Invalid response", result);
extractorControl.verify();
connectionControl.verify();
@@ -340,14 +339,14 @@ public class WebServiceTemplateTest extends XMLTestCase {
}
public void testSendAndReceiveCustomUri() throws Exception {
- final String customUri = "customUri";
+ final URI customUri = new URI("http://www.springframework.org/spring-ws/custom");
template.setMessageSender(new WebServiceMessageSender() {
- public WebServiceConnection createConnection(String uri) throws IOException {
+ public WebServiceConnection createConnection(URI uri) throws IOException {
return connectionMock;
}
- public boolean supports(String uri) {
+ public boolean supports(URI uri) {
assertEquals("Invalid uri", customUri, uri);
return true;
}
@@ -375,7 +374,7 @@ public class WebServiceTemplateTest extends XMLTestCase {
connectionMock.close();
connectionControl.replay();
- Object result = template.sendAndReceive(customUri, requestCallback, extractorMock);
+ Object result = template.sendAndReceive(customUri.toString(), requestCallback, extractorMock);
assertEquals("Invalid response", extracted, result);
callbackControl.verify();
diff --git a/core/src/test/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSenderIntegrationTestCase.java b/core/src/test/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSenderIntegrationTestCase.java
index 20267265..5bf0a7dc 100644
--- a/core/src/test/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSenderIntegrationTestCase.java
+++ b/core/src/test/java/org/springframework/ws/transport/http/AbstractHttpWebServiceMessageSenderIntegrationTestCase.java
@@ -18,6 +18,7 @@ package org.springframework.ws.transport.http;
import java.io.IOException;
import java.io.OutputStream;
+import java.net.URI;
import java.util.zip.GZIPOutputStream;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
@@ -34,11 +35,6 @@ import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
-import org.custommonkey.xmlunit.XMLTestCase;
-import org.custommonkey.xmlunit.XMLUnit;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.servlet.Context;
-import org.mortbay.jetty.servlet.ServletHolder;
import org.springframework.util.FileCopyUtils;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.WebServiceMessageFactory;
@@ -49,6 +45,12 @@ import org.springframework.ws.transport.WebServiceConnection;
import org.springframework.xml.transform.StringResult;
import org.springframework.xml.transform.StringSource;
+import org.custommonkey.xmlunit.XMLTestCase;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.servlet.Context;
+import org.mortbay.jetty.servlet.ServletHolder;
+
public abstract class AbstractHttpWebServiceMessageSenderIntegrationTestCase extends XMLTestCase {
private Server jettyServer;
@@ -77,7 +79,7 @@ public abstract class AbstractHttpWebServiceMessageSenderIntegrationTestCase ext
private Context jettyContext;
- private static final String URI = "http://localhost:8888/";
+ private static final String URI_STRING = "http://localhost:8888/";
private MessageFactory saajMessageFactory;
@@ -147,7 +149,7 @@ public abstract class AbstractHttpWebServiceMessageSenderIntegrationTestCase ext
jettyContext.addServlet(new ServletHolder(servlet), "/");
jettyServer.start();
FaultAwareWebServiceConnection connection =
- (FaultAwareWebServiceConnection) messageSender.createConnection(URI);
+ (FaultAwareWebServiceConnection) messageSender.createConnection(new URI(URI_STRING));
SOAPMessage request = createRequest();
try {
connection.send(new SaajSoapMessage(request));
@@ -163,7 +165,7 @@ public abstract class AbstractHttpWebServiceMessageSenderIntegrationTestCase ext
jettyContext.addServlet(new ServletHolder(servlet), "/");
jettyServer.start();
FaultAwareWebServiceConnection connection =
- (FaultAwareWebServiceConnection) messageSender.createConnection(URI);
+ (FaultAwareWebServiceConnection) messageSender.createConnection(new URI(URI_STRING));
SOAPMessage request = createRequest();
try {
connection.send(new SaajSoapMessage(request));
@@ -189,7 +191,7 @@ public abstract class AbstractHttpWebServiceMessageSenderIntegrationTestCase ext
jettyContext.addServlet(new ServletHolder(servlet), "/");
jettyServer.start();
- WebServiceConnection connection = messageSender.createConnection(URI);
+ WebServiceConnection connection = messageSender.createConnection(new URI(URI_STRING));
SOAPMessage request = createRequest();
try {
connection.send(new SaajSoapMessage(request));
diff --git a/support/pom.xml b/support/pom.xml
index 6b019557..d1f1934d 100644
--- a/support/pom.xml
+++ b/support/pom.xml
@@ -73,6 +73,22 @@
queue or
- * queueName property. It creates a temporary queue for the response message. For both request and response
- * {@link BytesMessage}s are used.
+ * This message sender supports URI's of the following format: jms:destination[?param-name=param-value][¶m-name=param-value]* + *where the characters :, ?, and & stand for + * themselves. The destination represents the name of the {@link Queue} or {@link Topic} that will be resolved by + * the {@link #getDestinationResolver() destination resolver}. Valid param-name include: + * + *
+ * + * If the replyToName is not set, a {@link Session#createTemporaryQueue() temporary queue} is used. + * + * Some examples of JMS URIs are: + * + *
+ * param-name Description + * deliveryMode Indicates whether the request message is persistent or not. This may be + * PERSISTENT or NON_PERSISTENT. See {@link MessageProducer#setDeliveryMode(int)} timeToLive The lifetime, in milliseconds, of the request message. See {@link + * MessageProducer#setTimeToLive(long)} + * priority The JMS priority (0-9) associated + * with the request message. See {@link MessageProducer#setPriority(int)} replyToName The name of the destination to which the response message must be sent, that + * will be resolved by the {@link #getDestinationResolver() destination resolver}.
jms:SomeQueue* * @author Arjen Poutsma + * @see IRI Scheme for Java(tm) Message + * Service 1.0 * @since 1.1.0 */ -public class JmsMessageSender implements WebServiceMessageSender, JmsTransportConstants { +public class JmsMessageSender extends JmsDestinationAccessor implements WebServiceMessageSender { - /** - * Default timeout for receive operations: -1 indicates a blocking receive without timeout. - */ + /** Default timeout for receive operations: -1 indicates a blocking receive without timeout. */ public static final long DEFAULT_RECEIVE_TIMEOUT = -1; - private ConnectionFactory connectionFactory; - - private DestinationResolver destinationResolver = new DynamicDestinationResolver(); - private long receiveTimeout = DEFAULT_RECEIVE_TIMEOUT; public JmsMessageSender() { } - public JmsMessageSender(ConnectionFactory connectionFactory) { - this.connectionFactory = connectionFactory; - } - /** - * Set the ConnectionFactory to use for obtaining JMS {@link Connection}s. - */ - public void setConnectionFactory(ConnectionFactory connectionFactory) { - this.connectionFactory = connectionFactory; - } - - public void setDestinationResolver(DestinationResolver destinationResolver) { - this.destinationResolver = destinationResolver; - } - - /** - * Set the timeout to use for receive calls. The default is 0, which means no timeout. + * Set the timeout to use for receive calls. The default is -1, which means no timeout. + * + * @see MessageConsumer#receive(long) */ public void setReceiveTimeout(long receiveTimeout) { this.receiveTimeout = receiveTimeout; } - public WebServiceConnection createConnection(String uriString) throws IOException { - Assert.notNull(connectionFactory, "connectionFactory must not be null"); - JmsSenderConnection connection = null; + public WebServiceConnection createConnection(URI uri) throws IOException { + Connection jmsConnection = null; + Session jmsSession = null; try { - JmsUri uri = new JmsUri(uriString); - connection = new JmsSenderConnection(uri, connectionFactory, destinationResolver, receiveTimeout); - return connection; + jmsConnection = createConnection(); + jmsSession = createSession(jmsConnection); + Destination requestDestination = resolveRequestDestination(jmsSession, uri); + JmsSenderConnection wsConnection = + new JmsSenderConnection(getConnectionFactory(), jmsConnection, jmsSession, requestDestination); + wsConnection.setDeliveryMode(JmsTransportUtils.getDeliveryMode(uri)); + wsConnection.setPriority(JmsTransportUtils.getPriority(uri)); + wsConnection.setReceiveTimeout(receiveTimeout); + wsConnection.setResponseDestination(resolveResponseDestination(jmsSession, uri)); + wsConnection.setTimeToLive(JmsTransportUtils.getTimeToLive(uri)); + return wsConnection; } catch (JMSException ex) { - if (connection != null) { - connection.close(); - } + JmsUtils.closeSession(jmsSession); + ConnectionFactoryUtils.releaseConnection(jmsConnection, getConnectionFactory(), true); throw new JmsTransportException(ex); } } - public boolean supports(String uri) { - return StringUtils.hasLength(uri) && uri.startsWith(URI_SCHEME + ":"); + public boolean supports(URI uri) { + return uri.getScheme().equals(JmsTransportConstants.JMS_URI_SCHEME); } + private Destination resolveRequestDestination(Session session, URI uri) throws JMSException { + return resolveDestinationName(session, JmsTransportUtils.getDestinationName(uri)); + } + + private Destination resolveResponseDestination(Session session, URI uri) throws JMSException { + String destinationName = JmsTransportUtils.getReplyToName(uri); + return StringUtils.hasLength(destinationName) ? resolveDestinationName(session, destinationName) : null; + } + + } diff --git a/support/src/main/java/org/springframework/ws/transport/jms/JmsSenderConnection.java b/support/src/main/java/org/springframework/ws/transport/jms/JmsSenderConnection.java index 8e1d8827..5d04f8c7 100644 --- a/support/src/main/java/org/springframework/ws/transport/jms/JmsSenderConnection.java +++ b/support/src/main/java/org/springframework/ws/transport/jms/JmsSenderConnection.java @@ -36,7 +36,6 @@ import javax.jms.TemporaryQueue; import org.springframework.jms.connection.ConnectionFactoryUtils; import org.springframework.jms.support.JmsUtils; -import org.springframework.jms.support.destination.DestinationResolver; import org.springframework.util.Assert; import org.springframework.ws.FaultAwareWebServiceMessage; import org.springframework.ws.WebServiceMessage; @@ -56,58 +55,78 @@ public class JmsSenderConnection extends AbstractSenderConnection private final ConnectionFactory connectionFactory; - private final DestinationResolver destinationResolver; - private final Connection connection; private final Session session; private final Destination requestDestination; - private final JmsUri uri; - - private final long receiveTimeout; - private Destination responseDestination; private BytesMessage requestMessage; private BytesMessage responseMessage; - /** - * Constructs a new JMS connection with the given parameters. - */ - protected JmsSenderConnection(JmsUri uri, - ConnectionFactory connectionFactory, - DestinationResolver destinationResolver, - long receiveTimeout) throws JMSException { - Assert.notNull(uri, "'uri' must not be null"); + private long receiveTimeout; + + private int deliveryMode; + + private long timeToLive; + + private int priority; + + /** Constructs a new JMS connection with the given parameters. */ + protected JmsSenderConnection(ConnectionFactory connectionFactory, + Connection connection, + Session session, + Destination requestDestination) throws JMSException { Assert.notNull(connectionFactory, "'connectionFactory' must not be null"); - Assert.notNull(destinationResolver, "destinationResolver must not be null"); + Assert.notNull(connection, "'connection' must not be null"); + Assert.notNull(session, "'session' must not be null"); this.connectionFactory = connectionFactory; - this.destinationResolver = destinationResolver; - connection = connectionFactory.createConnection(); - session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - requestDestination = - destinationResolver.resolveDestinationName(session, uri.getDestination(), uri.isPubSubDomain()); - this.uri = uri; - this.receiveTimeout = receiveTimeout; + this.connection = connection; + this.session = session; + this.requestDestination = requestDestination; } - /** - * Returns the request message for this connection. - */ + /** Returns the request message for this connection. */ public BytesMessage getRequestMessage() { return requestMessage; } - /** - * Returns the response message, if any, for this connection. - */ + /** Returns the response message, if any, for this connection. */ public BytesMessage getResponseMessage() { return responseMessage; } + /* + * Package-friendly setters + */ + + void setResponseDestination(Destination responseDestination) { + this.responseDestination = responseDestination; + } + + void setTimeToLive(long timeToLive) { + this.timeToLive = timeToLive; + } + + void setDeliveryMode(int deliveryMode) { + this.deliveryMode = deliveryMode; + } + + void setPriority(int priority) { + this.priority = priority; + } + + void setReceiveTimeout(long receiveTimeout) { + this.receiveTimeout = receiveTimeout; + } + + /* + * Errors + */ + public boolean hasError() throws IOException { return false; } @@ -128,7 +147,7 @@ public class JmsSenderConnection extends AbstractSenderConnection FaultAwareWebServiceMessage faultMessage = (FaultAwareWebServiceMessage) message; requestMessage.setBooleanProperty(PROPERTY_IS_FAULT, faultMessage.hasFault()); } - requestMessage.setStringProperty(PROPERTY_REQUEST_IRI, uri.toString()); +// requestMessage.setStringProperty(PROPERTY_REQUEST_IRI, uri.toString()); } catch (JMSException ex) { throw new JmsTransportException(ex); @@ -153,14 +172,10 @@ public class JmsSenderConnection extends AbstractSenderConnection MessageProducer messageProducer = null; try { messageProducer = session.createProducer(requestDestination); - messageProducer.setDeliveryMode(uri.getDeliveryMode()); - messageProducer.setTimeToLive(uri.getTimeToLive()); - messageProducer.setPriority(uri.getPriority()); - if (uri.hasReplyTo()) { - responseDestination = - destinationResolver.resolveDestinationName(session, uri.getReplyTo(), uri.isPubSubDomain()); - } - else { + messageProducer.setDeliveryMode(deliveryMode); + messageProducer.setTimeToLive(timeToLive); + messageProducer.setPriority(priority); + if (responseDestination == null) { responseDestination = session.createTemporaryQueue(); } requestMessage.setJMSReplyTo(responseDestination); diff --git a/support/src/main/java/org/springframework/ws/transport/jms/JmsTransportConstants.java b/support/src/main/java/org/springframework/ws/transport/jms/JmsTransportConstants.java index 5ce69c9a..e0fb2e5d 100644 --- a/support/src/main/java/org/springframework/ws/transport/jms/JmsTransportConstants.java +++ b/support/src/main/java/org/springframework/ws/transport/jms/JmsTransportConstants.java @@ -26,7 +26,8 @@ import org.springframework.ws.transport.TransportConstants; */ public interface JmsTransportConstants extends TransportConstants { - String URI_SCHEME = "jms"; + /** The "jms" URI scheme" */ + String JMS_URI_SCHEME = "jms"; String PARAM_DELIVERY_MODE = "deliveryMode"; diff --git a/support/src/main/java/org/springframework/ws/transport/jms/JmsUri.java b/support/src/main/java/org/springframework/ws/transport/jms/JmsUri.java deleted file mode 100644 index bb967691..00000000 --- a/support/src/main/java/org/springframework/ws/transport/jms/JmsUri.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2007 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.ws.transport.jms; - -import javax.jms.DeliveryMode; -import javax.jms.Destination; -import javax.jms.Message; -import javax.jms.Queue; -import javax.jms.Topic; - -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.ws.transport.support.ParameterizedUri; - -/** - * @author Arjen Poutsma - * @see RI - * Scheme for Java Message Service 1.0 RC1 - */ -public class JmsUri extends ParameterizedUri implements JmsTransportConstants { - - public JmsUri(String uri) { - super(uri); - validateParameters(); - } - - private void validateParameters() { - validateIntegerParameter(PARAM_DELIVERY_MODE); - validateIntegerParameter(PARAM_PRIORITY); - validateIntegerParameter(PARAM_TIME_TO_LIVE); - String destinationType = getDestinationType(); - if (StringUtils.hasLength(destinationType)) { - Assert.isTrue( - DESTINATION_TYPE_QUEUE.equals(destinationType) || DESTINATION_TYPE_TOPIC.equals(destinationType), - "Invalid " + PARAM_DESTINATION_TYPE + ": [" + destinationType + "]. Expected '" + - DESTINATION_TYPE_QUEUE + "' or '" + DESTINATION_TYPE_TOPIC + "'"); - } - } - - private void validateIntegerParameter(String paramName) { - String paramValue = getParameter(paramName); - if (StringUtils.hasLength(paramValue)) { - try { - Integer.parseInt(paramValue); - } - catch (NumberFormatException ex) { - throw new IllegalArgumentException("Invalid " + paramName + ": [" + paramValue + "]. Not an integer."); - } - } - } - - /** - * Returns whether the request message is persistent or not. - * - * @see DeliveryMode#NON_PERSISTENT - * @see DeliveryMode#PERSISTENT - */ - public int getDeliveryMode() { - return getIntegerParameter(PARAM_DELIVERY_MODE, Message.DEFAULT_DELIVERY_MODE); - } - - public String getDestination() { - return super.getDestination(); - } - - /** - * Specifies whether the destination is a {@link Queue} or a {@link Topic}, with the value "
jms:SomeTopic?priority=3&deliveryMode=NON_PERSISTENT
+ * jms:RequestQueue?replyToName=ResponseName
queue" or
- * "topic", respectively.
- */
- public String getDestinationType() {
- return getParameter(PARAM_DESTINATION_TYPE);
- }
-
- /**
- * Returns the JMS priority associated with the request message.
- *
- * @see Message#setJMSPriority(int)
- */
- public int getPriority() {
- return getIntegerParameter(PARAM_PRIORITY, Message.DEFAULT_PRIORITY);
- }
-
- /**
- * Returns the lifetime, in milliseconds, of the request message.
- */
- public long getTimeToLive() {
- String paramValue = getParameter(PARAM_TIME_TO_LIVE);
- return paramValue != null ? Long.parseLong(paramValue) : Message.DEFAULT_TIME_TO_LIVE;
- }
-
- private int getIntegerParameter(String paramName, int defaultValue) {
- String paramValue = getParameter(paramName);
- return paramValue != null ? Integer.parseInt(paramValue) : defaultValue;
- }
-
- /**
- * Indicates whether this URI has a reply-to name.
- */
- public boolean hasReplyTo() {
- return StringUtils.hasLength(getReplyTo());
- }
-
- /**
- * Returns the reply-to name.
- *
- * @see Message#setJMSReplyTo(Destination)
- */
- public String getReplyTo() {
- return getParameter(PARAM_REPLY_TO_NAME);
- }
-
- /**
- * Return whether the Publish/Subscribe domain ({@link javax.jms.Topic Topics}) is used. Otherwise, the
- * Point-to-Point domain ({@link javax.jms.Queue Queues}) is used.
- */
- public boolean isPubSubDomain() {
- return DESTINATION_TYPE_TOPIC.equals(getDestinationType());
- }
-
-}
diff --git a/support/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageListener.java b/support/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageListener.java
index 4d94a213..2185aae5 100644
--- a/support/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageListener.java
+++ b/support/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageListener.java
@@ -27,7 +27,7 @@ import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.transport.WebServiceMessageReceiver;
/**
- * Spring-2.0 {@link SessionAwareMessageListener} that can be used to handle incoming JMS messages.
+ * Spring {@link SessionAwareMessageListener} that can be used to handle incoming JMS messages.
*
* Requires a {@link WebServiceMessageFactory} which is used to convert the incoming JMS {@link BytesMessage} into a
* {@link WebServiceMessage}, and passes that to the {@link WebServiceMessageReceiver} {@link
diff --git a/support/src/main/java/org/springframework/ws/transport/jms/support/JmsTransportUtils.java b/support/src/main/java/org/springframework/ws/transport/jms/support/JmsTransportUtils.java
index fa672f9f..b313cc74 100644
--- a/support/src/main/java/org/springframework/ws/transport/jms/support/JmsTransportUtils.java
+++ b/support/src/main/java/org/springframework/ws/transport/jms/support/JmsTransportUtils.java
@@ -16,6 +16,13 @@
package org.springframework.ws.transport.jms.support;
+import java.net.URI;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.jms.DeliveryMode;
+import javax.jms.Destination;
+import javax.jms.Message;
+
import org.springframework.ws.transport.jms.JmsTransportConstants;
/**
@@ -27,6 +34,16 @@ import org.springframework.ws.transport.jms.JmsTransportConstants;
*/
public class JmsTransportUtils {
+ private static final Pattern DESTINATION_NAME_PATTERN = Pattern.compile("^jms:(\\w+)\\&?");
+
+ private static final Pattern DELIVERY_MODE_PATTERN = Pattern.compile("deliveryMode=(PERSISTENT|NON_PERSISTENT)");
+
+ private static final Pattern TIME_TO_LIVE_PATTERN = Pattern.compile("timeToLive=(\\d+)");
+
+ private static final Pattern PRIORITY_PATTERN = Pattern.compile("priority=(\\d)");
+
+ private static final Pattern REPLY_TO_NAME_PATTERN = Pattern.compile("replyToName=(\\w+)");
+
private static final String[] CONVERSION_TABLE = new String[]{JmsTransportConstants.HEADER_CONTENT_TYPE,
JmsTransportConstants.PROPERTY_CONTENT_TYPE, JmsTransportConstants.HEADER_CONTENT_LENGTH,
JmsTransportConstants.PROPERTY_CONTENT_LENGTH, JmsTransportConstants.HEADER_SOAP_ACTION,
@@ -66,4 +83,89 @@ public class JmsTransportUtils {
return propertyName;
}
+ public static String getDestinationName(URI uri) {
+ return getStringParameter(DESTINATION_NAME_PATTERN, uri);
+ }
+
+ /**
+ * Returns the delivery mode of the given URI.
+ *
+ * @see DeliveryMode#NON_PERSISTENT
+ * @see DeliveryMode#PERSISTENT
+ * @see Message#DEFAULT_DELIVERY_MODE
+ */
+ public static int getDeliveryMode(URI uri) {
+ String deliveryMode = getStringParameter(DELIVERY_MODE_PATTERN, uri);
+ if ("NON_PERSISTENT".equals(deliveryMode)) {
+ return DeliveryMode.NON_PERSISTENT;
+ }
+ else if ("PERSISTENT".equals(deliveryMode)) {
+ return DeliveryMode.PERSISTENT;
+ }
+ else {
+ return Message.DEFAULT_DELIVERY_MODE;
+ }
+ }
+
+ /**
+ * Returns the lifetime, in milliseconds, of the given URI.
+ *
+ * @see Message#DEFAULT_TIME_TO_LIVE
+ */
+ public static long getTimeToLive(URI uri) {
+ return getLongParameter(TIME_TO_LIVE_PATTERN, uri, Message.DEFAULT_TIME_TO_LIVE);
+ }
+
+ /**
+ * Returns the priority of the given URI.
+ *
+ * @see Message#DEFAULT_PRIORITY
+ */
+ public static int getPriority(URI uri) {
+ return getIntParameter(PRIORITY_PATTERN, uri, Message.DEFAULT_PRIORITY);
+ }
+
+ /**
+ * Returns the reply-to name of the given URI.
+ *
+ * @see Message#setJMSReplyTo(Destination)
+ */
+ public static String getReplyToName(URI uri) {
+ return getStringParameter(REPLY_TO_NAME_PATTERN, uri);
+ }
+
+ private static String getStringParameter(Pattern pattern, URI uri) {
+ Matcher matcher = pattern.matcher(uri.toString());
+ if (matcher.find() && matcher.groupCount() == 1) {
+ return matcher.group(1);
+ }
+ return null;
+ }
+
+ private static int getIntParameter(Pattern pattern, URI uri, int defaultValue) {
+ Matcher matcher = pattern.matcher(uri.toString());
+ if (matcher.find() && matcher.groupCount() == 1) {
+ try {
+ return Integer.parseInt(matcher.group(1));
+ }
+ catch (NumberFormatException ex) {
+ // fall through to default value
+ }
+ }
+ return defaultValue;
+ }
+
+ private static long getLongParameter(Pattern pattern, URI uri, long defaultValue) {
+ Matcher matcher = pattern.matcher(uri.toString());
+ if (matcher.find() && matcher.groupCount() == 1) {
+ try {
+ return Long.parseLong(matcher.group(1));
+ }
+ catch (NumberFormatException ex) {
+ // fall through to default value
+ }
+ }
+ return defaultValue;
+ }
+
}
diff --git a/support/src/main/java/org/springframework/ws/transport/support/ParameterizedUri.java b/support/src/main/java/org/springframework/ws/transport/support/ParameterizedUri.java
deleted file mode 100644
index 58be7494..00000000
--- a/support/src/main/java/org/springframework/ws/transport/support/ParameterizedUri.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright 2007 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.ws.transport.support;
-
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import org.springframework.core.CollectionFactory;
-import org.springframework.util.Assert;
-
-/** @author Arjen Poutsma */
-public class ParameterizedUri {
-
- private final String uri;
-
- private final String scheme;
-
- // keys are string parameter names; values are string parameter values
- private final Map parameters = CollectionFactory.createLinkedCaseInsensitiveMapIfPossible(5);
-
- private final String destination;
-
- public ParameterizedUri(String uri) {
- Assert.hasLength(uri, "'uri' must not be empty");
- this.uri = uri;
- int scIdx = uri.indexOf(':');
- Assert.isTrue(scIdx != -1, uri + " does contain scheme");
- scheme = uri.substring(0, scIdx);
- Assert.isTrue(uri.length() > scheme.length(), uri + " does not have a destination");
- int paramStart = uri.indexOf('?');
- if (paramStart == -1) {
- destination = uri.substring(scIdx + 1);
- }
- else {
- destination = uri.substring(scIdx + 1, paramStart);
- parseParameters(uri.substring(paramStart + 1));
- }
- }
-
- private void parseParameters(String parametersString) {
- StringTokenizer params = new StringTokenizer(parametersString, "&");
- while (params.hasMoreTokens()) {
- String param = params.nextToken();
- int paramSep = param.indexOf('=');
- if (paramSep == -1) {
- throw new IllegalArgumentException(param + " is not a valid parameter: it has no '='");
- }
- String paramName = param.substring(0, paramSep);
- String paramValue = param.substring(paramSep + 1);
- parameters.put(paramName, paramValue);
- }
- }
-
- /** Returns the destination of the uri. */
- protected String getDestination() {
- return destination;
- }
-
- public String toString() {
- return uri;
- }
-
- protected String getParameter(String paramName) {
- return (String) parameters.get(paramName);
- }
-
- protected boolean hasParameter(String paramName) {
- return parameters.containsKey(paramName);
- }
-}
diff --git a/support/src/test/java/org/springframework/ws/transport/jms/EchoPayloadEndpoint.java b/support/src/test/java/org/springframework/ws/transport/jms/EchoPayloadEndpoint.java
new file mode 100644
index 00000000..874258c8
--- /dev/null
+++ b/support/src/test/java/org/springframework/ws/transport/jms/EchoPayloadEndpoint.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ws.transport.jms;
+
+import javax.xml.transform.Source;
+
+import org.springframework.ws.server.endpoint.PayloadEndpoint;
+
+public class EchoPayloadEndpoint implements PayloadEndpoint {
+
+ public Source invoke(Source request) throws Exception {
+ return request;
+ }
+}
diff --git a/support/src/test/java/org/springframework/ws/transport/jms/JmsIntegrationTest.java b/support/src/test/java/org/springframework/ws/transport/jms/JmsIntegrationTest.java
new file mode 100644
index 00000000..f5a0e7a0
--- /dev/null
+++ b/support/src/test/java/org/springframework/ws/transport/jms/JmsIntegrationTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2007 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.ws.transport.jms;
+
+import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
+import org.springframework.ws.client.core.WebServiceTemplate;
+import org.springframework.xml.transform.StringResult;
+import org.springframework.xml.transform.StringSource;
+
+import org.custommonkey.xmlunit.XMLAssert;
+
+public class JmsIntegrationTest extends AbstractDependencyInjectionSpringContextTests {
+
+ private WebServiceTemplate webServiceTemplate;
+
+ protected String[] getConfigLocations() {
+ return new String[]{"classpath:org/springframework/ws/transport/jms/jms-applicationContext.xml"};
+ }
+
+ public void setWebServiceTemplate(WebServiceTemplate webServiceTemplate) {
+ this.webServiceTemplate = webServiceTemplate;
+ }
+
+ public void testJmsTransport() throws Exception {
+ String content = "