diff --git a/sandbox/pom.xml b/sandbox/pom.xml
index 8977b19b..05f0af25 100644
--- a/sandbox/pom.xml
+++ b/sandbox/pom.xml
@@ -1,4 +1,5 @@
-topic", respectively.
*/
public String getDestinationType() {
- return (String) parameters.get(PARAM_DESTINATION_TYPE);
+ return getParameter(PARAM_DESTINATION_TYPE);
}
/**
@@ -134,15 +101,10 @@ public class JmsUri implements JmsTransportConstants {
}
private int getIntegerParameter(String paramName, int defaultValue) {
- String paramValue = (String) parameters.get(paramName);
+ String paramValue = getParameter(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());
@@ -150,7 +112,7 @@ public class JmsUri implements JmsTransportConstants {
/** Returns the JNDI name of the Java class providing the connection factory. */
public String getConnectionFactoryName() {
- return (String) parameters.get(PARAM_CONNECTION_FACTORY_NAME);
+ return getParameter(PARAM_CONNECTION_FACTORY_NAME);
}
/** Indicates whether this URI has a "InitialContextFactory". */
@@ -164,7 +126,7 @@ public class JmsUri implements JmsTransportConstants {
* @see Context#INITIAL_CONTEXT_FACTORY
*/
public String getInitialContextFactory() {
- return (String) parameters.get(PARAM_INITIAL_CONTEXT_FACTORY);
+ return getParameter(PARAM_INITIAL_CONTEXT_FACTORY);
}
/** Indicates whether this URI has a JNDI provider URL. */
@@ -178,7 +140,7 @@ public class JmsUri implements JmsTransportConstants {
* @see Context#PROVIDER_URL
*/
public String getJndiUrl() {
- return (String) parameters.get(PARAM_JNDI_URL);
+ return getParameter(PARAM_JNDI_URL);
}
/** Indicates whether this URI has a reply-to name. */
@@ -192,7 +154,7 @@ public class JmsUri implements JmsTransportConstants {
* @see Message#setJMSReplyTo(Destination)
*/
public String getReplyTo() {
- return (String) parameters.get(PARAM_REPLY_TO_NAME);
+ return getParameter(PARAM_REPLY_TO_NAME);
}
/**
@@ -203,8 +165,4 @@ public class JmsUri implements JmsTransportConstants {
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/JmsTransportUtils.java b/sandbox/src/main/java/org/springframework/ws/transport/jms/support/JmsTransportUtils.java
similarity index 93%
rename from sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportUtils.java
rename to sandbox/src/main/java/org/springframework/ws/transport/jms/support/JmsTransportUtils.java
index 6eec7c4b..872a1fdb 100644
--- a/sandbox/src/main/java/org/springframework/ws/transport/jms/JmsTransportUtils.java
+++ b/sandbox/src/main/java/org/springframework/ws/transport/jms/support/JmsTransportUtils.java
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-package org.springframework.ws.transport.jms;
+package org.springframework.ws.transport.jms.support;
+
+import org.springframework.ws.transport.jms.JmsTransportConstants;
/** @author Arjen Poutsma */
public class JmsTransportUtils {
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailMessageReceiver.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailMessageReceiver.java
new file mode 100644
index 00000000..967808d3
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailMessageReceiver.java
@@ -0,0 +1,188 @@
+/*
+ * 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.mail;
+
+import java.util.Properties;
+import javax.mail.Folder;
+import javax.mail.FolderClosedException;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.URLName;
+import javax.mail.event.MessageCountEvent;
+import javax.mail.event.MessageCountListener;
+
+import com.sun.mail.imap.IMAPFolder;
+import org.springframework.util.Assert;
+import org.springframework.ws.transport.mail.support.MailUtils;
+import org.springframework.ws.transport.support.AbstractMultiThreadedMessageReceiver;
+
+/** @author Arjen Poutsma */
+public class MailMessageReceiver extends AbstractMultiThreadedMessageReceiver {
+
+ private Session session = Session.getInstance(new Properties(), null);
+
+ private URLName storeUri;
+
+ private Folder folder;
+
+ private MessageCountHandler eventHandler;
+
+ private Store store;
+
+ private boolean supportsIdle;
+
+ /**
+ * Set JavaMail properties for the {@link Session}.
+ *
Session, possibly pulled from JNDI.
+ *
+ * Default is a new Session without defaults, that is completely configured via this instance's
+ * properties.
+ *
+ * If using a pre-configured Session, non-default properties in this instance will override the
+ * settings in the Session.
+ *
+ * @see #setJavaMailProperties
+ */
+ public void setSession(Session session) {
+ Assert.notNull(session, "Session must not be null");
+ this.session = session;
+ }
+
+ public void setStoreUri(String storeUri) {
+ this.storeUri = new URLName(storeUri);
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ super.afterPropertiesSet();
+ Assert.notNull(storeUri, "Property 'storeUri' is required");
+ }
+
+ protected void onActivate() throws Exception {
+ openFolder();
+ }
+
+ protected void onStart() {
+ if (logger.isInfoEnabled()) {
+ logger.info("Starting mail receiver [" + storeUri.toString() + "]");
+ }
+ eventHandler = new MessageCountHandler();
+ folder.addMessageCountListener(eventHandler);
+/*
+ try {
+ if (folder instanceof IMAPFolder) {
+ IMAPFolder f = (IMAPFolder) folder;
+ logger.debug(folder.isOpen());
+ logger.debug("Starting IDLE");
+ f.idle();
+ logger.debug("IDLE done");
+ supportsIdle = true;
+ }
+ }
+ catch (MessagingException mex) {
+ supportsIdle = false;
+ }
+*/
+ logger.debug("Support IDLE: " + supportsIdle);
+ getTaskExecutor().execute(new MonitoringRunnable());
+ }
+
+ protected void onStop() {
+ if (logger.isInfoEnabled()) {
+ logger.info("Stopping mail receiver [" + storeUri.toString() + "]");
+ }
+ if (eventHandler != null) {
+ folder.removeMessageCountListener(eventHandler);
+ eventHandler = null;
+ }
+ }
+
+ protected void onShutdown() {
+ if (logger.isInfoEnabled()) {
+ logger.info("Shutting down mail receiver [" + storeUri.toString() + "]");
+ }
+ closeFolder();
+ }
+
+ protected void openFolder() throws MessagingException, MailTransportException {
+ store = session.getStore(storeUri);
+ store.connect();
+ folder = store.getFolder(storeUri);
+ if (folder == null || !folder.exists()) {
+ throw new MailTransportException("No default folder to receive from");
+ }
+ folder.open(Folder.READ_WRITE);
+ logger.info("folder contains " + folder.getMessageCount() + " messages");
+ }
+
+ protected void closeFolder() {
+ MailUtils.closeFolder(folder);
+ MailUtils.closeService(store);
+ }
+
+ private class MonitoringRunnable implements Runnable {
+
+ public void run() {
+ try {
+ while (isRunning()) {
+ if (supportsIdle && folder instanceof IMAPFolder) {
+ IMAPFolder f = (IMAPFolder) folder;
+ logger.debug("IDLE starts");
+ f.idle();
+ logger.debug("IDLE done");
+ }
+ else {
+ Thread.sleep(500); // sleep for freq milliseconds
+
+ // This is to force the IMAP server to send us
+ // EXISTS notifications.
+ folder.getMessageCount();
+ }
+ }
+ }
+ catch (InterruptedException ex) {
+ logger.warn(ex);
+ }
+ catch (MessagingException ex) {
+ logger.warn(ex);
+ }
+ }
+ }
+
+ private class MessageCountHandler implements MessageCountListener {
+
+ public void messagesAdded(MessageCountEvent event) {
+ Message[] msgs = event.getMessages();
+ logger.info("Got " + msgs.length + " new messages");
+ }
+
+ public void messagesRemoved(MessageCountEvent e) {
+ }
+ }
+}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailMessageSender.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailMessageSender.java
new file mode 100644
index 00000000..60370455
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailMessageSender.java
@@ -0,0 +1,102 @@
+/*
+ * 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.mail;
+
+import java.io.IOException;
+import java.util.Properties;
+import javax.mail.Session;
+import javax.mail.URLName;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.AddressException;
+
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+import org.springframework.ws.transport.WebServiceConnection;
+import org.springframework.ws.transport.WebServiceMessageSender;
+import org.springframework.beans.factory.InitializingBean;
+
+/** @author Arjen Poutsma */
+public class MailMessageSender implements WebServiceMessageSender, InitializingBean {
+
+ private Session session = Session.getInstance(new Properties(), null);
+
+ private URLName storeUri;
+
+ private URLName transportUri;
+
+ private InternetAddress from;
+
+ public void setFrom(String from) throws AddressException {
+ this.from = new InternetAddress(from);
+ }
+
+ /**
+ * Set JavaMail properties for the {@link Session}.
+ *
+ * A new {@link Session} will be created with those properties. Use either this method or {@link #setSession}, but
+ * not both.
+ *
+ * Non-default properties in this instance will override given JavaMail properties.
+ */
+ public void setJavaMailProperties(Properties javaMailProperties) {
+ session = Session.getInstance(javaMailProperties, null);
+ }
+
+ /**
+ * Set the JavaMail Session, possibly pulled from JNDI.
+ *
+ * Default is a new Session without defaults, that is completely configured via this instance's
+ * properties.
+ *
+ * If using a pre-configured Session, non-default properties in this instance will override the
+ * settings in the Session.
+ *
+ * @see #setJavaMailProperties
+ */
+ public void setSession(Session session) {
+ Assert.notNull(session, "Session must not be null");
+ this.session = session;
+ }
+
+ public void setStoreUri(String storeUri) {
+ this.storeUri = new URLName(storeUri);
+ }
+
+ public void setTransportUri(String transportUri) {
+ this.transportUri = new URLName(transportUri);
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ Assert.notNull(from, "Property 'from' is required");
+ }
+
+ public WebServiceConnection createConnection(String uri) throws IOException {
+ MailtoUri mailtoUri = new MailtoUri(uri);
+ MailSenderConnection connection = new MailSenderConnection(mailtoUri, session, from);
+ if (transportUri != null) {
+ connection.setTransportUri(transportUri);
+ }
+ if (storeUri != null) {
+ connection.setStoreUri(storeUri);
+ }
+ return connection;
+ }
+
+ public boolean supports(String uri) {
+ return StringUtils.hasLength(uri) && uri.startsWith(MailtoUri.MAILTO_SCHEME);
+ }
+}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailReceiverConnection.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailReceiverConnection.java
new file mode 100644
index 00000000..80962942
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailReceiverConnection.java
@@ -0,0 +1,198 @@
+/*
+ * 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.mail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import javax.mail.Header;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.URLName;
+import javax.mail.internet.MimeMessage;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+
+import org.springframework.util.Assert;
+import org.springframework.ws.transport.AbstractReceiverConnection;
+import org.springframework.ws.transport.TransportConstants;
+import org.springframework.ws.transport.mail.support.MailUtils;
+import org.springframework.ws.transport.jms.JmsTransportException;
+import org.springframework.ws.WebServiceMessage;
+
+/** @author Arjen Poutsma */
+public class MailReceiverConnection extends AbstractReceiverConnection {
+
+ private final MimeMessage requestMessage;
+
+ private final Session session;
+
+ private MimeMessage responseMessage;
+
+ private ByteArrayOutputStream responseBuffer;
+
+ private String responseContentType;
+
+ private URLName transportUri;
+
+ public MailReceiverConnection(MimeMessage requestMessage, Session session) {
+ Assert.notNull(requestMessage, "'requestMessage' must not be null");
+ Assert.notNull(session, "'session' must not be null");
+ this.requestMessage = requestMessage;
+ this.session = session;
+ }
+
+ public String getErrorMessage() throws IOException {
+ return null;
+ }
+
+ public boolean hasError() throws IOException {
+ return false;
+ }
+
+ public void setTransportUri(URLName transportUri) {
+ this.transportUri = transportUri;
+ }
+
+ public void close() throws IOException {
+ }
+
+ /*
+ * Receiving
+ */
+
+ protected Iterator getRequestHeaderNames() throws IOException {
+ try {
+ List headers = new ArrayList();
+ Enumeration enumeration = requestMessage.getAllHeaders();
+ while (enumeration.hasMoreElements()) {
+ Header header = (Header) enumeration.nextElement();
+ headers.add(header.getName());
+ }
+ return headers.iterator();
+ }
+ catch (MessagingException ex) {
+ throw new IOException(ex.getMessage());
+ }
+ }
+
+ protected Iterator getRequestHeaders(String name) throws IOException {
+ try {
+ String[] headers = requestMessage.getHeader(name);
+ return Arrays.asList(headers).iterator();
+ }
+ catch (MessagingException ex) {
+ throw new MailTransportException(ex);
+ }
+ }
+
+ protected InputStream getRequestInputStream() throws IOException {
+ try {
+ return requestMessage.getDataHandler().getInputStream();
+ }
+ catch (MessagingException ex) {
+ throw new MailTransportException(ex);
+ }
+ }
+
+ protected void addResponseHeader(String name, String value) throws IOException {
+ try {
+ responseMessage.addHeader(name, value);
+ if (TransportConstants.HEADER_CONTENT_TYPE.equals(name)) {
+ responseContentType = value;
+ }
+ }
+ catch (MessagingException ex) {
+ throw new MailTransportException(ex);
+ }
+ }
+
+ protected OutputStream getResponseOutputStream() throws IOException {
+ return responseBuffer;
+ }
+
+ /*
+ * Sending
+ */
+
+ protected void onSendBeforeWrite(WebServiceMessage message) throws IOException {
+ try {
+ responseMessage = (MimeMessage) requestMessage.reply(false);
+
+ responseBuffer = new ByteArrayOutputStream();
+ }
+ catch (MessagingException ex) {
+ throw new MailTransportException(ex);
+ }
+ }
+
+ protected void onSendAfterWrite(WebServiceMessage message) throws IOException {
+ Transport transport = null;
+ try {
+ requestMessage.setDataHandler(
+ new DataHandler(new ByteArrayDataSource(responseContentType, responseBuffer.toByteArray())));
+ transport = session.getTransport(transportUri);
+ transport.connect();
+ requestMessage.saveChanges();
+ transport.sendMessage(requestMessage, requestMessage.getAllRecipients());
+ }
+ catch (MessagingException ex) {
+ throw new MailTransportException(ex);
+ }
+ finally {
+ MailUtils.closeService(transport);
+ }
+ }
+
+ private class ByteArrayDataSource implements DataSource {
+
+ private byte[] data;
+
+ private String contentType;
+
+ public ByteArrayDataSource(String contentType, byte[] data) {
+ this.data = data;
+ this.contentType = contentType;
+ }
+
+ public String getContentType() {
+ return contentType;
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return new ByteArrayInputStream(data);
+ }
+
+ public String getName() {
+ return "ByteArrayDataSource";
+ }
+
+ public OutputStream getOutputStream() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailSenderConnection.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailSenderConnection.java
new file mode 100644
index 00000000..bda7c7b8
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailSenderConnection.java
@@ -0,0 +1,282 @@
+/*
+ * 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.mail;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import javax.activation.DataHandler;
+import javax.activation.DataSource;
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.Header;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.Transport;
+import javax.mail.URLName;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.mail.search.HeaderTerm;
+import javax.mail.search.SearchTerm;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.util.Assert;
+import org.springframework.ws.WebServiceMessage;
+import org.springframework.ws.transport.AbstractSenderConnection;
+import org.springframework.ws.transport.TransportConstants;
+import org.springframework.ws.transport.mail.support.MailUtils;
+
+/** @author Arjen Poutsma */
+public class MailSenderConnection extends AbstractSenderConnection {
+
+ private static final Log logger = LogFactory.getLog(MailSenderConnection.class);
+
+ private final Session session;
+
+ private final MailtoUri uri;
+
+ private MimeMessage requestMessage;
+
+ private MimeMessage responseMessage;
+
+ private String requestContentType;
+
+ private boolean deleteAfterReceive = false;
+
+ private URLName storeUri;
+
+ private URLName transportUri;
+
+ private ByteArrayOutputStream requestBuffer;
+
+ private InternetAddress from;
+
+ protected MailSenderConnection(MailtoUri uri, Session session, InternetAddress from) {
+ Assert.notNull(uri, "'uri' must not be null");
+ Assert.notNull(session, "'session' must not be null");
+ this.uri = uri;
+ this.session = session;
+ this.from = from;
+ }
+
+ public MimeMessage getRequestMessage() {
+ return requestMessage;
+ }
+
+ public void setTransportUri(URLName transportUri) {
+ this.transportUri = transportUri;
+ }
+
+ public void setStoreUri(URLName storeUri) {
+ this.storeUri = storeUri;
+ }
+
+ /*
+ * Sending
+ */
+
+ protected void onSendBeforeWrite(WebServiceMessage message) throws IOException {
+ try {
+ requestMessage = new MimeMessage(session);
+ requestMessage.setFrom(from);
+ requestMessage.setRecipient(Message.RecipientType.TO, uri.getTo());
+ if (uri.hasCc()) {
+ requestMessage.setRecipient(Message.RecipientType.CC, uri.getCc());
+ }
+ if (uri.hasSubject()) {
+ requestMessage.setSubject(uri.getSubject());
+ }
+ requestMessage.setSentDate(new Date());
+
+ requestBuffer = new ByteArrayOutputStream();
+ }
+ catch (MessagingException ex) {
+ throw new MailTransportException(ex);
+ }
+ }
+
+ protected void addRequestHeader(String name, String value) throws IOException {
+ try {
+ requestMessage.addHeader(name, value);
+ if (TransportConstants.HEADER_CONTENT_TYPE.equals(name)) {
+ requestContentType = value;
+ }
+ }
+ catch (MessagingException ex) {
+ throw new MailTransportException(ex);
+ }
+ }
+
+ protected OutputStream getRequestOutputStream() throws IOException {
+ return requestBuffer;
+ }
+
+ protected void onSendAfterWrite(WebServiceMessage message) throws IOException {
+ Transport transport = null;
+ try {
+ requestMessage.setDataHandler(
+ new DataHandler(new ByteArrayDataSource(requestContentType, requestBuffer.toByteArray())));
+ transport = session.getTransport(transportUri);
+ transport.connect();
+ requestMessage.saveChanges();
+ transport.sendMessage(requestMessage, requestMessage.getAllRecipients());
+ }
+ catch (MessagingException ex) {
+ throw new MailTransportException(ex);
+ }
+ finally {
+ MailUtils.closeService(transport);
+ }
+ }
+
+ /*
+ * Receiving
+ */
+
+ protected void onReceiveBeforeRead() throws IOException {
+ Store store = null;
+ Folder folder = null;
+ try {
+ try {
+ Thread.sleep(5000);
+ }
+ catch (InterruptedException e) {
+ logger.debug(e);
+ }
+ store = session.getStore(storeUri);
+ store.connect();
+ folder = store.getFolder(storeUri);
+ if (folder == null || !folder.exists()) {
+ throw new MailTransportException("No default folder to receive from");
+ }
+ if (deleteAfterReceive) {
+ folder.open(Folder.READ_WRITE);
+ }
+ else {
+ folder.open(Folder.READ_ONLY);
+ }
+ String requestMessageId = requestMessage.getMessageID();
+ SearchTerm searchTerm = new HeaderTerm(MailTransportConstants.HEADER_IN_REPLY_TO, requestMessageId);
+ Message[] responses = folder.search(searchTerm);
+ if (responses.length > 0) {
+ if (responses.length > 1) {
+ logger.warn("Received more than one response for request with ID [" + requestMessageId + "]");
+ }
+ responseMessage = (MimeMessage) responses[0];
+ }
+ if (deleteAfterReceive) {
+ responseMessage.setFlag(Flags.Flag.DELETED, true);
+ }
+ }
+ catch (MessagingException ex) {
+ throw new MailTransportException(ex);
+ }
+ finally {
+ MailUtils.closeFolder(folder, deleteAfterReceive);
+ MailUtils.closeService(store);
+ }
+ }
+
+ protected boolean hasResponse() throws IOException {
+ return responseMessage != null;
+ }
+
+ protected Iterator getResponseHeaderNames() throws IOException {
+ try {
+ List headers = new ArrayList();
+ Enumeration enumeration = responseMessage.getAllHeaders();
+ while (enumeration.hasMoreElements()) {
+ Header header = (Header) enumeration.nextElement();
+ headers.add(header.getName());
+ }
+ return headers.iterator();
+ }
+ catch (MessagingException ex) {
+ throw new MailTransportException(ex);
+ }
+ }
+
+ protected Iterator getResponseHeaders(String name) throws IOException {
+ try {
+ String[] headers = responseMessage.getHeader(name);
+ return Arrays.asList(headers).iterator();
+ }
+ catch (MessagingException ex) {
+ throw new MailTransportException(ex);
+
+ }
+ }
+
+ protected InputStream getResponseInputStream() throws IOException {
+ try {
+ return responseMessage.getDataHandler().getInputStream();
+ }
+ catch (MessagingException ex) {
+ throw new MailTransportException(ex);
+ }
+ }
+
+ public boolean hasError() throws IOException {
+ return false;
+ }
+
+ public String getErrorMessage() throws IOException {
+ return null;
+ }
+
+ public void close() throws IOException {
+ }
+
+ private class ByteArrayDataSource implements DataSource {
+
+ private byte[] data;
+
+ private String contentType;
+
+ public ByteArrayDataSource(String contentType, byte[] data) {
+ this.data = data;
+ this.contentType = contentType;
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return new ByteArrayInputStream(data);
+ }
+
+ public OutputStream getOutputStream() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getContentType() {
+ return contentType;
+ }
+
+ public String getName() {
+ return "ByteArrayDataSource";
+ }
+ }
+}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportConstants.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportConstants.java
new file mode 100644
index 00000000..144f26eb
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportConstants.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.mail;
+
+import org.springframework.ws.transport.TransportConstants;
+
+/** @author Arjen Poutsma */
+public interface MailTransportConstants extends TransportConstants {
+
+ /** The "In-Reply-To" header. */
+ String HEADER_IN_REPLY_TO = "In-Reply-To";
+
+
+}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportException.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportException.java
index 412455ec..c047fde1 100644
--- a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportException.java
+++ b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportException.java
@@ -24,15 +24,23 @@ import org.springframework.ws.transport.TransportException;
/** @author Arjen Poutsma */
public class MailTransportException extends TransportException {
+ private MessagingException messagingException;
+
public MailTransportException(String msg) {
super(msg);
}
- public MailTransportException(String msg, JMSException ex) {
+ public MailTransportException(String msg, MessagingException ex) {
super(msg + ": " + ex.getMessage());
+ initCause(ex);
}
public MailTransportException(MessagingException ex) {
super(ex.getMessage());
+ initCause(ex);
+ }
+
+ public MessagingException getMessagingException() {
+ return messagingException;
}
}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailtoUri.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailtoUri.java
new file mode 100644
index 00000000..baad6985
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailtoUri.java
@@ -0,0 +1,61 @@
+/*
+ * 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.mail;
+
+import javax.mail.internet.AddressException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.Address;
+
+import org.springframework.util.Assert;
+import org.springframework.ws.transport.support.ParameterizedUri;
+
+/** @author Arjen Poutsma */
+public class MailtoUri extends ParameterizedUri {
+
+ static final String MAILTO_SCHEME = "mailto:";
+
+ public MailtoUri(String uri) {
+ super(uri);
+ Assert.isTrue(uri.startsWith(MAILTO_SCHEME), "Invalid uri: " + uri);
+ try {
+ InternetAddress.parse(getDestination(), false);
+ }
+ catch (AddressException ex) {
+ throw new IllegalArgumentException(ex);
+ }
+ }
+
+ public InternetAddress getTo() throws AddressException {
+ return new InternetAddress(getDestination());
+ }
+
+ public String getSubject() {
+ return getParameter("subject");
+ }
+
+ public boolean hasSubject() {
+ return hasParameter("subject");
+ }
+
+ public boolean hasCc() {
+ return hasParameter("cc");
+ }
+
+ public InternetAddress getCc() throws AddressException {
+ return new InternetAddress(getParameter("cc"));
+ }
+}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/MonitoringStrategy.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/MonitoringStrategy.java
new file mode 100644
index 00000000..2222abbf
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/transport/mail/MonitoringStrategy.java
@@ -0,0 +1,22 @@
+/*
+ * 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.mail;
+
+/** @author Arjen Poutsma */
+public interface MonitoringStrategy {
+
+}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/support/MailUtils.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/support/MailUtils.java
new file mode 100644
index 00000000..0314883a
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/transport/mail/support/MailUtils.java
@@ -0,0 +1,82 @@
+/*
+ * 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.mail.support;
+
+import javax.mail.Folder;
+import javax.mail.MessagingException;
+import javax.mail.Service;
+import javax.mail.Store;
+import javax.mail.Transport;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/** @author Arjen Poutsma */
+public abstract class MailUtils {
+
+ private static final Log logger = LogFactory.getLog(MailUtils.class);
+
+ /**
+ * Close the given JavaMail Service and ignore any thrown exception. This is useful for typical finally
+ * blocks in manual JavaMail code.
+ *
+ * @param service the JavaMail Service to close (may be null)
+ * @see Transport
+ * @see Store
+ */
+ public static void closeService(Service service) {
+ if (service != null) {
+ try {
+ service.close();
+ }
+ catch (MessagingException ex) {
+ logger.debug("Could not close JavaMail Transport", ex);
+ }
+ }
+ }
+
+ /**
+ * Close the given JavaMail Folder and ignore any thrown exception. This is useful for typical finally
+ * blocks in manual JavaMail code.
+ *
+ * @param folder the JavaMail Folder to close (may be null)
+ */
+
+ public static void closeFolder(Folder folder) {
+ closeFolder(folder, false);
+ }
+
+ /**
+ * Close the given JavaMail Folder and ignore any thrown exception. This is useful for typical finally
+ * blocks in manual JavaMail code.
+ *
+ * @param folder the JavaMail Folder to close (may be null)
+ * @param expunge whether all deleted messages should be expunged from the folder
+ */
+ public static void closeFolder(Folder folder, boolean expunge) {
+ if (folder != null) {
+ try {
+ folder.close(expunge);
+ }
+ catch (MessagingException ex) {
+ logger.debug("Could not close JavaMail Transport", ex);
+ }
+ }
+ }
+
+
+}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/support/AbstractMultiThreadedMessageReceiver.java b/sandbox/src/main/java/org/springframework/ws/transport/support/AbstractMultiThreadedMessageReceiver.java
new file mode 100644
index 00000000..517fe756
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/transport/support/AbstractMultiThreadedMessageReceiver.java
@@ -0,0 +1,80 @@
+/*
+ * 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 org.springframework.beans.factory.BeanNameAware;
+import org.springframework.core.task.SimpleAsyncTaskExecutor;
+import org.springframework.core.task.TaskExecutor;
+import org.springframework.util.ClassUtils;
+import org.springframework.scheduling.commonj.WorkManagerTaskExecutor;
+
+/**
+ * Abstract base class for standalone, server-side transport objects. Contains a Spring {@link TaskExecutor}, and
+ * various lifecycle callbacks.
+ *
+ * @author Arjen Poutsma
+ */
+public abstract class AbstractMultiThreadedMessageReceiver extends AbstractStandaloneMessagingReceiver
+ implements BeanNameAware {
+
+ /** Default thread name prefix. */
+ public final String DEFAULT_THREAD_NAME_PREFIX = ClassUtils.getShortName(getClass()) + "-";
+
+ private TaskExecutor taskExecutor;
+
+ private String beanName;
+
+ /** Returns the task executor. */
+ public TaskExecutor getTaskExecutor() {
+ return taskExecutor;
+ }
+
+ /**
+ * Set the Spring {@link TaskExecutor} to use for running the listener threads. Default is {@link
+ * SimpleAsyncTaskExecutor}, starting up a number of new threads.
+ *
+ * Specify an alternative task executor for integration with an existing thread pool, such as the {@link
+ * WorkManagerTaskExecutor} to integrate with WebSphere or WebLogic.
+ */
+ public void setTaskExecutor(TaskExecutor taskExecutor) {
+ this.taskExecutor = taskExecutor;
+ }
+
+ public void setBeanName(String beanName) {
+ this.beanName = beanName;
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ if (taskExecutor == null) {
+ taskExecutor = createDefaultTaskExecutor();
+ }
+ super.afterPropertiesSet();
+ }
+
+ /**
+ * Create a default TaskExecutor. Called if no explicit TaskExecutor has been specified.
+ *
+ * The default implementation builds a {@link org.springframework.core.task.SimpleAsyncTaskExecutor} with the
+ * specified bean name (or the class name, if no bean name specified) as thread name prefix.
+ *
+ * @see org.springframework.core.task.SimpleAsyncTaskExecutor#SimpleAsyncTaskExecutor(String)
+ */
+ protected TaskExecutor createDefaultTaskExecutor() {
+ String threadNamePrefix = beanName != null ? beanName + "-" : DEFAULT_THREAD_NAME_PREFIX;
+ return new SimpleAsyncTaskExecutor(threadNamePrefix);
+ }
+}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/support/AbstractMessagingContainer.java b/sandbox/src/main/java/org/springframework/ws/transport/support/AbstractStandaloneMessagingReceiver.java
similarity index 58%
rename from sandbox/src/main/java/org/springframework/ws/transport/support/AbstractMessagingContainer.java
rename to sandbox/src/main/java/org/springframework/ws/transport/support/AbstractStandaloneMessagingReceiver.java
index 557131f6..fb3676f9 100644
--- a/sandbox/src/main/java/org/springframework/ws/transport/support/AbstractMessagingContainer.java
+++ b/sandbox/src/main/java/org/springframework/ws/transport/support/AbstractStandaloneMessagingReceiver.java
@@ -16,24 +16,12 @@
package org.springframework.ws.transport.support;
-import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.Lifecycle;
-import org.springframework.core.task.SimpleAsyncTaskExecutor;
-import org.springframework.core.task.TaskExecutor;
-import org.springframework.util.ClassUtils;
-/**
- * Abstract base class for standalone, server-side transport objects. Contains a Spring {@link TaskExecutor}, and
- * various lifecycle callbacks.
- *
- * @author Arjen Poutsma
- */
-public abstract class AbstractMessagingContainer extends SimpleWebServiceMessageReceiverObjectSupport
- implements Lifecycle, DisposableBean, BeanNameAware {
-
- /** Default thread name prefix. */
- public final String DEFAULT_THREAD_NAME_PREFIX = ClassUtils.getShortName(getClass()) + "-";
+/** @author Arjen Poutsma */
+public abstract class AbstractStandaloneMessagingReceiver extends SimpleWebServiceMessageReceiverObjectSupport
+ implements Lifecycle, DisposableBean {
private volatile boolean active = false;
@@ -43,39 +31,6 @@ public abstract class AbstractMessagingContainer extends SimpleWebServiceMessage
private final Object lifecycleMonitor = new Object();
- private TaskExecutor taskExecutor;
-
- private String beanName;
-
- /**
- * Set whether to automatically start the listener after initialization.
- *
- * Default is true; set this to false to allow for manual startup.
- */
- public void setAutoStartup(boolean autoStartup) {
- this.autoStartup = autoStartup;
- }
-
- /**
- * Set the Spring {@link TaskExecutor} to use for running the listener threads. Default is {@link
- * SimpleAsyncTaskExecutor}, starting up a number of new threads.
- *
- * Specify an alternative task executor for integration with an existing thread pool, such as the {@link
- * org.springframework.scheduling.commonj.WorkManagerTaskExecutor} to integrate with WebSphere or WebLogic.
- */
- public void setTaskExecutor(TaskExecutor taskExecutor) {
- this.taskExecutor = taskExecutor;
- }
-
- /** Returns the task executor. */
- public TaskExecutor getTaskExecutor() {
- return taskExecutor;
- }
-
- public void setBeanName(String beanName) {
- this.beanName = beanName;
- }
-
/** Return whether this server is currently active, that is, whether it has been set up but not shut down yet. */
public final boolean isActive() {
synchronized (lifecycleMonitor) {
@@ -91,23 +46,15 @@ public abstract class AbstractMessagingContainer extends SimpleWebServiceMessage
}
/**
- * Create a default TaskExecutor. Called if no explicit TaskExecutor has been specified.
+ * Set whether to automatically start the listener after initialization.
*
- * The default implementation builds a {@link org.springframework.core.task.SimpleAsyncTaskExecutor} with the
- * specified bean name (or the class name, if no bean name specified) as thread name prefix.
- *
- * @see org.springframework.core.task.SimpleAsyncTaskExecutor#SimpleAsyncTaskExecutor(String)
+ * Default is true; set this to false to allow for manual startup.
*/
- protected TaskExecutor createDefaultTaskExecutor() {
- String threadNamePrefix = beanName != null ? beanName + "-" : DEFAULT_THREAD_NAME_PREFIX;
- return new SimpleAsyncTaskExecutor(threadNamePrefix);
+ public void setAutoStartup(boolean autoStartup) {
+ this.autoStartup = autoStartup;
}
public void afterPropertiesSet() throws Exception {
- super.afterPropertiesSet();
- if (taskExecutor == null) {
- taskExecutor = createDefaultTaskExecutor();
- }
activate();
}
@@ -167,5 +114,4 @@ public abstract class AbstractMessagingContainer extends SimpleWebServiceMessage
protected abstract void onStop();
protected abstract void onShutdown();
-
}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/support/ParameterizedUri.java b/sandbox/src/main/java/org/springframework/ws/transport/support/ParameterizedUri.java
new file mode 100644
index 00000000..58be7494
--- /dev/null
+++ b/sandbox/src/main/java/org/springframework/ws/transport/support/ParameterizedUri.java
@@ -0,0 +1,84 @@
+/*
+ * 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/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessagingContainer.java b/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessageReceiver.java
similarity index 70%
rename from sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessagingContainer.java
rename to sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessageReceiver.java
index 9f05db5d..886ecb7d 100644
--- a/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessagingContainer.java
+++ b/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessageReceiver.java
@@ -24,10 +24,11 @@ import java.net.Socket;
import java.net.UnknownHostException;
import org.springframework.ws.transport.WebServiceConnection;
-import org.springframework.ws.transport.support.AbstractMessagingContainer;
+import org.springframework.ws.transport.support.AbstractMultiThreadedMessageReceiver;
/** @author Arjen Poutsma */
-public class TcpMessagingContainer extends AbstractMessagingContainer {
+public class TcpMessageReceiver extends AbstractMultiThreadedMessageReceiver {
+ public static final int DEFAULT_PORT = 8081;
private ServerSocket serverSocket;
@@ -35,7 +36,7 @@ public class TcpMessagingContainer extends AbstractMessagingContainer {
private int backlog = -1;
- private int port = -1;
+ private int port = DEFAULT_PORT;
/** Sets the port the server will bind to. */
public void setPort(int port) {
@@ -58,58 +59,34 @@ public class TcpMessagingContainer extends AbstractMessagingContainer {
this.bindAddress = InetAddress.getByName(bindAddress);
}
- public void afterPropertiesSet() throws Exception {
- super.afterPropertiesSet();
- if (port == -1) {
- throw new IllegalArgumentException("port is required");
- }
- openServerSocket();
- }
-
protected void onActivate() throws IOException {
openServerSocket();
}
protected void onStart() {
if (logger.isInfoEnabled()) {
- logger.info("Starting tcp server [" + serverSocket.getLocalSocketAddress() + "]");
+ logger.info("Starting tcp receiver [" + serverSocket.getLocalSocketAddress() + "]");
}
getTaskExecutor().execute(new SocketAcceptingRunnable());
}
protected void onStop() {
if (logger.isInfoEnabled()) {
- logger.info("Stopping tcp server [" + serverSocket.getLocalSocketAddress() + "]");
+ logger.info("Stopping tcp receiver [" + serverSocket.getLocalSocketAddress() + "]");
}
}
protected void onShutdown() {
if (logger.isInfoEnabled()) {
- logger.info("Shutting down tcp server [" + serverSocket.getLocalSocketAddress() + "]");
+ logger.info("Shutting down tcp receiver [" + serverSocket.getLocalSocketAddress() + "]");
}
closeServerSocket();
}
/**
- * Establish a shared ServerSocket for this server.
- *
- * The default implementation delegates to refreshSharedConnection, which does one immediate attempt
- * and throws an exception if it fails. Can be overridden to have a recovery proces in place, retrying until a
- * ServerSocket can be successfully established.
- *
- * @see #refreshServerSocket()
+ * Establish a ServerSocket for this receiver.
*/
protected void openServerSocket() throws IOException {
- refreshServerSocket();
- }
-
- /**
- * Refresh the shared ServerSocket that this server holds.
- *
- * Called on startup and also after an infrastructure exception that occured during listener setup and/or
- * execution.
- */
- protected final void refreshServerSocket() throws IOException {
closeServerSocket();
serverSocket = new ServerSocket(port, backlog, bindAddress);
}
@@ -154,7 +131,7 @@ public class TcpMessagingContainer extends AbstractMessagingContainer {
}
public void run() {
- WebServiceConnection connection = new TcpReceivingWebServiceConnection(socket);
+ WebServiceConnection connection = new TcpReceiverConnection(socket);
try {
handleConnection(connection);
}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessageSender.java b/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessageSender.java
index 637dc5a2..9be37a0b 100644
--- a/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessageSender.java
+++ b/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpMessageSender.java
@@ -17,57 +17,49 @@
package org.springframework.ws.transport.tcp;
import java.io.IOException;
-import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
-import java.net.UnknownHostException;
-import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
import org.springframework.ws.transport.WebServiceConnection;
import org.springframework.ws.transport.WebServiceMessageSender;
/** @author Arjen Poutsma */
-public class TcpMessageSender implements WebServiceMessageSender, InitializingBean {
+public class TcpMessageSender implements WebServiceMessageSender {
- private InetAddress address;
+ private static final String TCP_SCHEME = "tcp://";
- private int port = -1;
+ public static final int DEFAULT_PORT = 8081;
private int timeOut = 1000;
- /** Sets the port the sender will connect to. */
- public void setPort(int port) {
- this.port = port;
- }
-
/** Sets the amount of milliseconds before the tcp connection will timeout. */
public void setTimeOut(int timeOut) {
this.timeOut = timeOut;
}
- /**
- * Sets the internet address the client will connect to.
- *
- * @throws java.net.UnknownHostException when the given address is not known
- */
- public void setAddress(String address) throws UnknownHostException {
- this.address = InetAddress.getByName(address);
+ public boolean supports(String uri) {
+ return StringUtils.hasLength(uri) && uri.startsWith(TCP_SCHEME);
}
- public WebServiceConnection createConnection() throws IOException {
- Socket socket = new Socket();
- SocketAddress socketAddress = new InetSocketAddress(address, port);
- socket.connect(socketAddress, timeOut);
- return new TcpSendingWebServiceConnection(socket);
- }
-
- public void afterPropertiesSet() throws Exception {
- if (port == -1) {
- throw new IllegalArgumentException("port is required");
+ public WebServiceConnection createConnection(String uri) throws IOException {
+ Assert.isTrue(uri.startsWith(TCP_SCHEME), "Invalid uri: " + uri);
+ uri = uri.substring(TCP_SCHEME.length());
+ int idx = uri.indexOf(':');
+ String hostname;
+ int port;
+ if (idx != -1) {
+ hostname = uri.substring(0, idx);
+ port = Integer.parseInt(uri.substring(idx + 1));
+ } else {
+ hostname = uri;
+ port = DEFAULT_PORT;
}
- Assert.notNull(address, "address is required");
-
+ Socket socket = new Socket();
+ SocketAddress socketAddress = new InetSocketAddress(hostname, port);
+ socket.connect(socketAddress, timeOut);
+ return new TcpSenderConnection(socket);
}
}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpReceivingWebServiceConnection.java b/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpReceiverConnection.java
similarity index 83%
rename from sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpReceivingWebServiceConnection.java
rename to sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpReceiverConnection.java
index b57babe7..e864a663 100644
--- a/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpReceivingWebServiceConnection.java
+++ b/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpReceiverConnection.java
@@ -26,18 +26,26 @@ import java.util.Collections;
import java.util.Iterator;
import org.springframework.util.Assert;
-import org.springframework.ws.transport.AbstractReceivingWebServiceConnection;
+import org.springframework.ws.transport.AbstractReceiverConnection;
/** @author Arjen Poutsma */
-public class TcpReceivingWebServiceConnection extends AbstractReceivingWebServiceConnection {
+public class TcpReceiverConnection extends AbstractReceiverConnection {
private final Socket socket;
- public TcpReceivingWebServiceConnection(Socket socket) {
+ protected TcpReceiverConnection(Socket socket) {
Assert.notNull(socket, "socket must not be null");
this.socket = socket;
}
+ public boolean hasError() throws IOException {
+ return false;
+ }
+
+ public String getErrorMessage() throws IOException {
+ return null;
+ }
+
public void close() throws IOException {
socket.close();
}
@@ -73,7 +81,7 @@ public class TcpReceivingWebServiceConnection extends AbstractReceivingWebServic
};
}
- protected void sendResponse() throws IOException {
+ protected void sendResponse(boolean sentFault) throws IOException {
}
diff --git a/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpSendingWebServiceConnection.java b/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpSenderConnection.java
similarity index 86%
rename from sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpSendingWebServiceConnection.java
rename to sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpSenderConnection.java
index 005ec35c..ad5c0a4f 100644
--- a/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpSendingWebServiceConnection.java
+++ b/sandbox/src/main/java/org/springframework/ws/transport/tcp/TcpSenderConnection.java
@@ -26,14 +26,14 @@ import java.util.Collections;
import java.util.Iterator;
import org.springframework.util.Assert;
-import org.springframework.ws.transport.AbstractSendingWebServiceConnection;
+import org.springframework.ws.transport.AbstractSenderConnection;
/** @author Arjen Poutsma */
-public class TcpSendingWebServiceConnection extends AbstractSendingWebServiceConnection {
+public class TcpSenderConnection extends AbstractSenderConnection {
private final Socket socket;
- public TcpSendingWebServiceConnection(Socket socket) {
+ protected TcpSenderConnection(Socket socket) {
Assert.notNull(socket, "socket must not be null");
this.socket = socket;
}
@@ -42,6 +42,14 @@ public class TcpSendingWebServiceConnection extends AbstractSendingWebServiceCon
socket.close();
}
+ public boolean hasError() throws IOException {
+ return false;
+ }
+
+ public String getErrorMessage() throws IOException {
+ return null;
+ }
+
protected void addRequestHeader(String name, String value) throws IOException {
}
diff --git a/sandbox/src/test/java/org/springframework/ws/transport/SimpleTestingMessageReceiver.java b/sandbox/src/test/java/org/springframework/ws/transport/SimpleTestingMessageReceiver.java
index b40d0948..aff2af56 100644
--- a/sandbox/src/test/java/org/springframework/ws/transport/SimpleTestingMessageReceiver.java
+++ b/sandbox/src/test/java/org/springframework/ws/transport/SimpleTestingMessageReceiver.java
@@ -18,14 +18,14 @@ package org.springframework.ws.transport;
import javax.xml.transform.Transformer;
-import junit.framework.Assert;
import org.springframework.ws.context.MessageContext;
import org.springframework.xml.transform.TransformerObjectSupport;
+import org.springframework.util.Assert;
public class SimpleTestingMessageReceiver extends TransformerObjectSupport implements WebServiceMessageReceiver {
public void receive(MessageContext messageContext) throws Exception {
- Assert.assertNotNull("MessageContext is null", messageContext);
+ Assert.notNull(messageContext, "MessageContext is null");
logger.info("Received message");
Transformer transformer = createTransformer();
transformer.transform(messageContext.getRequest().getPayloadSource(),
diff --git a/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsUriTest.java b/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsUriTest.java
index 028d72d5..87f6465a 100644
--- a/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsUriTest.java
+++ b/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsUriTest.java
@@ -35,7 +35,6 @@ public class JmsUriTest extends TestCase {
assertEquals("Invalid prority", 8, uri.getPriority());
assertEquals("Invalid time to live", 10, uri.getTimeToLive());
assertEquals("Invalid reply to name", "interested", uri.getReplyTo());
- assertEquals("Invalid custom property", "mystuff", uri.getCustomParameter("userprop"));
}
diff --git a/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsTransportUtilsTest.java b/sandbox/src/test/java/org/springframework/ws/transport/jms/support/JmsTransportUtilsTest.java
similarity index 88%
rename from sandbox/src/test/java/org/springframework/ws/transport/jms/JmsTransportUtilsTest.java
rename to sandbox/src/test/java/org/springframework/ws/transport/jms/support/JmsTransportUtilsTest.java
index 90aa01cb..350665eb 100644
--- a/sandbox/src/test/java/org/springframework/ws/transport/jms/JmsTransportUtilsTest.java
+++ b/sandbox/src/test/java/org/springframework/ws/transport/jms/support/JmsTransportUtilsTest.java
@@ -14,9 +14,10 @@
* limitations under the License.
*/
-package org.springframework.ws.transport.jms;
+package org.springframework.ws.transport.jms.support;
import junit.framework.TestCase;
+import org.springframework.ws.transport.jms.support.JmsTransportUtils;
public class JmsTransportUtilsTest extends TestCase {
diff --git a/sandbox/src/test/java/org/springframework/ws/transport/mail/Driver.java b/sandbox/src/test/java/org/springframework/ws/transport/mail/Driver.java
new file mode 100644
index 00000000..107a6714
--- /dev/null
+++ b/sandbox/src/test/java/org/springframework/ws/transport/mail/Driver.java
@@ -0,0 +1,32 @@
+/*
+ * 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.mail;
+
+import java.io.IOException;
+
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+/** @author Arjen Poutsma */
+public class Driver {
+
+ public static void main(String[] args) throws IOException {
+ new ClassPathXmlApplicationContext("applicationContext.xml", Driver.class);
+ System.out.println("Started....");
+ System.in.read();
+ }
+
+}
diff --git a/sandbox/src/test/java/org/springframework/ws/transport/mail/MailMessageSenderIntegrationTest.java b/sandbox/src/test/java/org/springframework/ws/transport/mail/MailMessageSenderIntegrationTest.java
new file mode 100644
index 00000000..1d270489
--- /dev/null
+++ b/sandbox/src/test/java/org/springframework/ws/transport/mail/MailMessageSenderIntegrationTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.mail;
+
+import java.util.Properties;
+import javax.jms.BytesMessage;
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPConstants;
+import javax.xml.soap.SOAPMessage;
+import javax.mail.URLName;
+
+import junit.framework.TestCase;
+import org.springframework.ws.soap.SoapMessage;
+import org.springframework.ws.soap.saaj.SaajSoapMessage;
+import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
+import org.springframework.ws.transport.WebServiceConnection;
+
+public class MailMessageSenderIntegrationTest extends TestCase {
+
+ private MailMessageSender messageSender;
+
+ private MessageFactory messageFactory;
+
+ private static final String URI = "mailto:ajwpi21@xs4all.nl?subject=SOAP Test";
+
+ private static final String SOAP_ACTION = "http://springframework.org/DoIt";
+
+ protected void setUp() throws Exception {
+ Properties properties = new Properties();
+ properties.setProperty("mail.smtp.host", "smtp.xs4all.nl");
+ messageSender = new MailMessageSender();
+ messageSender.setStoreUri("pop3://ajwpi21:sjantaL.@pop.xs4all.nl/INBOX");
+ messageSender.setTransportUri("smtp://ajwpi21:sjantaL.@smtp.xs4all.nl");
+ messageSender.setFrom("Arjen Poutsma