This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>spring-ws</artifactId>
|
||||
@@ -21,6 +22,16 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<reporting>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<configuration>
|
||||
<stylesheetfile>${basedir}/../src/main/javadoc/javadoc.css</stylesheetfile>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
<dependencies>
|
||||
<!-- Spring-WS dependencies -->
|
||||
<dependency>
|
||||
@@ -56,6 +67,11 @@
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jms</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-remoting</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jmx</artifactId>
|
||||
@@ -84,10 +100,10 @@
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.jbi</groupId>
|
||||
<artifactId>jbi</artifactId>
|
||||
<version>1.0</version>
|
||||
<scope>provided</scope>
|
||||
<groupId>javax.ejb</groupId>
|
||||
<artifactId>ejb</artifactId>
|
||||
<version>2.1</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.xml.ws</groupId>
|
||||
@@ -127,5 +143,12 @@
|
||||
<version>6.0.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- Test dependencies -->
|
||||
<dependency>
|
||||
<groupId>easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
<version>1.2_Java1.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -32,11 +32,15 @@ import javax.jms.Session;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.springframework.jms.support.JmsUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.FaultAwareWebServiceMessage;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.transport.AbstractReceiverConnection;
|
||||
import org.springframework.ws.transport.FaultAwareWebServiceConnection;
|
||||
import org.springframework.ws.transport.jms.support.JmsTransportUtils;
|
||||
|
||||
/** @author Arjen Poutsma */
|
||||
public class JmsReceiverConnection extends AbstractReceiverConnection implements JmsTransportConstants {
|
||||
public class JmsReceiverConnection extends AbstractReceiverConnection
|
||||
implements JmsTransportConstants, FaultAwareWebServiceConnection {
|
||||
|
||||
private final Log logger;
|
||||
|
||||
@@ -63,9 +67,6 @@ public class JmsReceiverConnection extends AbstractReceiverConnection implements
|
||||
return false;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
/*
|
||||
* Receiving
|
||||
*/
|
||||
@@ -102,15 +103,18 @@ public class JmsReceiverConnection extends AbstractReceiverConnection implements
|
||||
}
|
||||
|
||||
/*
|
||||
* Sending
|
||||
*/
|
||||
* Sending
|
||||
*/
|
||||
|
||||
protected void onSendBeforeWrite(WebServiceMessage message) throws IOException {
|
||||
try {
|
||||
responseMessage = session.createBytesMessage();
|
||||
responseMessage.setJMSCorrelationID(requestMessage.getJMSMessageID());
|
||||
responseMessage.setStringProperty(PROPERTY_BINDING_VERSION, "1.0");
|
||||
responseMessage.setBooleanProperty(PROPERTY_IS_FAULT, message.hasFault());
|
||||
if (message instanceof FaultAwareWebServiceMessage) {
|
||||
FaultAwareWebServiceMessage faultMessage = (FaultAwareWebServiceMessage) message;
|
||||
responseMessage.setBooleanProperty(PROPERTY_IS_FAULT, faultMessage.hasFault());
|
||||
}
|
||||
}
|
||||
catch (JMSException ex) {
|
||||
throw new JmsTransportException("Could not create response message", ex);
|
||||
@@ -152,4 +156,32 @@ public class JmsReceiverConnection extends AbstractReceiverConnection implements
|
||||
}
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
/*
|
||||
* Faults
|
||||
*/
|
||||
|
||||
public boolean hasFault() throws IOException {
|
||||
try {
|
||||
return requestMessage.getBooleanProperty(JmsTransportConstants.PROPERTY_IS_FAULT);
|
||||
}
|
||||
catch (JMSException ex) {
|
||||
throw new JmsTransportException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void setFault(boolean fault) throws IOException {
|
||||
if (responseMessage != null) {
|
||||
try {
|
||||
responseMessage.setBooleanProperty(JmsTransportConstants.PROPERTY_IS_FAULT, true);
|
||||
}
|
||||
catch (JMSException ex) {
|
||||
throw new JmsTransportException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -37,9 +37,11 @@ import javax.jms.TemporaryQueue;
|
||||
import org.springframework.jms.connection.ConnectionFactoryUtils;
|
||||
import org.springframework.jms.support.JmsUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.ws.FaultAwareWebServiceMessage;
|
||||
import org.springframework.ws.WebServiceMessage;
|
||||
import org.springframework.ws.transport.AbstractSenderConnection;
|
||||
import org.springframework.ws.transport.FaultAwareWebServiceConnection;
|
||||
import org.springframework.ws.transport.jms.support.JmsTransportUtils;
|
||||
|
||||
/** @author Arjen Poutsma */
|
||||
public class JmsSenderConnection extends AbstractSenderConnection
|
||||
@@ -88,6 +90,14 @@ public class JmsSenderConnection extends AbstractSenderConnection
|
||||
return responseMessage;
|
||||
}
|
||||
|
||||
public boolean hasError() throws IOException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getErrorMessage() throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sending
|
||||
*/
|
||||
@@ -96,8 +106,11 @@ public class JmsSenderConnection extends AbstractSenderConnection
|
||||
try {
|
||||
requestMessage = session.createBytesMessage();
|
||||
requestMessage.setStringProperty(PROPERTY_BINDING_VERSION, "1.0");
|
||||
requestMessage.setBooleanProperty(PROPERTY_IS_FAULT, message.hasFault());
|
||||
requestMessage.setStringProperty(PROPERTY_REQUEST_IRI, uri.getUri());
|
||||
if (message instanceof FaultAwareWebServiceMessage) {
|
||||
FaultAwareWebServiceMessage faultMessage = (FaultAwareWebServiceMessage) message;
|
||||
requestMessage.setBooleanProperty(PROPERTY_IS_FAULT, faultMessage.hasFault());
|
||||
}
|
||||
requestMessage.setStringProperty(PROPERTY_REQUEST_IRI, uri.toString());
|
||||
}
|
||||
catch (JMSException ex) {
|
||||
throw new JmsTransportException(ex);
|
||||
@@ -176,6 +189,10 @@ public class JmsSenderConnection extends AbstractSenderConnection
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean hasResponse() throws IOException {
|
||||
return responseMessage != null;
|
||||
}
|
||||
|
||||
protected Iterator getResponseHeaderNames() throws IOException {
|
||||
try {
|
||||
List headerNames = new ArrayList();
|
||||
@@ -216,9 +233,9 @@ public class JmsSenderConnection extends AbstractSenderConnection
|
||||
ConnectionFactoryUtils.releaseConnection(connection, connectionFactory, true);
|
||||
}
|
||||
|
||||
protected boolean hasResponse() throws IOException {
|
||||
return responseMessage != null;
|
||||
}
|
||||
/*
|
||||
* Faults
|
||||
*/
|
||||
|
||||
public boolean hasFault() throws IOException {
|
||||
if (responseMessage != null) {
|
||||
@@ -234,11 +251,13 @@ public class JmsSenderConnection extends AbstractSenderConnection
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasError() throws IOException {
|
||||
return false;
|
||||
public void setFault(boolean fault) throws IOException {
|
||||
try {
|
||||
requestMessage.setBooleanProperty(JmsTransportConstants.PROPERTY_IS_FAULT, true);
|
||||
}
|
||||
catch (JMSException ex) {
|
||||
throw new JmsTransportException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public String getErrorMessage() throws IOException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,49 +28,17 @@ import javax.naming.Context;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.ws.transport.support.ParameterizedUri;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
* @see <a href="http://mail-archives.apache.org/mod_mbox/ws-axis-dev/200701.mbox/raw/%3C80A43FC052CE3949A327527DCD5D6B27020FB65C@MAIL01.bedford.progress.com%3E/2">RI
|
||||
* Scheme for Java Message Service 1.0 RC1</a>
|
||||
*/
|
||||
public class JmsUri implements JmsTransportConstants {
|
||||
|
||||
private final String uri;
|
||||
|
||||
private final String destination;
|
||||
|
||||
// keys are string parameter names; values are string parameter values
|
||||
private final Map parameters = new HashMap();
|
||||
public class JmsUri extends ParameterizedUri implements JmsTransportConstants {
|
||||
|
||||
public JmsUri(String uri) {
|
||||
Assert.hasLength(uri, "'uri' must not be empty");
|
||||
String scheme = URI_SCHEME + ":";
|
||||
Assert.isTrue(uri.startsWith(scheme), uri + " does not start with " + scheme);
|
||||
Assert.isTrue(uri.length() > scheme.length(), uri + " does not have a destination");
|
||||
int paramStart = uri.indexOf('?');
|
||||
if (paramStart == -1) {
|
||||
destination = uri.substring(scheme.length());
|
||||
}
|
||||
else {
|
||||
destination = uri.substring(scheme.length(), paramStart);
|
||||
parseParameters(uri.substring(paramStart + 1));
|
||||
}
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
private void parseParameters(String parametersString) {
|
||||
StringTokenizer params = new StringTokenizer(parametersString, "&");
|
||||
while (params.hasMoreTokens()) {
|
||||
String param = params.nextToken();
|
||||
int paramSep = param.indexOf('=');
|
||||
if (paramSep == -1) {
|
||||
throw new IllegalArgumentException(param + " is not a valid parameter: it has no '='");
|
||||
}
|
||||
String paramName = param.substring(0, paramSep);
|
||||
String paramValue = param.substring(paramSep + 1);
|
||||
parameters.put(paramName, paramValue);
|
||||
}
|
||||
super(uri);
|
||||
validateParameters();
|
||||
}
|
||||
|
||||
@@ -85,7 +53,7 @@ public class JmsUri implements JmsTransportConstants {
|
||||
}
|
||||
|
||||
private void validateIntegerParameter(String paramName) {
|
||||
String paramValue = (String) parameters.get(paramName);
|
||||
String paramValue = (String) getParameter(paramName);
|
||||
if (StringUtils.hasLength(paramValue)) {
|
||||
try {
|
||||
Integer.parseInt(paramValue);
|
||||
@@ -106,9 +74,8 @@ public class JmsUri implements JmsTransportConstants {
|
||||
return getIntegerParameter(PARAM_DELIVERY_MODE, Message.DEFAULT_DELIVERY_MODE);
|
||||
}
|
||||
|
||||
/** Returns thethe JNDI name of the destination queue or topic. */
|
||||
public String getDestination() {
|
||||
return destination;
|
||||
return super.getDestination();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,7 +83,7 @@ public class JmsUri implements JmsTransportConstants {
|
||||
* "<code>topic</code>", 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
@@ -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}.
|
||||
* <p/>
|
||||
* A new {@link Session} will be created with those properties. Use either this method or {@link #setSession}, but
|
||||
* not both.
|
||||
* <p/>
|
||||
* Non-default properties in this instance will override given JavaMail properties.
|
||||
*/
|
||||
public void setJavaMailProperties(Properties javaMailProperties) {
|
||||
session = Session.getInstance(javaMailProperties, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the JavaMail <code>Session</code>, possibly pulled from JNDI.
|
||||
* <p/>
|
||||
* Default is a new <code>Session</code> without defaults, that is completely configured via this instance's
|
||||
* properties.
|
||||
* <p/>
|
||||
* If using a pre-configured <code>Session</code>, non-default properties in this instance will override the
|
||||
* settings in the <code>Session</code>.
|
||||
*
|
||||
* @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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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}.
|
||||
* <p/>
|
||||
* A new {@link Session} will be created with those properties. Use either this method or {@link #setSession}, but
|
||||
* not both.
|
||||
* <p/>
|
||||
* Non-default properties in this instance will override given JavaMail properties.
|
||||
*/
|
||||
public void setJavaMailProperties(Properties javaMailProperties) {
|
||||
session = Session.getInstance(javaMailProperties, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the JavaMail <code>Session</code>, possibly pulled from JNDI.
|
||||
* <p/>
|
||||
* Default is a new <code>Session</code> without defaults, that is completely configured via this instance's
|
||||
* properties.
|
||||
* <p/>
|
||||
* If using a pre-configured <code>Session</code>, non-default properties in this instance will override the
|
||||
* settings in the <code>Session</code>.
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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 <code>finally</code>
|
||||
* blocks in manual JavaMail code.
|
||||
*
|
||||
* @param service the JavaMail Service to close (may be <code>null</code>)
|
||||
* @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 <code>finally</code>
|
||||
* blocks in manual JavaMail code.
|
||||
*
|
||||
* @param folder the JavaMail Folder to close (may be <code>null</code>)
|
||||
*/
|
||||
|
||||
public static void closeFolder(Folder folder) {
|
||||
closeFolder(folder, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the given JavaMail Folder and ignore any thrown exception. This is useful for typical <code>finally</code>
|
||||
* blocks in manual JavaMail code.
|
||||
*
|
||||
* @param folder the JavaMail Folder to close (may be <code>null</code>)
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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.
|
||||
* <p/>
|
||||
* 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.
|
||||
* <p/>
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
* <p/>
|
||||
* Default is <code>true</code>; set this to <code>false</code> 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.
|
||||
* <p/>
|
||||
* 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.
|
||||
* <p/>
|
||||
* 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 <code>true</code>; set this to <code>false</code> 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();
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 <code>ServerSocket</code> for this server.
|
||||
* <p/>
|
||||
* The default implementation delegates to <code>refreshSharedConnection</code>, 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 <code>ServerSocket</code> for this receiver.
|
||||
*/
|
||||
protected void openServerSocket() throws IOException {
|
||||
refreshServerSocket();
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the shared <code>ServerSocket</code> that this server holds.
|
||||
* <p/>
|
||||
* 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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 <ajwp@xs4all.nl>");
|
||||
messageSender.setJavaMailProperties(properties);
|
||||
messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);
|
||||
}
|
||||
|
||||
public void testSendAndReceiveQueueNoResponse() throws Exception {
|
||||
WebServiceConnection connection = null;
|
||||
try {
|
||||
connection = messageSender.createConnection(URI);
|
||||
SOAPMessage saajMessage = messageFactory.createMessage();
|
||||
SoapMessage soapRequest = new SaajSoapMessage(saajMessage);
|
||||
soapRequest.setSoapAction(SOAP_ACTION);
|
||||
connection.send(soapRequest);
|
||||
// SoapMessage response = (SoapMessage) connection.receive(new SaajSoapMessageFactory(messageFactory));
|
||||
}
|
||||
finally {
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.tcp;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,7 +31,7 @@ import org.springframework.ws.client.core.WebServiceTemplate;
|
||||
import org.springframework.ws.transport.WebServiceMessageSender;
|
||||
import org.springframework.xml.transform.StringSource;
|
||||
|
||||
public class TcpServerIntegrationTest extends AbstractDependencyInjectionSpringContextTests {
|
||||
public class TcpMessageReceiverIntegrationTest extends AbstractDependencyInjectionSpringContextTests {
|
||||
|
||||
private WebServiceMessageFactory messageFactory;
|
||||
|
||||
@@ -54,7 +54,7 @@ public class TcpServerIntegrationTest extends AbstractDependencyInjectionSpringC
|
||||
" </SOAP-ENV:Body>\n" + "</SOAP-ENV:Envelope>";
|
||||
|
||||
public void testServer() throws IOException, InterruptedException {
|
||||
Socket socket = new Socket("localhost", 9999);
|
||||
Socket socket = new Socket("localhost", TcpMessageReceiver.DEFAULT_PORT);
|
||||
Writer writer = null;
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
@@ -74,8 +74,9 @@ public class TcpServerIntegrationTest extends AbstractDependencyInjectionSpringC
|
||||
}
|
||||
|
||||
public void testTemplate() throws Exception {
|
||||
WebServiceTemplate template = new WebServiceTemplate(messageFactory, messageSender);
|
||||
template.sendAndReceive(new StringSource(REQUEST), new StreamResult(System.out));
|
||||
WebServiceTemplate template = new WebServiceTemplate(messageFactory);
|
||||
template.setMessageSender(messageSender);
|
||||
template.sendAndReceive("tcp://localhost",new StringSource(REQUEST), new StreamResult(System.out));
|
||||
}
|
||||
|
||||
protected String[] getConfigLocations() {
|
||||
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
|
||||
|
||||
<bean id="messagingReceiver" class="org.springframework.ws.transport.mail.MailMessageReceiver">
|
||||
<property name="storeUri" value="imap://ajwpi21:sjantaL.@imap.xs4all.nl/INBOX"/>
|
||||
<property name="messageFactory" ref="messageFactory"/>
|
||||
<property name="messageReceiver">
|
||||
<bean class="org.springframework.ws.transport.SimpleTestingMessageReceiver"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>
|
||||
|
||||
<!-- define an MBeanExporter -->
|
||||
<bean id="mbeanExporter" class="org.springframework.jmx.export.MBeanExporter">
|
||||
<!-- the beans to be exported to JMX -->
|
||||
<property name="beans">
|
||||
<map>
|
||||
<entry key="spring-ws:service=messagingContainer">
|
||||
<ref local="messagingReceiver"/>
|
||||
</entry>
|
||||
</map>
|
||||
</property>
|
||||
<property name="assembler">
|
||||
<bean class="org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler">
|
||||
<property name="interfaceMappings">
|
||||
<props>
|
||||
<prop key="spring-ws:service=messagingContainer">org.springframework.context.Lifecycle</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
|
||||
</beans>
|
||||
@@ -2,19 +2,14 @@
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
|
||||
|
||||
<bean id="messagingContainer" class="org.springframework.ws.transport.tcp.TcpMessagingContainer">
|
||||
<property name="port" value="9999"/>
|
||||
<property name="bindAddress" value="localhost"/>
|
||||
<bean id="messagingReceiver" class="org.springframework.ws.transport.tcp.TcpMessageReceiver">
|
||||
<property name="messageFactory" ref="messageFactory"/>
|
||||
<property name="messageReceiver">
|
||||
<bean class="org.springframework.ws.transport.SimpleTestingMessageReceiver"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="tcpSender" class="org.springframework.ws.transport.tcp.TcpMessageSender">
|
||||
<property name="port" value="9999"/>
|
||||
<property name="address" value="localhost"/>
|
||||
</bean>
|
||||
<bean id="tcpSender" class="org.springframework.ws.transport.tcp.TcpMessageSender" />
|
||||
|
||||
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>
|
||||
|
||||
@@ -24,7 +19,7 @@
|
||||
<property name="beans">
|
||||
<map>
|
||||
<entry key="spring-ws:service=messagingContainer">
|
||||
<ref local="messagingContainer"/>
|
||||
<ref local="messagingReceiver"/>
|
||||
</entry>
|
||||
</map>
|
||||
</property>
|
||||
|
||||
Reference in New Issue
Block a user