From 755236e60c3e313653d3da30faf2ebc17fdbfcaf Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Fri, 28 Sep 2007 22:19:56 +0000 Subject: [PATCH] Updates sandbox so it compiles. --- .../AbstractWsAddressingMapping.java | 24 ++-- .../soap/addressing/WsAddressing200408.java | 4 +- .../ws/soap/addressing/package.html | 5 + .../AbstractPollingMonitoringStrategy.java | 90 +++++++++++++ .../mail/DefaultMonitoringStrategy.java | 108 +++++++++++++++ .../transport/mail/MailMessageReceiver.java | 127 +++++++++--------- .../mail/MailReceiverConnection.java | 43 +++--- .../transport/mail/MailSenderConnection.java | 70 ++++++---- .../mail/MailTransportInputStream.java | 67 --------- .../mail/MailTransportOutputStream.java | 53 -------- .../ws/transport/mail/MonitoringStrategy.java | 20 ++- .../soap/addressing/AddressingHelperTest.java | 4 - .../ws/transport/mail/Driver.java | 8 +- .../MailMessageSenderIntegrationTest.java | 10 +- .../TcpMessageReceiverIntegrationTest.java | 3 +- sandbox/src/test/resources/log4j.properties | 3 +- .../ws/transport/mail/applicationContext.xml | 8 +- 17 files changed, 388 insertions(+), 259 deletions(-) create mode 100644 sandbox/src/main/java/org/springframework/ws/soap/addressing/package.html create mode 100644 sandbox/src/main/java/org/springframework/ws/transport/mail/AbstractPollingMonitoringStrategy.java create mode 100644 sandbox/src/main/java/org/springframework/ws/transport/mail/DefaultMonitoringStrategy.java delete mode 100644 sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportInputStream.java delete mode 100644 sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportOutputStream.java diff --git a/sandbox/src/main/java/org/springframework/ws/soap/addressing/AbstractWsAddressingMapping.java b/sandbox/src/main/java/org/springframework/ws/soap/addressing/AbstractWsAddressingMapping.java index fd488a8f..e8345264 100644 --- a/sandbox/src/main/java/org/springframework/ws/soap/addressing/AbstractWsAddressingMapping.java +++ b/sandbox/src/main/java/org/springframework/ws/soap/addressing/AbstractWsAddressingMapping.java @@ -18,8 +18,6 @@ package org.springframework.ws.soap.addressing; import javax.xml.transform.TransformerException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.springframework.core.JdkVersion; import org.springframework.util.Assert; import org.springframework.ws.context.MessageContext; @@ -33,13 +31,15 @@ import org.springframework.ws.soap.server.SoapEndpointInvocationChain; import org.springframework.ws.soap.server.SoapEndpointMapping; import org.springframework.xml.transform.TransformerObjectSupport; -/** @author Arjen Poutsma */ +/** + * @author Arjen Poutsma + */ public abstract class AbstractWsAddressingMapping extends TransformerObjectSupport implements SoapEndpointMapping { - protected final Log logger = LogFactory.getLog(getClass()); - private String[] actorsOrRoles; + private boolean isUltimateReceiver = true; + private MessageIdProvider messageIdProvider; private AddressingHelper[] helpers = new AddressingHelper[]{new AddressingHelper(new WsAddressing200408())}; @@ -50,7 +50,9 @@ public abstract class AbstractWsAddressingMapping extends TransformerObjectSuppo private static final Object MISSING_HEADER_ENDPOINT = new Object(); - /** Protected constructor */ + /** + * Protected constructor + */ protected AbstractWsAddressingMapping() { if (JdkVersion.getMajorJavaVersion() >= JdkVersion.JAVA_15) { messageIdProvider = new UuidMessageIdProvider(); @@ -70,6 +72,10 @@ public abstract class AbstractWsAddressingMapping extends TransformerObjectSuppo this.actorsOrRoles = actorsOrRoles; } + public final void setUltimateReceiver(boolean ultimateReceiver) { + this.isUltimateReceiver = ultimateReceiver; + } + /** * Sets the message id provider used for creating WS-Addressing MessageIds. By default, the {@link * UuidMessageIdProvider} is used on Java 5 and higher, and the {@link UidMessageIdProvider} on Java 1.4 and lower. @@ -80,9 +86,9 @@ public abstract class AbstractWsAddressingMapping extends TransformerObjectSuppo public final void setVersions(WsAddressingVersion[] versions) { Assert.notEmpty(versions, "specifications must not be empty"); - helpers = new AddressingHelper[versions.length]; + this.helpers = new AddressingHelper[versions.length]; for (int i = 0; i < versions.length; i++) { - helpers[i] = new AddressingHelper(versions[i]); + this.helpers[i] = new AddressingHelper(versions[i]); } } @@ -107,7 +113,7 @@ public abstract class AbstractWsAddressingMapping extends TransformerObjectSuppo if (endpoint == null) { return null; } - return new SoapEndpointInvocationChain(endpoint, null, actorsOrRoles); + return new SoapEndpointInvocationChain(endpoint, null, actorsOrRoles, isUltimateReceiver); } return null; } diff --git a/sandbox/src/main/java/org/springframework/ws/soap/addressing/WsAddressing200408.java b/sandbox/src/main/java/org/springframework/ws/soap/addressing/WsAddressing200408.java index 72fd3f52..17955066 100644 --- a/sandbox/src/main/java/org/springframework/ws/soap/addressing/WsAddressing200408.java +++ b/sandbox/src/main/java/org/springframework/ws/soap/addressing/WsAddressing200408.java @@ -20,11 +20,11 @@ import javax.xml.namespace.QName; /** * Implements the August 2004 edition of the WS-Addressing specification. This version of the specification is used by - * Microsoft's Web Service Enhancements (WSE) 3.0. + * Microsoft's Web Services Enhancements (WSE) 3.0. * * @author Arjen Poutsma * @see Web Services Addressing, August 2004 - * @see Web Service Enhancements + * @see Web Services Enhancements */ public class WsAddressing200408 implements WsAddressingVersion { diff --git a/sandbox/src/main/java/org/springframework/ws/soap/addressing/package.html b/sandbox/src/main/java/org/springframework/ws/soap/addressing/package.html new file mode 100644 index 00000000..b859632d --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/soap/addressing/package.html @@ -0,0 +1,5 @@ + + +Provides WS-Addressing implementation classes. + + \ No newline at end of file diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/AbstractPollingMonitoringStrategy.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/AbstractPollingMonitoringStrategy.java new file mode 100644 index 00000000..fd6fc8b8 --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/transport/mail/AbstractPollingMonitoringStrategy.java @@ -0,0 +1,90 @@ +/* + * 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.Folder; +import javax.mail.Message; +import javax.mail.MessagingException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.InitializingBean; + +/** + * Abstract base class for {@link MonitoringStrategy} implementations that use a polling mechanism. Defines a {@link + * #setPollingInterval(int) polling interval} property which defines the interval in between message polls. + * + * @author Arjen Poutsma + */ +public abstract class AbstractPollingMonitoringStrategy implements MonitoringStrategy, InitializingBean { + + /** + * Defines the default polling frequency. Set to 1000 * 60 * 5 milliseconds (i.e. 5 minutes). + */ + public static final int DEFAULT_POLLING_FREQUENCY = 1000 * 60 * 5; + + /** + * Logger available to subclasses. + */ + private final Log logger = LogFactory.getLog(getClass()); + + private int pollingInterval = DEFAULT_POLLING_FREQUENCY; + + public void afterPropertiesSet() throws Exception { + logger.info("Polling every " + getPollingInterval() + " milliseconds"); + } + + /** + * Returns the polling interval. + */ + public int getPollingInterval() { + return pollingInterval; + } + + /** + * Sets the interval used in between message polls, in milliseconds. The default is 1000 * 60 * 5 + * ms, that is 5 minutes. + */ + public void setPollingInterval(int pollingInterval) { + this.pollingInterval = pollingInterval; + } + + /** + * Sleeps for the {@link #setPollingInterval(int) defined amount of milliseconds}, and calls {@link + * #pollForNewMessages(Folder)}. + * + * @param folder the folder to look in + * @return the new messages + * @throws MessagingException in case of JavaMail errors. + */ + public final Message[] getNewMessages(Folder folder) throws MessagingException { + try { + Thread.sleep(getPollingInterval()); + folder.getMessageCount(); + return pollForNewMessages(folder); + } + catch (InterruptedException e) { + logger.warn(e); + return new Message[0]; + } + } + + /** + * Abstract template method that is invoked every interval. + */ + protected abstract Message[] pollForNewMessages(Folder folder) throws MessagingException; +} diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/DefaultMonitoringStrategy.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/DefaultMonitoringStrategy.java new file mode 100644 index 00000000..b2bd19e2 --- /dev/null +++ b/sandbox/src/main/java/org/springframework/ws/transport/mail/DefaultMonitoringStrategy.java @@ -0,0 +1,108 @@ +/* + * 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.FetchProfile; +import javax.mail.Flags; +import javax.mail.Folder; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.search.AndTerm; +import javax.mail.search.FlagTerm; +import javax.mail.search.SearchTerm; + +/** + * Default implementation of the {@link MonitoringStrategy}. Polls for new messages using a defined {@link + * #setPollingInterval(int) interval}. + * + * @author Arjen Poutsma + */ +public class DefaultMonitoringStrategy extends AbstractPollingMonitoringStrategy { + + private boolean deleteMessages = true; + + /** + * Sets whether messages should be marked as {@link Flags.Flag#DELETED DELETED} after they have been read. Default + * is true. + */ + public void setDeleteMessages(boolean deleteMessages) { + this.deleteMessages = deleteMessages; + } + + /** + * Polls for new messages in the given folder. Calls {@link #createSearchTerm(Folder)}, and uses that created term + * to search for messages in the given folder. Marks the messages as {@link Flags.Flag#DELETED DELETED} if the + * {@link #setDeleteMessages(boolean) deleteMessages} property is set. + */ + protected final Message[] pollForNewMessages(Folder folder) throws MessagingException { + SearchTerm searchTerm = createSearchTerm(folder); + Message[] messages; + if (searchTerm == null) { + messages = folder.getMessages(); + } + else { + messages = folder.search(searchTerm); + } + if (messages.length > 0) { + FetchProfile contentsProfile = new FetchProfile(); + contentsProfile.add(FetchProfile.Item.ENVELOPE); + contentsProfile.add(FetchProfile.Item.CONTENT_INFO); + folder.fetch(messages, contentsProfile); + if (deleteMessages) { + for (int i = 0; i < messages.length; i++) { + messages[i].setFlag(Flags.Flag.DELETED, true); + } + } + } + return messages; + } + + /** + * Creates the search term that defines the messages to look for. Default implementation returns a term that + * searches for all messages in the folder that are {@link Flags.Flag#RECENT RECENT}, and not {@link + * Flags.Flag#ANSWERED ANSWERED}, and not {@link Flags.Flag#DELETED DELETED}. + *

+ * Return null if all messages should be returned from {@link #pollForNewMessages(Folder)}. + */ + protected SearchTerm createSearchTerm(Folder folder) { + Flags supportedFlags = folder.getPermanentFlags(); + SearchTerm searchTerm = null; + if (supportedFlags.contains(Flags.Flag.RECENT)) { + searchTerm = new FlagTerm(new Flags(Flags.Flag.RECENT), true); + } + if (supportedFlags.contains(Flags.Flag.ANSWERED)) { + FlagTerm answeredTerm = new FlagTerm(new Flags(Flags.Flag.ANSWERED), false); + if (searchTerm == null) { + searchTerm = answeredTerm; + } + else { + searchTerm = new AndTerm(searchTerm, answeredTerm); + } + } + if (supportedFlags.contains(Flags.Flag.DELETED)) { + FlagTerm deletedTerm = new FlagTerm(new Flags(Flags.Flag.DELETED), false); + if (searchTerm == null) { + searchTerm = deletedTerm; + } + else { + searchTerm = new AndTerm(searchTerm, deletedTerm); + } + } + return searchTerm; + } + +} 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 index 967808d3..a3d46b62 100644 --- a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailMessageReceiver.java +++ b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailMessageReceiver.java @@ -18,34 +18,41 @@ 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 javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; -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 */ +/** + * @author Arjen Poutsma + */ public class MailMessageReceiver extends AbstractMultiThreadedMessageReceiver { private Session session = Session.getInstance(new Properties(), null); private URLName storeUri; - private Folder folder; + private URLName transportUri; - private MessageCountHandler eventHandler; + private Folder folder; private Store store; - private boolean supportsIdle; + private MonitoringStrategy monitoringStrategy = new DefaultMonitoringStrategy(); + + private InternetAddress from; + + public void setFrom(String from) throws AddressException { + this.from = new InternetAddress(from); + } /** * Set JavaMail properties for the {@link Session}. @@ -59,6 +66,14 @@ public class MailMessageReceiver extends AbstractMultiThreadedMessageReceiver { session = Session.getInstance(javaMailProperties, null); } + /** + * + * @param monitoringStrategy + */ + public void setMonitoringStrategy(MonitoringStrategy monitoringStrategy) { + this.monitoringStrategy = monitoringStrategy; + } + /** * Set the JavaMail Session, possibly pulled from JNDI. *

@@ -79,9 +94,15 @@ public class MailMessageReceiver extends AbstractMultiThreadedMessageReceiver { this.storeUri = new URLName(storeUri); } + public void setTransportUri(String transportUri) { + this.transportUri = new URLName(transportUri); + } + public void afterPropertiesSet() throws Exception { - super.afterPropertiesSet(); Assert.notNull(storeUri, "Property 'storeUri' is required"); + Assert.notNull(transportUri, "Property 'transportUri' is required"); + Assert.notNull(monitoringStrategy, "Property 'monitoringStrategy' is required"); + super.afterPropertiesSet(); } protected void onActivate() throws Exception { @@ -92,24 +113,6 @@ public class MailMessageReceiver extends AbstractMultiThreadedMessageReceiver { 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()); } @@ -117,10 +120,6 @@ public class MailMessageReceiver extends AbstractMultiThreadedMessageReceiver { if (logger.isInfoEnabled()) { logger.info("Stopping mail receiver [" + storeUri.toString() + "]"); } - if (eventHandler != null) { - folder.removeMessageCountListener(eventHandler); - eventHandler = null; - } } protected void onShutdown() { @@ -130,6 +129,11 @@ public class MailMessageReceiver extends AbstractMultiThreadedMessageReceiver { closeFolder(); } + protected void closeFolder() { + MailUtils.closeFolder(folder, true); + MailUtils.closeService(store); + } + protected void openFolder() throws MessagingException, MailTransportException { store = session.getStore(storeUri); store.connect(); @@ -138,51 +142,50 @@ public class MailMessageReceiver extends AbstractMultiThreadedMessageReceiver { 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(); + while (isRunning()) { + try { + Message[] newMessages = monitoringStrategy.getNewMessages(folder); + for (int i = 0; i < newMessages.length; i++) { + if (logger.isDebugEnabled()) { + if (newMessages[i] instanceof MimeMessage) { + MimeMessage mimeMessage = (MimeMessage) newMessages[i]; + logger.debug("Received email message with MessageID " + mimeMessage.getMessageID()); + } + } + MessageRequestHandler handler = new MessageRequestHandler(newMessages[i]); + getTaskExecutor().execute(handler); } } - } - catch (InterruptedException ex) { - logger.warn(ex); - } - catch (MessagingException ex) { - logger.warn(ex); + catch (MessagingException ex) { + logger.warn(ex); + } } } } - private class MessageCountHandler implements MessageCountListener { + private class MessageRequestHandler implements Runnable { - public void messagesAdded(MessageCountEvent event) { - Message[] msgs = event.getMessages(); - logger.info("Got " + msgs.length + " new messages"); + private final Message message; + + public MessageRequestHandler(Message message) { + this.message = message; } - public void messagesRemoved(MessageCountEvent e) { + public void run() { + MailReceiverConnection connection = new MailReceiverConnection(message, session); + connection.setTransportUri(transportUri); + connection.setFrom(from); + try { + handleConnection(connection); + } + catch (Exception ex) { + logger.warn("Could not handle message", ex); + } } } } 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 index 80962942..e4a63947 100644 --- a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailReceiverConnection.java +++ b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailReceiverConnection.java @@ -16,42 +16,42 @@ 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.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.activation.DataHandler; +import javax.activation.DataSource; import javax.mail.Header; +import javax.mail.Message; 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 javax.mail.internet.InternetAddress; import org.springframework.util.Assert; +import org.springframework.ws.WebServiceMessage; 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 */ +/** + * @author Arjen Poutsma + */ public class MailReceiverConnection extends AbstractReceiverConnection { - private final MimeMessage requestMessage; + private final Message requestMessage; private final Session session; - private MimeMessage responseMessage; + private Message responseMessage; private ByteArrayOutputStream responseBuffer; @@ -59,7 +59,9 @@ public class MailReceiverConnection extends AbstractReceiverConnection { private URLName transportUri; - public MailReceiverConnection(MimeMessage requestMessage, Session session) { + private InternetAddress from; + + public MailReceiverConnection(Message requestMessage, Session session) { Assert.notNull(requestMessage, "'requestMessage' must not be null"); Assert.notNull(session, "'session' must not be null"); this.requestMessage = requestMessage; @@ -112,7 +114,7 @@ public class MailReceiverConnection extends AbstractReceiverConnection { protected InputStream getRequestInputStream() throws IOException { try { - return requestMessage.getDataHandler().getInputStream(); + return requestMessage.getInputStream(); } catch (MessagingException ex) { throw new MailTransportException(ex); @@ -141,7 +143,8 @@ public class MailReceiverConnection extends AbstractReceiverConnection { protected void onSendBeforeWrite(WebServiceMessage message) throws IOException { try { - responseMessage = (MimeMessage) requestMessage.reply(false); + responseMessage = requestMessage.reply(false); + responseMessage.setFrom(from); responseBuffer = new ByteArrayOutputStream(); } @@ -153,12 +156,12 @@ public class MailReceiverConnection extends AbstractReceiverConnection { protected void onSendAfterWrite(WebServiceMessage message) throws IOException { Transport transport = null; try { - requestMessage.setDataHandler( + responseMessage.setDataHandler( new DataHandler(new ByteArrayDataSource(responseContentType, responseBuffer.toByteArray()))); transport = session.getTransport(transportUri); transport.connect(); - requestMessage.saveChanges(); - transport.sendMessage(requestMessage, requestMessage.getAllRecipients()); + responseMessage.saveChanges(); + transport.sendMessage(responseMessage, responseMessage.getAllRecipients()); } catch (MessagingException ex) { throw new MailTransportException(ex); @@ -168,6 +171,10 @@ public class MailReceiverConnection extends AbstractReceiverConnection { } } + public void setFrom(InternetAddress from) { + this.from = from; + } + private class ByteArrayDataSource implements DataSource { private byte[] data; 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 index bda7c7b8..2ef50af4 100644 --- a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailSenderConnection.java +++ b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailSenderConnection.java @@ -46,12 +46,15 @@ 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.util.StringUtils; 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 */ +/** + * @author Arjen Poutsma + */ public class MailSenderConnection extends AbstractSenderConnection { private static final Log logger = LogFactory.getLog(MailSenderConnection.class); @@ -62,7 +65,7 @@ public class MailSenderConnection extends AbstractSenderConnection { private MimeMessage requestMessage; - private MimeMessage responseMessage; + private Message responseMessage; private String requestContentType; @@ -84,7 +87,7 @@ public class MailSenderConnection extends AbstractSenderConnection { this.from = from; } - public MimeMessage getRequestMessage() { + public Message getRequestMessage() { return requestMessage; } @@ -162,35 +165,43 @@ public class MailSenderConnection extends AbstractSenderConnection { Store store = null; Folder folder = null; try { - try { - Thread.sleep(5000); + String requestMessageId = null; + if (requestMessage instanceof MimeMessage) { + requestMessageId = ((MimeMessage) requestMessage).getMessageID(); } - 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); + if (StringUtils.hasLength(requestMessageId)) { + 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); + } + 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); + } } 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); + logger.warn("Request message had no Message ID, could not find response"); } } catch (MessagingException ex) { @@ -279,4 +290,5 @@ public class MailSenderConnection extends AbstractSenderConnection { return "ByteArrayDataSource"; } } + } diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportInputStream.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportInputStream.java deleted file mode 100644 index 4865db93..00000000 --- a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportInputStream.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2006 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.util.Arrays; -import java.util.Iterator; -import javax.mail.Message; -import javax.mail.MessagingException; - -import org.springframework.ws.transport.TransportInputStream; -import org.springframework.ws.transport.support.EnumerationIterator; - -/** - * @author Arjen Poutsma - */ -public class MailTransportInputStream extends TransportInputStream { - - private final Message message; - - public MailTransportInputStream(Message message) { - this.message = message; - } - - protected InputStream createInputStream() throws IOException { - try { - return message.getDataHandler().getInputStream(); - } - catch (MessagingException ex) { - throw new IOException(ex.getMessage()); - } - } - - public Iterator getHeaders(String name) throws IOException { - try { - String[] headers = message.getHeader(name); - return Arrays.asList(headers).iterator(); - } - catch (MessagingException ex) { - throw new IOException(ex.getMessage()); - } - } - - public Iterator getHeaderNames() throws IOException { - try { - return new EnumerationIterator(message.getAllHeaders()); - } - catch (MessagingException ex) { - throw new IOException(ex.getMessage()); - } - } -} diff --git a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportOutputStream.java b/sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportOutputStream.java deleted file mode 100644 index c72c26a2..00000000 --- a/sandbox/src/main/java/org/springframework/ws/transport/mail/MailTransportOutputStream.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2006 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.OutputStream; -import javax.mail.Message; -import javax.mail.MessagingException; - -import org.springframework.ws.transport.TransportOutputStream; - -/** @author Arjen Poutsma */ -public class MailTransportOutputStream extends TransportOutputStream { - - private final Message message; - - public MailTransportOutputStream(Message message) { - this.message = message; - } - - public void addHeader(String name, String value) throws IOException { - try { - message.addHeader(name, value); - } - catch (MessagingException ex) { - throw new IOException(ex.getMessage()); - } - } - - protected OutputStream createOutputStream() throws IOException { - try { - return message.getDataHandler().getOutputStream(); - } - catch (MessagingException ex) { - throw new IOException(ex.getMessage()); - } - } - -} 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 index 2222abbf..3e6bf859 100644 --- a/sandbox/src/main/java/org/springframework/ws/transport/mail/MonitoringStrategy.java +++ b/sandbox/src/main/java/org/springframework/ws/transport/mail/MonitoringStrategy.java @@ -16,7 +16,25 @@ package org.springframework.ws.transport.mail; -/** @author Arjen Poutsma */ +import javax.mail.Folder; +import javax.mail.Message; +import javax.mail.MessagingException; + +/** + * Defines the contract for objects that monitor a given folder for new messages. Allows for multiple implementation + * strategies, including polling, or event-driven techniques such as IMAP's IDLE command. + * + * @author Arjen Poutsma + */ public interface MonitoringStrategy { + /** + * Return the new messages in a given JavaMail folder. + * + * @param folder the folder in which to look for new messages + * @return the new messages + * @throws MessagingException in case of JavaMail errors + */ + Message[] getNewMessages(Folder folder) throws MessagingException; + } diff --git a/sandbox/src/test/java/org/springframework/ws/soap/addressing/AddressingHelperTest.java b/sandbox/src/test/java/org/springframework/ws/soap/addressing/AddressingHelperTest.java index 8c3b7fdd..ac2ac7f8 100644 --- a/sandbox/src/test/java/org/springframework/ws/soap/addressing/AddressingHelperTest.java +++ b/sandbox/src/test/java/org/springframework/ws/soap/addressing/AddressingHelperTest.java @@ -21,18 +21,14 @@ import javax.xml.soap.SOAPConstants; import javax.xml.soap.SOAPMessage; import org.springframework.ws.soap.saaj.SaajSoapMessage; -import org.w3c.dom.Element; public class AddressingHelperTest extends AbstractWsAddressingTestCase { private AddressingHelper helper; - private Element headerElement; - protected void onSetUp() throws Exception { helper = new AddressingHelper(new WsAddressing200408()); SaajSoapMessage message = loadSaajMessage("request-200408.xml"); - headerElement = message.getSaajMessage().getSOAPHeader(); } public void testAddMessageHeaderRequiredFault12() throws Exception { 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 index 107a6714..36aa86e2 100644 --- a/sandbox/src/test/java/org/springframework/ws/transport/mail/Driver.java +++ b/sandbox/src/test/java/org/springframework/ws/transport/mail/Driver.java @@ -20,11 +20,15 @@ import java.io.IOException; import org.springframework.context.support.ClassPathXmlApplicationContext; -/** @author Arjen Poutsma */ +/** + * @author Arjen Poutsma + */ public class Driver { public static void main(String[] args) throws IOException { - new ClassPathXmlApplicationContext("applicationContext.xml", Driver.class); + ClassPathXmlApplicationContext context = + new ClassPathXmlApplicationContext("applicationContext.xml", Driver.class); + context.registerShutdownHook(); 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 index 1d270489..78769594 100644 --- a/sandbox/src/test/java/org/springframework/ws/transport/mail/MailMessageSenderIntegrationTest.java +++ b/sandbox/src/test/java/org/springframework/ws/transport/mail/MailMessageSenderIntegrationTest.java @@ -16,17 +16,14 @@ package org.springframework.ws.transport.mail; -import java.util.Properties; -import javax.jms.BytesMessage; +import javax.xml.namespace.QName; 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 { @@ -36,17 +33,15 @@ public class MailMessageSenderIntegrationTest extends TestCase { private MessageFactory messageFactory; private static final String URI = "mailto:ajwpi21@xs4all.nl?subject=SOAP Test"; +// private static final String URI = "mailto:revans@interface21.com?subject=Believe me now?"; 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 "); - messageSender.setJavaMailProperties(properties); messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL); } @@ -55,6 +50,7 @@ public class MailMessageSenderIntegrationTest extends TestCase { try { connection = messageSender.createConnection(URI); SOAPMessage saajMessage = messageFactory.createMessage(); + saajMessage.getSOAPBody().addBodyElement(new QName("http://springframework.org", "test")); SoapMessage soapRequest = new SaajSoapMessage(saajMessage); soapRequest.setSoapAction(SOAP_ACTION); connection.send(soapRequest); diff --git a/sandbox/src/test/java/org/springframework/ws/transport/tcp/TcpMessageReceiverIntegrationTest.java b/sandbox/src/test/java/org/springframework/ws/transport/tcp/TcpMessageReceiverIntegrationTest.java index 6de7345f..551fb329 100644 --- a/sandbox/src/test/java/org/springframework/ws/transport/tcp/TcpMessageReceiverIntegrationTest.java +++ b/sandbox/src/test/java/org/springframework/ws/transport/tcp/TcpMessageReceiverIntegrationTest.java @@ -76,7 +76,8 @@ public class TcpMessageReceiverIntegrationTest extends AbstractDependencyInjecti public void testTemplate() throws Exception { WebServiceTemplate template = new WebServiceTemplate(messageFactory); template.setMessageSender(messageSender); - template.sendAndReceive("tcp://localhost",new StringSource(REQUEST), new StreamResult(System.out)); + template.sendSourceAndReceiveToResult("tcp://localhost", new StringSource(REQUEST), + new StreamResult(System.out)); } protected String[] getConfigLocations() { diff --git a/sandbox/src/test/resources/log4j.properties b/sandbox/src/test/resources/log4j.properties index 92e896c8..0e307524 100644 --- a/sandbox/src/test/resources/log4j.properties +++ b/sandbox/src/test/resources/log4j.properties @@ -1,5 +1,6 @@ log4j.rootCategory=INFO, stdout -log4j.logger.org.springframework.ws=DEBUG +#log4j.logger.org.springframework.ws=DEBUG +log4j.logger.org.springframework=DEBUG log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout diff --git a/sandbox/src/test/resources/org/springframework/ws/transport/mail/applicationContext.xml b/sandbox/src/test/resources/org/springframework/ws/transport/mail/applicationContext.xml index 544cc4e1..ecfcdabb 100644 --- a/sandbox/src/test/resources/org/springframework/ws/transport/mail/applicationContext.xml +++ b/sandbox/src/test/resources/org/springframework/ws/transport/mail/applicationContext.xml @@ -3,18 +3,20 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> - + + + + + - -