diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsMessageSender.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsMessageSender.java index 02f7fbc4..bca36897 100644 --- a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsMessageSender.java +++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsMessageSender.java @@ -17,17 +17,18 @@ package org.springframework.ws.transport.jms; import java.io.IOException; +import java.util.Properties; import javax.jms.BytesMessage; +import javax.jms.ConnectionFactory; import javax.jms.JMSException; import javax.jms.Queue; -import javax.jms.QueueConnection; -import javax.jms.QueueConnectionFactory; -import javax.jms.QueueSession; -import javax.jms.Session; +import javax.naming.Context; +import javax.naming.NamingException; -import org.springframework.jms.support.destination.DestinationResolver; -import org.springframework.jms.support.destination.DynamicDestinationResolver; -import org.springframework.util.Assert; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.jndi.JndiTemplate; +import org.springframework.util.StringUtils; import org.springframework.ws.transport.WebServiceConnection; import org.springframework.ws.transport.WebServiceMessageSender; @@ -42,30 +43,27 @@ import org.springframework.ws.transport.WebServiceMessageSender; */ public class JmsMessageSender implements WebServiceMessageSender { - /** Default timeout for receive operations. */ - public static final long DEFAULT_RECEIVE_TIMEOUT = 0; + private static final Log logger = LogFactory.getLog(JmsMessageSender.class); - private QueueConnectionFactory connectionFactory; + /** Default timeout for receive operations: -1 indicates a blocking receive without timeout. */ + public static final long DEFAULT_RECEIVE_TIMEOUT = -1; - private Object queue; + private static final String JMS_SCHEME = "jms:"; - private DestinationResolver destinationResolver = new DynamicDestinationResolver(); + private ConnectionFactory defaultConnectionFactory; private long receiveTimeout = DEFAULT_RECEIVE_TIMEOUT; - /** Set the QueueConnectionFactory to use for obtaining JMS QueueConnections. */ - public void setConnectionFactory(QueueConnectionFactory connectionFactory) { - this.connectionFactory = connectionFactory; + public JmsMessageSender() { } - /** Set the target Queue to send invoker requests to. */ - public void setQueue(Queue queue) { - this.queue = queue; + public JmsMessageSender(ConnectionFactory defaultConnectionFactory) { + this.defaultConnectionFactory = defaultConnectionFactory; } - /** Set the name of target queue to send invoker requests to. */ - public void setQueueName(String queueName) { - queue = queueName; + /** Set the default ConnectionFactory to use for obtaining JMS Connections. */ + public void setDefaultConnectionFactory(ConnectionFactory defaultConnectionFactory) { + this.defaultConnectionFactory = defaultConnectionFactory; } /** Set the timeout to use for receive calls. The default is 0, which means no timeout. */ @@ -73,72 +71,51 @@ public class JmsMessageSender implements WebServiceMessageSender { this.receiveTimeout = receiveTimeout; } - /** - * Set the DestinationResolver that is to be used to resolve Queue references for this accessor.
The default
- * resolver is a DynamicDestinationResolver. Specify a JndiDestinationResolver for resolving destination names as
- * JNDI locations.
- *
- * @param destinationResolver the DestinationResolver that is to be used
- * @see org.springframework.jms.support.destination.DynamicDestinationResolver
- * @see org.springframework.jms.support.destination.JndiDestinationResolver
- */
- public void setDestinationResolver(DestinationResolver destinationResolver) {
- Assert.notNull(destinationResolver, "DestinationResolver must not be null");
- this.destinationResolver = destinationResolver;
- }
-
- public void afterPropertiesSet() {
- if (connectionFactory == null) {
- throw new IllegalArgumentException("connectionFactory is required");
- }
- if (queue == null) {
- throw new IllegalArgumentException("'queue' or 'queueName' is required");
- }
- }
-
- /**
- * Resolve this accessor's target queue.
- *
- * @param session the current JMS Session
- * @return the resolved target Queue
- * @throws JMSException if resolution failed
- */
- protected Queue resolveQueue(Session session) throws JMSException {
- if (queue instanceof Queue) {
- return (Queue) queue;
- }
- else if (queue instanceof String) {
- return resolveQueueName(session, (String) queue);
- }
- else {
- throw new javax.jms.IllegalStateException(
- "Queue object [" + queue + "] is neither a [javax.jms.Queue] nor a queue name String");
- }
- }
-
- /**
- * Resolve the given queue name into a JMS {@link javax.jms.Queue}, via this accessor's {@link
- * DestinationResolver}.
- *
- * @param session the current JMS Session
- * @param queueName the name of the queue
- * @return the located Queue
- * @throws JMSException if resolution failed
- * @see #setDestinationResolver
- */
- protected Queue resolveQueueName(Session session, String queueName) throws JMSException {
- return (Queue) destinationResolver.resolveDestinationName(session, queueName, false);
- }
-
- public WebServiceConnection createConnection() throws IOException {
+ public WebServiceConnection createConnection(String uriString) throws IOException {
+ JmsSenderConnection connection = null;
try {
- QueueConnection con = connectionFactory.createQueueConnection();
- QueueSession session = con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
- Queue queueToUse = resolveQueue(session);
- return new JmsSendingWebServiceConnection(con, session, queueToUse, receiveTimeout);
+ JmsUri uri = new JmsUri(uriString);
+ ConnectionFactory connectionFactory = resolveConnectionFactory(uri);
+ connection = new JmsSenderConnection(uri, connectionFactory, receiveTimeout);
+ return connection;
}
catch (JMSException ex) {
+ if (connection != null) {
+ connection.close();
+ }
throw new JmsTransportException(ex);
}
}
+
+ public boolean supports(String uri) {
+ return StringUtils.hasLength(uri) && uri.startsWith(JMS_SCHEME);
+ }
+
+ protected ConnectionFactory resolveConnectionFactory(JmsUri uri) {
+ if (uri.hasConnectionFactoryName()) {
+ Properties environment = new Properties();
+ if (uri.hasInitialContextFactory()) {
+ environment.setProperty(Context.INITIAL_CONTEXT_FACTORY, uri.getInitialContextFactory());
+ }
+ if (uri.hasJndiUrl()) {
+ environment.setProperty(Context.PROVIDER_URL, uri.getJndiUrl());
+ }
+ try {
+ JndiTemplate jndiTemplate = new JndiTemplate(environment);
+ return (ConnectionFactory) jndiTemplate.lookup(uri.getConnectionFactoryName(), ConnectionFactory.class);
+ }
+ catch (NamingException ex) {
+ logger.debug("ConnectionFactory [" + uri.getConnectionFactoryName() + "] not found in JNDI", ex);
+ // fall through to the default
+ }
+ }
+ if (defaultConnectionFactory != null) {
+ return defaultConnectionFactory;
+ }
+ else {
+ throw new IllegalStateException("Could not resolve JMS ConnectionFactory. " +
+ "Specify a 'defaultConnectionFactory' or 'connectionFactoryName' in the URI.");
+ }
+ }
+
}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsReceivingWebServiceConnection.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsReceiverConnection.java
similarity index 51%
rename from sandbox/src/main/java/org/springframework/ws/transport/jms/JmsReceivingWebServiceConnection.java
rename to sandbox/src/main/java/org/springframework/ws/transport/jms/JmsReceiverConnection.java
index 20ee524a..46a083ab 100644
--- a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsReceivingWebServiceConnection.java
+++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsReceiverConnection.java
@@ -19,21 +19,26 @@ package org.springframework.ws.transport.jms;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.Enumeration;
import java.util.Iterator;
+import java.util.List;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
+import org.apache.commons.logging.Log;
import org.springframework.jms.support.JmsUtils;
import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
-import org.springframework.ws.transport.AbstractReceivingWebServiceConnection;
-import org.springframework.ws.transport.support.EnumerationIterator;
+import org.springframework.ws.WebServiceMessage;
+import org.springframework.ws.transport.AbstractReceiverConnection;
/** @author Arjen Poutsma */
-public class JmsReceivingWebServiceConnection extends AbstractReceivingWebServiceConnection {
+public class JmsReceiverConnection extends AbstractReceiverConnection implements JmsTransportConstants {
+
+ private final Log logger;
private final BytesMessage requestMessage;
@@ -41,78 +46,41 @@ public class JmsReceivingWebServiceConnection extends AbstractReceivingWebServic
private BytesMessage responseMessage;
- public JmsReceivingWebServiceConnection(BytesMessage requestMessage, Session session) {
+ protected JmsReceiverConnection(BytesMessage requestMessage, Session session, Log logger) {
Assert.notNull(requestMessage, "requestMessage must not be null");
Assert.notNull(session, "session must not be null");
+ Assert.notNull(logger, "'logger' must not be null");
this.requestMessage = requestMessage;
this.session = session;
+ this.logger = logger;
+ }
+
+ public String getErrorMessage() throws IOException {
+ return null;
+ }
+
+ public boolean hasError() throws IOException {
+ return false;
}
public void close() throws IOException {
- try {
- session.close();
- }
- catch (JMSException ex) {
- throw new JmsTransportException("Could not close session", ex);
- }
}
- protected void sendResponse() throws IOException {
- if (responseMessage != null) {
- MessageProducer producer = null;
- try {
- if (requestMessage.getJMSReplyTo() != null) {
- producer = session.createProducer(requestMessage.getJMSReplyTo());
- producer.send(responseMessage);
- }
- else {
- logger.warn("Incoming message has no ReplyTo set, not sending response");
- }
- }
- catch (JMSException ex) {
- throw new JmsTransportException("Could not send response", ex);
- }
- finally {
- if (producer != null) {
- JmsUtils.closeMessageProducer(producer);
- }
- }
- }
- }
-
- private void createResponseMessage() throws IOException {
- if (responseMessage == null) {
- try {
- responseMessage = session.createBytesMessage();
- String correlationID = requestMessage.getJMSCorrelationID();
- if (StringUtils.hasLength(correlationID)) {
- responseMessage.setJMSCorrelationID(correlationID);
- }
- }
- catch (JMSException ex) {
- throw new JmsTransportException("Could not create response message", ex);
- }
- }
- }
-
- protected void addResponseHeader(String name, String value) throws IOException {
- try {
- createResponseMessage();
- responseMessage.setStringProperty(name, value);
- }
- catch (JMSException ex) {
- throw new JmsTransportException("Could not set property", ex);
- }
- }
-
- protected OutputStream getResponseOutputStream() throws IOException {
- createResponseMessage();
- return new BytesMessageOutputStream(responseMessage);
- }
+ /*
+ * Receiving
+ */
protected Iterator getRequestHeaderNames() throws IOException {
try {
- return new EnumerationIterator(requestMessage.getPropertyNames());
+ Enumeration headers = requestMessage.getPropertyNames();
+ List results = new ArrayList();
+ while (headers.hasMoreElements()) {
+ String header = (String) headers.nextElement();
+ if (header.startsWith(JmsTransportConstants.PROPERTY_PREFIX)) {
+ results.add(header);
+ }
+ }
+ return results.iterator();
}
catch (JMSException ex) {
throw new JmsTransportException("Could not get property names", ex);
@@ -132,4 +100,56 @@ public class JmsReceivingWebServiceConnection extends AbstractReceivingWebServic
protected InputStream getRequestInputStream() throws IOException {
return new BytesMessageInputStream(requestMessage);
}
+
+ /*
+ * Sending
+ */
+
+ protected void onSendBeforeWrite(WebServiceMessage message) throws IOException {
+ try {
+ responseMessage = session.createBytesMessage();
+ responseMessage.setJMSCorrelationID(requestMessage.getJMSMessageID());
+ responseMessage.setStringProperty(PROPERTY_BINDING_VERSION, "1.0");
+ responseMessage.setBooleanProperty(PROPERTY_IS_FAULT, message.hasFault());
+ }
+ catch (JMSException ex) {
+ throw new JmsTransportException("Could not create response message", ex);
+ }
+ }
+
+ protected void addResponseHeader(String name, String value) throws IOException {
+ try {
+ String property = JmsTransportUtils.headerToJmsProperty(name);
+ responseMessage.setStringProperty(property, value);
+ }
+ catch (JMSException ex) {
+ throw new JmsTransportException("Could not set property", ex);
+ }
+ }
+
+ protected OutputStream getResponseOutputStream() throws IOException {
+ return new BytesMessageOutputStream(responseMessage);
+ }
+
+ protected void onSendAfterWrite(WebServiceMessage message) throws IOException {
+ MessageProducer messageProducer = null;
+ try {
+ if (requestMessage.getJMSReplyTo() != null) {
+ messageProducer = session.createProducer(requestMessage.getJMSReplyTo());
+ messageProducer.setDeliveryMode(requestMessage.getJMSDeliveryMode());
+ messageProducer.setPriority(requestMessage.getJMSPriority());
+ messageProducer.send(responseMessage);
+ }
+ else {
+ logger.warn("Incoming message has no ReplyTo set, not sending response");
+ }
+ }
+ catch (JMSException ex) {
+ throw new JmsTransportException(ex);
+ }
+ finally {
+ JmsUtils.closeMessageProducer(messageProducer);
+ }
+ }
+
}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsSenderConnection.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsSenderConnection.java
new file mode 100644
index 00000000..d269c35e
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsSenderConnection.java
@@ -0,0 +1,244 @@
+/*
+ * 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 java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import javax.jms.BytesMessage;
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.TemporaryQueue;
+
+import org.springframework.jms.connection.ConnectionFactoryUtils;
+import org.springframework.jms.support.JmsUtils;
+import org.springframework.util.Assert;
+import org.springframework.ws.WebServiceMessage;
+import org.springframework.ws.transport.AbstractSenderConnection;
+import org.springframework.ws.transport.FaultAwareWebServiceConnection;
+
+/** @author Arjen Poutsma */
+public class JmsSenderConnection extends AbstractSenderConnection
+ implements FaultAwareWebServiceConnection, JmsTransportConstants {
+
+ private final ConnectionFactory connectionFactory;
+
+ private final Connection connection;
+
+ private final Session session;
+
+ private final Destination requestDestination;
+
+ private Destination responseDestination;
+
+ private final JmsUri uri;
+
+ private BytesMessage requestMessage;
+
+ private BytesMessage responseMessage;
+
+ private long receiveTimeout;
+
+ protected JmsSenderConnection(JmsUri uri, ConnectionFactory connectionFactory, long receiveTimeout)
+ throws JMSException {
+ Assert.notNull(uri, "'uri' must not be null");
+ Assert.notNull(connectionFactory, "'connectionFactory' must not be null");
+ this.connectionFactory = connectionFactory;
+ connection = connectionFactory.createConnection();
+ session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ if (uri.isPubSubDomain()) {
+ requestDestination = session.createTopic(uri.getDestination());
+ }
+ else {
+ requestDestination = session.createQueue(uri.getDestination());
+ }
+ this.uri = uri;
+ this.receiveTimeout = receiveTimeout;
+ }
+
+ public BytesMessage getRequestMessage() {
+ return requestMessage;
+ }
+
+ public BytesMessage getResponseMessage() {
+ return responseMessage;
+ }
+
+ /*
+ * Sending
+ */
+
+ protected void onSendBeforeWrite(WebServiceMessage message) throws IOException {
+ try {
+ requestMessage = session.createBytesMessage();
+ requestMessage.setStringProperty(PROPERTY_BINDING_VERSION, "1.0");
+ requestMessage.setBooleanProperty(PROPERTY_IS_FAULT, message.hasFault());
+ requestMessage.setStringProperty(PROPERTY_REQUEST_IRI, uri.getUri());
+ }
+ catch (JMSException ex) {
+ throw new JmsTransportException(ex);
+ }
+ }
+
+ protected void addRequestHeader(String name, String value) throws IOException {
+ try {
+ String property = JmsTransportUtils.headerToJmsProperty(name);
+ requestMessage.setStringProperty(property, value);
+ }
+ catch (JMSException ex) {
+ throw new JmsTransportException("Could not set property", ex);
+ }
+ }
+
+ protected OutputStream getRequestOutputStream() throws IOException {
+ return new BytesMessageOutputStream(requestMessage);
+ }
+
+ protected void onSendAfterWrite(WebServiceMessage message) throws IOException {
+ MessageProducer messageProducer = null;
+ try {
+ messageProducer = session.createProducer(requestDestination);
+ messageProducer.setDeliveryMode(uri.getDeliveryMode());
+ messageProducer.setTimeToLive(uri.getTimeToLive());
+ messageProducer.setPriority(uri.getPriority());
+ if (uri.hasReplyTo()) {
+ if (uri.isPubSubDomain()) {
+ responseDestination = session.createTopic(uri.getReplyTo());
+ }
+ else {
+ responseDestination = session.createQueue(uri.getReplyTo());
+ }
+
+ }
+ else {
+ responseDestination = session.createTemporaryQueue();
+ }
+ requestMessage.setJMSReplyTo(responseDestination);
+ connection.start();
+ messageProducer.send(requestMessage);
+ }
+ catch (JMSException ex) {
+ throw new JmsTransportException(ex);
+ }
+ finally {
+ JmsUtils.closeMessageProducer(messageProducer);
+ }
+ }
+
+ /*
+ * Receiving
+ */
+
+ protected void onReceiveBeforeRead() throws IOException {
+ MessageConsumer messageConsumer = null;
+ try {
+ messageConsumer = session.createConsumer(responseDestination);
+ responseMessage = (BytesMessage) (receiveTimeout >= 0 ? messageConsumer.receive(receiveTimeout) :
+ messageConsumer.receive());
+ }
+ catch (JMSException ex) {
+ throw new JmsTransportException(ex);
+ }
+ finally {
+ JmsUtils.closeMessageConsumer(messageConsumer);
+ if (responseDestination instanceof TemporaryQueue) {
+ try {
+ ((TemporaryQueue) responseDestination).delete();
+ }
+ catch (JMSException e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ protected Iterator getResponseHeaderNames() throws IOException {
+ try {
+ List headerNames = new ArrayList();
+ Enumeration propertyNames = responseMessage.getPropertyNames();
+ while (propertyNames.hasMoreElements()) {
+ String propertyName = (String) propertyNames.nextElement();
+ headerNames.add(JmsTransportUtils.jmsPropertyToHeader(propertyName));
+ }
+ return headerNames.iterator();
+ }
+ catch (JMSException ex) {
+ throw new JmsTransportException("Could not get property names", ex);
+ }
+ }
+
+ protected Iterator getResponseHeaders(String name) throws IOException {
+ try {
+ String propertyName = JmsTransportUtils.headerToJmsProperty(name);
+ String value = responseMessage.getStringProperty(propertyName);
+ if (value != null) {
+ return Collections.singletonList(value).iterator();
+ }
+ else {
+ return Collections.EMPTY_LIST.iterator();
+ }
+ }
+ catch (JMSException ex) {
+ throw new JmsTransportException("Could not get property value", ex);
+ }
+ }
+
+ protected InputStream getResponseInputStream() throws IOException {
+ return new BytesMessageInputStream(responseMessage);
+ }
+
+ public void close() throws IOException {
+ JmsUtils.closeSession(session);
+ ConnectionFactoryUtils.releaseConnection(connection, connectionFactory, true);
+ }
+
+ protected boolean hasResponse() throws IOException {
+ return responseMessage != null;
+ }
+
+ public boolean hasFault() throws IOException {
+ if (responseMessage != null) {
+ try {
+ return responseMessage.getBooleanProperty(JmsTransportConstants.PROPERTY_IS_FAULT);
+ }
+ catch (JMSException ex) {
+ throw new JmsTransportException(ex);
+ }
+ }
+ else {
+ return false;
+ }
+ }
+
+ public boolean hasError() throws IOException {
+ return false;
+ }
+
+ public String getErrorMessage() throws IOException {
+ return null;
+ }
+}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsSendingWebServiceConnection.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsSendingWebServiceConnection.java
deleted file mode 100644
index f90eb4ab..00000000
--- a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsSendingWebServiceConnection.java
+++ /dev/null
@@ -1,179 +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 java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Collections;
-import java.util.Iterator;
-import javax.jms.BytesMessage;
-import javax.jms.JMSException;
-import javax.jms.Queue;
-import javax.jms.QueueConnection;
-import javax.jms.QueueReceiver;
-import javax.jms.QueueSender;
-import javax.jms.QueueSession;
-import javax.jms.TemporaryQueue;
-
-import org.springframework.util.Assert;
-import org.springframework.ws.transport.AbstractSendingWebServiceConnection;
-import org.springframework.ws.transport.support.EnumerationIterator;
-
-/** @author Arjen Poutsma */
-public class JmsSendingWebServiceConnection extends AbstractSendingWebServiceConnection {
-
- private final BytesMessage requestMessage;
-
- private BytesMessage responseMessage;
-
- private final QueueSession session;
-
- private TemporaryQueue responseQueue = null;
-
- private QueueConnection connection;
-
- private long receiveTimeout;
-
- private Queue queue;
-
- public JmsSendingWebServiceConnection(QueueConnection connection,
- QueueSession session,
- Queue queue,
- long receiveTimeout) throws JMSException {
- Assert.notNull(connection, "connection must not be null");
- Assert.notNull(session, "session must not be null");
- Assert.notNull(queue, "queue must not be null");
- this.connection = connection;
- this.session = session;
- this.queue = queue;
- this.receiveTimeout = receiveTimeout;
- requestMessage = session.createBytesMessage();
- }
-
- public void close() throws IOException {
- try {
- session.close();
- }
- catch (JMSException ex) {
- throw new JmsTransportException("Could not close session", ex);
- }
- try {
- connection.close();
- }
- catch (JMSException ex) {
- throw new JmsTransportException("Could not close connection", ex);
- }
- }
-
- protected void addRequestHeader(String name, String value) throws IOException {
- try {
- requestMessage.setStringProperty(name, value);
- }
- catch (JMSException ex) {
- throw new JmsTransportException("Could not set property", ex);
- }
- }
-
- protected OutputStream getRequestOutputStream() throws IOException {
- return new BytesMessageOutputStream(requestMessage);
- }
-
- protected void sendRequest() throws IOException {
- QueueSender sender = null;
- try {
- sender = session.createSender(queue);
- responseQueue = session.createTemporaryQueue();
- requestMessage.setJMSReplyTo(responseQueue);
- connection.start();
- sender.send(requestMessage);
- }
- catch (JMSException ex) {
- throw new JmsTransportException("Could not send request message", ex);
- }
- finally {
- try {
- if (sender != null) {
- sender.close();
- }
- }
- catch (JMSException ex) {
- throw new JmsTransportException("Could not close QueueSender", ex);
- }
- }
- }
-
- protected boolean hasResponse() throws IOException {
- if (responseMessage != null) {
- return true;
- }
- else if (responseQueue != null) {
- QueueReceiver receiver = null;
- try {
- receiver = session.createReceiver(responseQueue);
- responseMessage = (BytesMessage) receiver.receive(receiveTimeout);
- return responseMessage != null;
- }
- catch (JMSException ex) {
- throw new JmsTransportException("Could not receive message", ex);
- }
- finally {
- try {
- if (receiver != null) {
- receiver.close();
- }
- }
- catch (JMSException ex) {
- throw new JmsTransportException("Could not close QueueReceiver", ex);
- }
- try {
- responseQueue.delete();
- responseQueue = null;
- }
- catch (JMSException ex) {
- throw new JmsTransportException("Could not delete temporary response queue", ex);
- }
- }
- }
- else {
- return false;
- }
- }
-
- protected Iterator getResponseHeaderNames() throws IOException {
- try {
- return new EnumerationIterator(responseMessage.getPropertyNames());
- }
- catch (JMSException ex) {
- throw new JmsTransportException("Could not get property names", ex);
- }
- }
-
- protected Iterator getResponseHeaders(String name) throws IOException {
- try {
- String value = responseMessage.getStringProperty(name);
- return Collections.singletonList(value).iterator();
- }
- catch (JMSException ex) {
- throw new JmsTransportException("Could not get property value", ex);
- }
- }
-
- protected InputStream getResponseInputStream() throws IOException {
- return new BytesMessageInputStream(responseMessage);
- }
-}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportConstants.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportConstants.java
new file mode 100644
index 00000000..9d8d024b
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportConstants.java
@@ -0,0 +1,63 @@
+/*
+ * 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.ws.transport.TransportConstants;
+
+/** @author Arjen Poutsma */
+public interface JmsTransportConstants extends TransportConstants {
+
+ String URI_SCHEME = "jms";
+
+ String PARAM_DELIVERY_MODE = "deliveryMode";
+
+ String PARAM_CONNECTION_FACTORY_NAME = "connectionFactoryName";
+
+ String PARAM_INITIAL_CONTEXT_FACTORY = "initialContextFactory";
+
+ String PARAM_JNDI_URL = "jndiURL";
+
+ String PARAM_TIME_TO_LIVE = "timeToLive";
+
+ String PARAM_PRIORITY = "priority";
+
+ String PARAM_DESTINATION_TYPE = "destinationType";
+
+ String PARAM_REPLY_TO_NAME = "replyToName";
+
+ String DESTINATION_TYPE_QUEUE = "queue";
+
+ String DESTINATION_TYPE_TOPIC = "topic";
+
+ String PROPERTY_PREFIX = "SOAPJMS_";
+
+ String PROPERTY_IS_FAULT = PROPERTY_PREFIX + "isFault";
+
+ String PROPERTY_SOAP_ACTION = PROPERTY_PREFIX + "soapAction";
+
+ String PROPERTY_CONTENT_LENGTH = PROPERTY_PREFIX + "contentLength";
+
+ String PROPERTY_CONTENT_TYPE = PROPERTY_PREFIX + "contentType";
+
+ String PROPERTY_BINDING_VERSION = PROPERTY_PREFIX + "bindingVersion";
+
+ String PROPERTY_TARGET_SERVICE = PROPERTY_PREFIX + "targetService";
+
+ String PROPERTY_REQUEST_IRI = PROPERTY_PREFIX + "requestIRI";
+
+ String PROPERTY_SOAP_MEP = PROPERTY_PREFIX + "soapMEP";
+}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportException.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportException.java
index 95ab4e3f..1c8839c9 100644
--- a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportException.java
+++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportException.java
@@ -20,20 +20,22 @@ import javax.jms.JMSException;
import org.springframework.ws.transport.TransportException;
-/**
- * @author Arjen Poutsma
- */
+/** @author Arjen Poutsma */
public class JmsTransportException extends TransportException {
- public JmsTransportException(String msg) {
- super(msg);
- }
+ private final JMSException jmsException;
public JmsTransportException(String msg, JMSException ex) {
super(msg + ": " + ex.getMessage());
+ jmsException = ex;
}
public JmsTransportException(JMSException ex) {
super(ex.getMessage());
+ jmsException = ex;
+ }
+
+ public JMSException getJmsException() {
+ return jmsException;
}
}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportUtils.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportUtils.java
new file mode 100644
index 00000000..6eec7c4b
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportUtils.java
@@ -0,0 +1,49 @@
+/*
+ * 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;
+
+/** @author Arjen Poutsma */
+public class JmsTransportUtils {
+
+ 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,
+ JmsTransportConstants.PROPERTY_SOAP_ACTION};
+
+ private JmsTransportUtils() {
+
+ }
+
+ public static String headerToJmsProperty(String headerName) {
+ for (int i = 0; i < CONVERSION_TABLE.length; i = i + 2) {
+ if (CONVERSION_TABLE[i].equals(headerName)) {
+ return CONVERSION_TABLE[i + 1];
+ }
+ }
+ return headerName;
+ }
+
+ public static String jmsPropertyToHeader(String propertyName) {
+ for (int i = 1; i < CONVERSION_TABLE.length; i = i + 2) {
+ if (CONVERSION_TABLE[i].equals(propertyName)) {
+ return CONVERSION_TABLE[i - 1];
+ }
+ }
+ return propertyName;
+ }
+
+}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsUri.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsUri.java
new file mode 100644
index 00000000..7df5ec1e
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsUri.java
@@ -0,0 +1,210 @@
+/*
+ * 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 java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+import javax.jms.DeliveryMode;
+import javax.jms.Destination;
+import javax.jms.Message;
+import javax.jms.Queue;
+import javax.jms.Topic;
+import javax.naming.Context;
+
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+/**
+ * @author Arjen Poutsma
+ * @see RI
+ * Scheme for Java Message Service 1.0 RC1
+ */
+public class JmsUri implements JmsTransportConstants {
+
+ private final String uri;
+
+ private final String destination;
+
+ // keys are string parameter names; values are string parameter values
+ private final Map parameters = new HashMap();
+
+ public JmsUri(String uri) {
+ Assert.hasLength(uri, "'uri' must not be empty");
+ String scheme = URI_SCHEME + ":";
+ Assert.isTrue(uri.startsWith(scheme), uri + " does not start with " + scheme);
+ Assert.isTrue(uri.length() > scheme.length(), uri + " does not have a destination");
+ int paramStart = uri.indexOf('?');
+ if (paramStart == -1) {
+ destination = uri.substring(scheme.length());
+ }
+ else {
+ destination = uri.substring(scheme.length(), paramStart);
+ parseParameters(uri.substring(paramStart + 1));
+ }
+ this.uri = uri;
+ }
+
+ 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);
+ }
+ validateParameters();
+ }
+
+ private void validateParameters() {
+ validateIntegerParameter(PARAM_DELIVERY_MODE);
+ validateIntegerParameter(PARAM_PRIORITY);
+ validateIntegerParameter(PARAM_TIME_TO_LIVE);
+ String destinationType = getDestinationType();
+ 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 = (String) parameters.get(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);
+ }
+
+ /** Returns thethe JNDI name of the destination queue or topic. */
+ public String getDestination() {
+ return destination;
+ }
+
+ /**
+ * Specifies whether the destination is a {@link Queue} or a {@link Topic}, with the value "queue" or
+ * "topic", respectively.
+ */
+ public String getDestinationType() {
+ return (String) parameters.get(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 int getTimeToLive() {
+ return getIntegerParameter(PARAM_TIME_TO_LIVE, (int) Message.DEFAULT_TIME_TO_LIVE);
+ }
+
+ private int getIntegerParameter(String paramName, int defaultValue) {
+ String paramValue = (String) parameters.get(paramName);
+ return paramValue != null ? Integer.parseInt(paramValue) : defaultValue;
+ }
+
+ /** Returns the full JMS URI. */
+ public String getUri() {
+ return uri;
+ }
+
+ /** Indicates whether this URI has a connection factory name. */
+ public boolean hasConnectionFactoryName() {
+ return StringUtils.hasLength(getConnectionFactoryName());
+ }
+
+ /** Returns the JNDI name of the Java class providing the connection factory. */
+ public String getConnectionFactoryName() {
+ return (String) parameters.get(PARAM_CONNECTION_FACTORY_NAME);
+ }
+
+ /** Indicates whether this URI has a "InitialContextFactory". */
+ public boolean hasInitialContextFactory() {
+ return StringUtils.hasLength(getInitialContextFactory());
+ }
+
+ /**
+ * Returns the fully qualified Java class name of the "InitialContextFactory" implementation class to use.
+ *
+ * @see Context#INITIAL_CONTEXT_FACTORY
+ */
+ public String getInitialContextFactory() {
+ return (String) parameters.get(PARAM_INITIAL_CONTEXT_FACTORY);
+ }
+
+ /** Indicates whether this URI has a JNDI provider URL. */
+ public boolean hasJndiUrl() {
+ return StringUtils.hasLength(getJndiUrl());
+ }
+
+ /**
+ * Returns the JNDI provider URL.
+ *
+ * @see Context#PROVIDER_URL
+ */
+ public String getJndiUrl() {
+ return (String) parameters.get(PARAM_JNDI_URL);
+ }
+
+ /** 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 (String) parameters.get(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());
+ }
+
+ /** Returns the value of a custom parameter with the given name. */
+ public String getCustomParameter(String paramName) {
+ return (String) parameters.get(paramName);
+ }
+}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsWebServiceMessageReceiverObjectSupport.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsWebServiceMessageReceiverObjectSupport.java
index 14c98bad..f50573ca 100644
--- a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsWebServiceMessageReceiverObjectSupport.java
+++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsWebServiceMessageReceiverObjectSupport.java
@@ -44,7 +44,7 @@ public abstract class JmsWebServiceMessageReceiverObjectSupport extends SimpleWe
*/
protected final void handleMessage(Message request, Session session) throws Exception {
if (request instanceof BytesMessage) {
- WebServiceConnection connection = new JmsReceivingWebServiceConnection((BytesMessage) request, session);
+ WebServiceConnection connection = new JmsReceiverConnection((BytesMessage) request, session, logger);
handleConnection(connection, getMessageReceiver());
}
else {
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageReceiverMessageListener.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageListener.java
similarity index 92%
rename from sandbox/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageReceiverMessageListener.java
rename to sandbox/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageListener.java
index 77c39fea..5b3a874d 100644
--- a/sandbox/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageReceiverMessageListener.java
+++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/WebServiceMessageListener.java
@@ -37,13 +37,16 @@ import org.springframework.ws.transport.WebServiceMessageReceiver;
* @see #setMessageFactory(org.springframework.ws.WebServiceMessageFactory)
* @see #setMessageReceiver(org.springframework.ws.transport.WebServiceMessageReceiver)
*/
-public class WebServiceMessageReceiverMessageListener extends JmsWebServiceMessageReceiverObjectSupport
+public class WebServiceMessageListener extends JmsWebServiceMessageReceiverObjectSupport
implements SessionAwareMessageListener {
public void onMessage(Message message, Session session) throws JMSException {
try {
handleMessage(message, session);
}
+ catch (JmsTransportException ex) {
+ throw ex.getJmsException();
+ }
catch (Exception ex) {
JMSException jmsException = new JMSException(ex.getMessage());
jmsException.setLinkedException(ex);
diff --git a/sandbox/src/main/resources/org/springframework/ws/transport/jms/applicationContext-ws-jms.xml b/sandbox/src/main/resources/org/springframework/ws/transport/jms/applicationContext-ws-jms.xml
index 26f8f54b..8daf7253 100644
--- a/sandbox/src/main/resources/org/springframework/ws/transport/jms/applicationContext-ws-jms.xml
+++ b/sandbox/src/main/resources/org/springframework/ws/transport/jms/applicationContext-ws-jms.xml
@@ -28,7 +28,7 @@