Providing better separation between PollableSource and PollingSourceAdapter (work in progress).
This commit is contained in:
@@ -25,7 +25,6 @@ import org.springframework.integration.channel.MessageChannel;
|
||||
import org.springframework.integration.channel.RequestReplyTemplate;
|
||||
import org.springframework.integration.handler.MessageHandler;
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A source adapter that implements the {@link MessageHandler} interface. It may
|
||||
@@ -33,12 +32,10 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class MessageHandlingSourceAdapter implements SourceAdapter, MessageHandler, InitializingBean {
|
||||
public class MessageHandlingSourceAdapter extends AbstractSourceAdapter implements MessageHandler, InitializingBean {
|
||||
|
||||
private final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
private volatile MessageChannel channel;
|
||||
|
||||
private volatile RequestReplyTemplate requestReplyTemplate;
|
||||
|
||||
private volatile boolean expectReply = true;
|
||||
@@ -59,28 +56,9 @@ public class MessageHandlingSourceAdapter implements SourceAdapter, MessageHandl
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public MessageHandlingSourceAdapter(MessageChannel channel) {
|
||||
Assert.notNull(channel, "'channel' must not be null");
|
||||
this.channel = channel;
|
||||
super(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* No-arg constructor for configuration via setters. Note that upon
|
||||
* initialization, this adapter will throw an exception if a
|
||||
* {@link MessageChannel} has not been provided.
|
||||
*
|
||||
* @see #setChannel(MessageChannel)
|
||||
*/
|
||||
public MessageHandlingSourceAdapter() {
|
||||
}
|
||||
|
||||
|
||||
public void setChannel(MessageChannel channel) {
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
protected MessageChannel getChannel() {
|
||||
return this.channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether the handle method should be expected to return a reply.
|
||||
@@ -90,19 +68,11 @@ public class MessageHandlingSourceAdapter implements SourceAdapter, MessageHandl
|
||||
this.expectReply = expectReply;
|
||||
}
|
||||
|
||||
public void setSendTimeout(long sendTimeout) {
|
||||
this.sendTimeout = sendTimeout;
|
||||
}
|
||||
|
||||
public void setReceiveTimeout(long receiveTimeout) {
|
||||
this.receiveTimeout = receiveTimeout;
|
||||
}
|
||||
|
||||
public final void afterPropertiesSet() throws Exception {
|
||||
if (this.channel == null) {
|
||||
throw new ConfigurationException("The 'channel' property of '" + this.getClass().getName()
|
||||
+ "' must not be null.");
|
||||
}
|
||||
synchronized (this.lifecycleMonitor) {
|
||||
if (this.initialized) {
|
||||
return;
|
||||
@@ -122,7 +92,7 @@ public class MessageHandlingSourceAdapter implements SourceAdapter, MessageHandl
|
||||
}
|
||||
|
||||
private RequestReplyTemplate createRequestReplyTemplate() {
|
||||
RequestReplyTemplate template = new RequestReplyTemplate(this.channel);
|
||||
RequestReplyTemplate template = new RequestReplyTemplate(this.getChannel());
|
||||
template.setDefaultSendTimeout(this.sendTimeout);
|
||||
template.setDefaultReceiveTimeout(this.receiveTimeout);
|
||||
return template;
|
||||
@@ -138,9 +108,8 @@ public class MessageHandlingSourceAdapter implements SourceAdapter, MessageHandl
|
||||
}
|
||||
}
|
||||
if (!this.expectReply) {
|
||||
if (!this.channel.send(message, this.sendTimeout) && logger.isWarnEnabled()) {
|
||||
logger.warn("failed to send message to channel '" + this.channel + "' within timeout of "
|
||||
+ this.sendTimeout + " milliseconds");
|
||||
if (!this.sendToChannel(message) && logger.isWarnEnabled()) {
|
||||
logger.warn("failed to send message to channel within timeout of " + this.sendTimeout + " milliseconds");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.integration.adapter.config;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.ConfigurationException;
|
||||
import org.springframework.integration.adapter.PollingSourceAdapter;
|
||||
import org.springframework.integration.message.PollableSource;
|
||||
import org.springframework.integration.scheduling.PollingSchedule;
|
||||
import org.springframework.integration.scheduling.Schedule;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Base parser for polling adapters.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public abstract class AbstractPollingSourceAdapterParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
protected final Class<?> getBeanClass(Element element) {
|
||||
return PollingSourceAdapter.class;
|
||||
}
|
||||
|
||||
protected boolean shouldGenerateId() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean shouldGenerateIdAsFallback() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean isEligibleAttribute(String attributeName) {
|
||||
return !ID_ATTRIBUTE.equals(attributeName) && !"channel".equals(attributeName) && !"poll-period".equals(attributeName)
|
||||
&& !shouldSkipAttribute(attributeName);
|
||||
}
|
||||
|
||||
protected boolean shouldSkipAttribute(String attributeName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void doPostProcess(BeanDefinitionBuilder beanDefinition, Element element) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
String channel = element.getAttribute("channel");
|
||||
if (!StringUtils.hasText(channel)) {
|
||||
throw new ConfigurationException("'channel' is required");
|
||||
}
|
||||
SourceParser sourceParser = new SourceParser();
|
||||
sourceParser.parse(element, parserContext);
|
||||
builder.addConstructorArgReference(sourceParser.generatedName);
|
||||
builder.addConstructorArgReference(channel);
|
||||
builder.addConstructorArgValue(this.parseSchedule(element));
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override this method to control the creation of the {@link Schedule}. The default
|
||||
* implementation creates a {@link PollingSchedule} instance based on the provided "poll-period" attribute.
|
||||
*/
|
||||
protected Schedule parseSchedule(Element element) {
|
||||
String period = element.getAttribute("poll-period");
|
||||
if (!StringUtils.hasText(period)) {
|
||||
throw new ConfigurationException("'poll-period' is required");
|
||||
}
|
||||
PollingSchedule schedule = new PollingSchedule(Long.valueOf(period));
|
||||
return schedule;
|
||||
}
|
||||
|
||||
protected abstract Class<? extends PollableSource<?>> getSourceBeanClass(Element element);
|
||||
|
||||
|
||||
private class SourceParser extends AbstractSimpleBeanDefinitionParser {
|
||||
|
||||
private String generatedName;
|
||||
|
||||
@Override
|
||||
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
|
||||
throws BeanDefinitionStoreException {
|
||||
this.generatedName = parserContext.getReaderContext().generateBeanName(definition);
|
||||
return this.generatedName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return getSourceBeanClass(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEligibleAttribute(String attributeName) {
|
||||
return AbstractPollingSourceAdapterParser.this.isEligibleAttribute(attributeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void postProcess(BeanDefinitionBuilder beanDefinition, Element element) {
|
||||
doPostProcess(beanDefinition, element);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -50,7 +50,7 @@ public abstract class AbstractRequestReplySourceAdapterParser extends AbstractSi
|
||||
|
||||
@Override
|
||||
protected boolean isEligibleAttribute(String attributeName) {
|
||||
return !attributeName.equals("name") && super.isEligibleAttribute(attributeName);
|
||||
return !attributeName.equals("name") && !attributeName.equals("channel") && super.isEligibleAttribute(attributeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,7 +59,7 @@ public abstract class AbstractRequestReplySourceAdapterParser extends AbstractSi
|
||||
if (!StringUtils.hasText(channelRef)) {
|
||||
throw new ConfigurationException("a 'channel' reference is required");
|
||||
}
|
||||
builder.addPropertyReference("channel", channelRef);
|
||||
builder.addConstructorArgReference(channelRef);
|
||||
builder.addPropertyValue("expectReply", element.getAttribute("expect-reply").equals("true"));
|
||||
String sendTimeout = element.getAttribute("send-timeout");
|
||||
if (StringUtils.hasText(sendTimeout)) {
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<xsd:attribute name="local-working-directory" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="remote-working-directory" type="xsd:string" use="optional"/>
|
||||
<xsd:attribute name="channel" type="xsd:string" use="required"/>
|
||||
<xsd:attribute name="period" type="xsd:long" use="required"/>
|
||||
<xsd:attribute name="poll-period" type="xsd:long" use="required"/>
|
||||
<xsd:attribute name="text-based" type="xsd:boolean" use="optional"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
@@ -22,22 +22,27 @@ import java.util.List;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.integration.adapter.AbstractSourceAdapter;
|
||||
import org.springframework.integration.channel.MessageChannel;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* A source adapter for passing Spring
|
||||
* A message source for passing Spring
|
||||
* {@link ApplicationEvent ApplicationEvents} within messages.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class ApplicationEventSourceAdapter extends AbstractSourceAdapter<ApplicationEvent> implements
|
||||
ApplicationListener {
|
||||
public class ApplicationEventSourceAdapter extends AbstractSourceAdapter implements ApplicationListener {
|
||||
|
||||
private List<Class<? extends ApplicationEvent>> eventTypes = new ArrayList<Class<? extends ApplicationEvent>>();
|
||||
|
||||
|
||||
public ApplicationEventSourceAdapter(MessageChannel channel) {
|
||||
super(channel);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the list of event types (classes that extend ApplicationEvent) that
|
||||
* this adapter should send to the message channel. By default, all event
|
||||
@@ -61,8 +66,8 @@ public class ApplicationEventSourceAdapter extends AbstractSourceAdapter<Applica
|
||||
}
|
||||
}
|
||||
|
||||
private void sendMessage(ApplicationEvent event) {
|
||||
this.sendToChannel(new GenericMessage<ApplicationEvent>(event));
|
||||
private boolean sendMessage(ApplicationEvent event) {
|
||||
return this.sendToChannel(new GenericMessage<ApplicationEvent>(event));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FilenameFilter;
|
||||
|
||||
import org.springframework.integration.adapter.PollingSourceAdapter;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.MessagingException;
|
||||
import org.springframework.integration.message.PollableSource;
|
||||
@@ -31,7 +31,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class FileSourceAdapter extends PollingSourceAdapter<Object> implements PollableSource<Object> {
|
||||
public class FileSource implements PollableSource<Object>, InitializingBean {
|
||||
|
||||
private final File directory;
|
||||
|
||||
@@ -46,7 +46,7 @@ public class FileSourceAdapter extends PollingSourceAdapter<Object> implements P
|
||||
private volatile FilenameFilter filenameFilter;
|
||||
|
||||
|
||||
public FileSourceAdapter(File directory) {
|
||||
public FileSource(File directory) {
|
||||
Assert.notNull(directory, "directory must not be null");
|
||||
this.directory = directory;
|
||||
}
|
||||
@@ -72,9 +72,7 @@ public class FileSourceAdapter extends PollingSourceAdapter<Object> implements P
|
||||
this.fileNameGenerator = fileNameGenerator;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
this.setSource(this);
|
||||
public void afterPropertiesSet() {
|
||||
if (this.isTextBased()) {
|
||||
this.mapper = new TextFileMapper(this.directory);
|
||||
}
|
||||
@@ -84,7 +82,6 @@ public class FileSourceAdapter extends PollingSourceAdapter<Object> implements P
|
||||
if (this.fileNameGenerator != null) {
|
||||
this.mapper.setFileNameGenerator(this.fileNameGenerator);
|
||||
}
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
public Message<Object> poll() {
|
||||
@@ -19,35 +19,30 @@ package org.springframework.integration.adapter.file.config;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.integration.adapter.file.FileSourceAdapter;
|
||||
import org.springframework.integration.adapter.config.AbstractPollingSourceAdapterParser;
|
||||
import org.springframework.integration.adapter.file.FileSource;
|
||||
import org.springframework.integration.message.PollableSource;
|
||||
|
||||
/**
|
||||
* Parser for the <file-source/> element.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class FileSourceAdapterParser extends AbstractSingleBeanDefinitionParser {
|
||||
public class FileSourceAdapterParser extends AbstractPollingSourceAdapterParser {
|
||||
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return FileSourceAdapter.class;
|
||||
@Override
|
||||
protected Class<? extends PollableSource<?>> getSourceBeanClass(Element element) {
|
||||
return FileSource.class;
|
||||
}
|
||||
|
||||
protected boolean shouldGenerateId() {
|
||||
return false;
|
||||
@Override
|
||||
protected boolean shouldSkipAttribute(String attributeName) {
|
||||
return "directory".equals(attributeName);
|
||||
}
|
||||
|
||||
protected boolean shouldGenerateIdAsFallback() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void doParse(Element element, BeanDefinitionBuilder builder) {
|
||||
String directory = element.getAttribute("directory");
|
||||
String channel = element.getAttribute("channel");
|
||||
String pollPeriod = element.getAttribute("poll-period");
|
||||
builder.addConstructorArgValue(directory);
|
||||
builder.addPropertyReference("channel", channel);
|
||||
builder.addPropertyValue("period", pollPeriod);
|
||||
@Override
|
||||
protected void doPostProcess(BeanDefinitionBuilder builder, Element element) {
|
||||
builder.addConstructorArgValue(element.getAttribute("directory"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,11 +28,11 @@ import org.apache.commons.net.ftp.FTP;
|
||||
import org.apache.commons.net.ftp.FTPClient;
|
||||
import org.apache.commons.net.ftp.FTPFile;
|
||||
|
||||
import org.springframework.integration.adapter.PollingSourceAdapter;
|
||||
import org.springframework.integration.adapter.file.ByteArrayFileMapper;
|
||||
import org.springframework.integration.adapter.file.FileNameGenerator;
|
||||
import org.springframework.integration.adapter.file.TextFileMapper;
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.MessageDeliveryAware;
|
||||
import org.springframework.integration.message.MessageMapper;
|
||||
import org.springframework.integration.message.MessagingException;
|
||||
import org.springframework.integration.message.PollableSource;
|
||||
@@ -45,7 +45,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Marius Bogoevici
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class FtpSourceAdapter extends PollingSourceAdapter<Object> implements PollableSource<Object> {
|
||||
public class FtpSource implements PollableSource<Object>, MessageDeliveryAware {
|
||||
|
||||
private final static String DEFAULT_HOST = "localhost";
|
||||
|
||||
@@ -104,37 +104,22 @@ public class FtpSourceAdapter extends PollingSourceAdapter<Object> implements Po
|
||||
}
|
||||
|
||||
public boolean isTextBased() {
|
||||
return textBased;
|
||||
return this.textBased;
|
||||
}
|
||||
|
||||
public void setTextBased(boolean textBased) {
|
||||
this.textBased = textBased;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
this.setSource(this);
|
||||
public void afterPropertiesSet() {
|
||||
if (this.isTextBased()) {
|
||||
this.mapper = new TextFileMapper(this.localWorkingDirectory);
|
||||
}
|
||||
else {
|
||||
this.mapper = new ByteArrayFileMapper(this.localWorkingDirectory);
|
||||
}
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSend(Message<Object> message) {
|
||||
String filename = message.getHeader().getProperty(FileNameGenerator.FILENAME_PROPERTY_KEY);
|
||||
if (StringUtils.hasText(filename)) {
|
||||
this.directoryContentManager.fileProcessed(filename);
|
||||
}
|
||||
else if (this.logger.isWarnEnabled()) {
|
||||
logger.warn("No filename in Message header, cannot send notification of processing.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public final Message<Object> poll() {
|
||||
try {
|
||||
this.establishConnection();
|
||||
@@ -195,4 +180,20 @@ public class FtpSourceAdapter extends PollingSourceAdapter<Object> implements Po
|
||||
}
|
||||
}
|
||||
|
||||
public void onSend(Message<?> message) {
|
||||
String filename = message.getHeader().getProperty(FileNameGenerator.FILENAME_PROPERTY_KEY);
|
||||
if (StringUtils.hasText(filename)) {
|
||||
this.directoryContentManager.fileProcessed(filename);
|
||||
}
|
||||
else if (this.logger.isWarnEnabled()) {
|
||||
logger.warn("No filename in Message header, cannot send notification of processing.");
|
||||
}
|
||||
}
|
||||
|
||||
public void onFailure(MessagingException exception) {
|
||||
if (this.logger.isWarnEnabled()) {
|
||||
logger.warn("FtpSource received failure notifcation", exception);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,45 +18,21 @@ package org.springframework.integration.adapter.ftp.config;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.core.Conventions;
|
||||
import org.springframework.integration.adapter.ftp.FtpSourceAdapter;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.integration.adapter.config.AbstractPollingSourceAdapterParser;
|
||||
import org.springframework.integration.adapter.ftp.FtpSource;
|
||||
import org.springframework.integration.message.PollableSource;
|
||||
|
||||
/**
|
||||
* Parser for the <ftp-source/> element.
|
||||
*
|
||||
* @author Marius Bogoevici
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class FtpSourceAdapterParser extends AbstractSimpleBeanDefinitionParser {
|
||||
|
||||
private static final String CHANNEL_ATTRIBUTE = "channel";
|
||||
|
||||
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return FtpSourceAdapter.class;
|
||||
}
|
||||
|
||||
protected boolean shouldGenerateId() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean shouldGenerateIdAsFallback() {
|
||||
return true;
|
||||
}
|
||||
public class FtpSourceAdapterParser extends AbstractPollingSourceAdapterParser {
|
||||
|
||||
@Override
|
||||
protected boolean isEligibleAttribute(String attributeName) {
|
||||
return !CHANNEL_ATTRIBUTE.equals(attributeName) && super.isEligibleAttribute(attributeName);
|
||||
}
|
||||
|
||||
protected void postProcess(BeanDefinitionBuilder beanDefinition, Element element) {
|
||||
String channelRef = element.getAttribute(CHANNEL_ATTRIBUTE);
|
||||
if (StringUtils.hasText(channelRef)) {
|
||||
beanDefinition.addPropertyReference(
|
||||
Conventions.attributeNameToPropertyName(CHANNEL_ATTRIBUTE), channelRef);
|
||||
}
|
||||
protected Class<? extends PollableSource<?>> getSourceBeanClass(Element element) {
|
||||
return FtpSource.class;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -64,13 +64,8 @@ public class HttpInvokerSourceAdapter extends MessageHandlingSourceAdapter imple
|
||||
private volatile HttpInvokerServiceExporter exporter;
|
||||
|
||||
|
||||
public HttpInvokerSourceAdapter() {
|
||||
super();
|
||||
}
|
||||
|
||||
public HttpInvokerSourceAdapter(MessageChannel channel) {
|
||||
this();
|
||||
this.setChannel(channel);
|
||||
super(channel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -46,13 +46,16 @@ public class JmsPollableSource extends AbstractJmsTemplateBasedAdapter implement
|
||||
super(connectionFactory, destinationName);
|
||||
}
|
||||
|
||||
public JmsPollableSource() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
public Message<Object> poll() {
|
||||
return new GenericMessage<Object>(this.getJmsTemplate().receiveAndConvert());
|
||||
Object receivedObject = this.getJmsTemplate().receiveAndConvert();
|
||||
if (receivedObject == null) {
|
||||
return null;
|
||||
}
|
||||
if (receivedObject instanceof Message) {
|
||||
return (Message<Object>) receivedObject;
|
||||
}
|
||||
return new GenericMessage<Object>(receivedObject);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.integration.adapter.jms;
|
||||
|
||||
import javax.jms.ConnectionFactory;
|
||||
import javax.jms.Destination;
|
||||
|
||||
import org.springframework.integration.adapter.PollingSourceAdapter;
|
||||
import org.springframework.jms.core.JmsTemplate;
|
||||
|
||||
/**
|
||||
* A convenience adapter that wraps a {@link JmsPollableSource}.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class JmsPollingSourceAdapter extends PollingSourceAdapter<Object> {
|
||||
|
||||
public JmsPollingSourceAdapter(JmsTemplate jmsTemplate) {
|
||||
super(new JmsPollableSource(jmsTemplate));
|
||||
}
|
||||
|
||||
public JmsPollingSourceAdapter(ConnectionFactory connectionFactory, Destination destination) {
|
||||
super(new JmsPollableSource(connectionFactory, destination));
|
||||
}
|
||||
|
||||
public JmsPollingSourceAdapter(ConnectionFactory connectionFactory, String destinationName) {
|
||||
super(new JmsPollableSource(connectionFactory, destinationName));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
* Copyright 2002-2008 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.
|
||||
@@ -21,10 +21,16 @@ import javax.jms.Session;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.integration.adapter.PollingSourceAdapter;
|
||||
import org.springframework.integration.adapter.jms.JmsMessageDrivenSourceAdapter;
|
||||
import org.springframework.integration.adapter.jms.JmsPollingSourceAdapter;
|
||||
import org.springframework.integration.adapter.jms.JmsPollableSource;
|
||||
import org.springframework.integration.scheduling.PollingSchedule;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -32,12 +38,10 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class JmsSourceAdapterParser extends AbstractSingleBeanDefinitionParser {
|
||||
public class JmsSourceAdapterParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
private static final String POLL_PERIOD_ATTRIBUTE = "poll-period";
|
||||
|
||||
private static final String POLL_PERIOD_PROPERTY = "period";
|
||||
|
||||
private static final String MESSAGE_CONVERTER_ATTRIBUTE = "message-converter";
|
||||
|
||||
private static final String MESSAGE_CONVERTER_PROPERTY = "messageConverter";
|
||||
@@ -53,13 +57,6 @@ public class JmsSourceAdapterParser extends AbstractSingleBeanDefinitionParser {
|
||||
private static final String ACKNOWLEDGE_TRANSACTED = "transacted";
|
||||
|
||||
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
if (StringUtils.hasText(element.getAttribute(POLL_PERIOD_ATTRIBUTE))) {
|
||||
return JmsPollingSourceAdapter.class;
|
||||
}
|
||||
return JmsMessageDrivenSourceAdapter.class;
|
||||
}
|
||||
|
||||
protected boolean shouldGenerateId() {
|
||||
return false;
|
||||
}
|
||||
@@ -68,31 +65,26 @@ public class JmsSourceAdapterParser extends AbstractSingleBeanDefinitionParser {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void doParse(Element element, BeanDefinitionBuilder builder) {
|
||||
if (builder.getBeanDefinition().getBeanClass().equals(JmsPollingSourceAdapter.class)) {
|
||||
parsePollingSourceAdapter(element, builder);
|
||||
@Override
|
||||
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
|
||||
if (StringUtils.hasText(element.getAttribute(POLL_PERIOD_ATTRIBUTE))) {
|
||||
return parsePollingSourceAdapter(element, parserContext);
|
||||
}
|
||||
else {
|
||||
parseMessageDrivenSourceAdapter(element, builder);
|
||||
}
|
||||
String channel = element.getAttribute(JmsAdapterParserUtils.CHANNEL_ATTRIBUTE);
|
||||
builder.addPropertyReference(JmsAdapterParserUtils.CHANNEL_PROPERTY, channel);
|
||||
return parseMessageDrivenSourceAdapter(element, parserContext);
|
||||
}
|
||||
|
||||
private void parsePollingSourceAdapter(Element element, BeanDefinitionBuilder builder) {
|
||||
private AbstractBeanDefinition parsePollingSourceAdapter(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder sourceBuilder = BeanDefinitionBuilder.genericBeanDefinition(JmsPollableSource.class);
|
||||
String pollPeriod = element.getAttribute(POLL_PERIOD_ATTRIBUTE);
|
||||
if (!StringUtils.hasText(pollPeriod)) {
|
||||
throw new BeanCreationException("'" + POLL_PERIOD_ATTRIBUTE +
|
||||
"' is required for a " + JmsPollingSourceAdapter.class.getSimpleName());
|
||||
throw new BeanCreationException("'" + POLL_PERIOD_ATTRIBUTE + "' is required for a polling JMS adapter");
|
||||
}
|
||||
if (StringUtils.hasText(element.getAttribute(MESSAGE_CONVERTER_ATTRIBUTE))) {
|
||||
throw new BeanCreationException(
|
||||
"The '" + MESSAGE_CONVERTER_ATTRIBUTE + "' attribute is not supported for a " +
|
||||
JmsPollingSourceAdapter.class.getSimpleName() + ". Consider providing a '" +
|
||||
JmsAdapterParserUtils.JMS_TEMPLATE_ATTRIBUTE +
|
||||
"The '" + MESSAGE_CONVERTER_ATTRIBUTE + "' attribute is not supported for a polling JMS adapter. " +
|
||||
". Consider providing a '" + JmsAdapterParserUtils.JMS_TEMPLATE_ATTRIBUTE +
|
||||
"' reference where the template contains a 'messageConverter' property instead.");
|
||||
}
|
||||
builder.addPropertyValue(POLL_PERIOD_PROPERTY, pollPeriod);
|
||||
String jmsTemplate = element.getAttribute(JmsAdapterParserUtils.JMS_TEMPLATE_ATTRIBUTE);
|
||||
String destination = element.getAttribute(JmsAdapterParserUtils.DESTINATION_ATTRIBUTE);
|
||||
String destinationName = element.getAttribute(JmsAdapterParserUtils.DESTINATION_NAME_ATTRIBUTE);
|
||||
@@ -106,26 +98,37 @@ public class JmsSourceAdapterParser extends AbstractSingleBeanDefinitionParser {
|
||||
"', '" + JmsAdapterParserUtils.DESTINATION_ATTRIBUTE + "', or '" +
|
||||
JmsAdapterParserUtils.DESTINATION_NAME_ATTRIBUTE + "' should be provided.");
|
||||
}
|
||||
builder.addConstructorArgReference(jmsTemplate);
|
||||
sourceBuilder.addConstructorArgReference(jmsTemplate);
|
||||
}
|
||||
else if (StringUtils.hasText(destination) || StringUtils.hasText(destinationName)) {
|
||||
builder.addConstructorArgReference(JmsAdapterParserUtils.determineConnectionFactoryBeanName(element));
|
||||
sourceBuilder.addConstructorArgReference(JmsAdapterParserUtils.determineConnectionFactoryBeanName(element));
|
||||
if (StringUtils.hasText(destination)) {
|
||||
builder.addConstructorArgReference(destination);
|
||||
sourceBuilder.addConstructorArgReference(destination);
|
||||
}
|
||||
else if (StringUtils.hasText(destinationName)) {
|
||||
builder.addConstructorArgValue(destinationName);
|
||||
sourceBuilder.addConstructorArgValue(destinationName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new BeanCreationException("either a '" + JmsAdapterParserUtils.JMS_TEMPLATE_ATTRIBUTE +
|
||||
"' or one of '" + JmsAdapterParserUtils.DESTINATION_ATTRIBUTE + "' or '" +
|
||||
JmsAdapterParserUtils.DESTINATION_NAME_ATTRIBUTE + "' attributes " +
|
||||
"must be provided for a " + JmsPollingSourceAdapter.class.getSimpleName());
|
||||
throw new BeanCreationException("either a '" + JmsAdapterParserUtils.JMS_TEMPLATE_ATTRIBUTE + "' or one of '" +
|
||||
JmsAdapterParserUtils.DESTINATION_ATTRIBUTE + "' or '" + JmsAdapterParserUtils.DESTINATION_NAME_ATTRIBUTE +
|
||||
"' attributes must be provided for a polling JMS adapter");
|
||||
}
|
||||
String channel = element.getAttribute(JmsAdapterParserUtils.CHANNEL_ATTRIBUTE);
|
||||
PollingSchedule schedule = new PollingSchedule(Long.valueOf(pollPeriod));
|
||||
BeanDefinition sourceDef = sourceBuilder.getBeanDefinition();
|
||||
String sourceBeanName = parserContext.getReaderContext().generateBeanName(sourceDef);
|
||||
BeanComponentDefinition sourceComponent = new BeanComponentDefinition(sourceDef, sourceBeanName);
|
||||
parserContext.registerBeanComponent(sourceComponent);
|
||||
BeanDefinitionBuilder adapterBuilder = BeanDefinitionBuilder.genericBeanDefinition(PollingSourceAdapter.class);
|
||||
adapterBuilder.addConstructorArgReference(sourceBeanName);
|
||||
adapterBuilder.addConstructorArgReference(channel);
|
||||
adapterBuilder.addConstructorArgValue(schedule);
|
||||
return adapterBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
private void parseMessageDrivenSourceAdapter(Element element, BeanDefinitionBuilder builder) {
|
||||
private AbstractBeanDefinition parseMessageDrivenSourceAdapter(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(JmsMessageDrivenSourceAdapter.class);
|
||||
String destination = element.getAttribute(JmsAdapterParserUtils.DESTINATION_ATTRIBUTE);
|
||||
String destinationName = element.getAttribute(JmsAdapterParserUtils.DESTINATION_NAME_ATTRIBUTE);
|
||||
String messageConverter = element.getAttribute(MESSAGE_CONVERTER_ATTRIBUTE);
|
||||
@@ -161,6 +164,9 @@ public class JmsSourceAdapterParser extends AbstractSingleBeanDefinitionParser {
|
||||
builder.addPropertyValue("sessionAcknowledgeMode", acknowledgeMode);
|
||||
}
|
||||
}
|
||||
String channel = element.getAttribute(JmsAdapterParserUtils.CHANNEL_ATTRIBUTE);
|
||||
builder.addPropertyReference(JmsAdapterParserUtils.CHANNEL_PROPERTY, channel);
|
||||
return builder.getBeanDefinition();
|
||||
}
|
||||
|
||||
private Integer parseAcknowledgeMode(Element element) {
|
||||
|
||||
@@ -43,13 +43,8 @@ public class RmiSourceAdapter extends MessageHandlingSourceAdapter {
|
||||
private volatile RemoteInvocationExecutor remoteInvocationExecutor;
|
||||
|
||||
|
||||
public RmiSourceAdapter() {
|
||||
super();
|
||||
}
|
||||
|
||||
public RmiSourceAdapter(MessageChannel channel) {
|
||||
this();
|
||||
this.setChannel(channel);
|
||||
super(channel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-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.integration.adapter.stream;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.springframework.integration.adapter.PollingSourceAdapter;
|
||||
|
||||
/**
|
||||
* A polling source adapter that wraps a {@link ByteStreamSource}.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class ByteStreamSourceAdapter extends PollingSourceAdapter<byte[]> {
|
||||
|
||||
public ByteStreamSourceAdapter(InputStream stream) {
|
||||
super(new ByteStreamSource(stream));
|
||||
}
|
||||
|
||||
|
||||
public void setBytesPerMessage(int bytesPerMessage) {
|
||||
((ByteStreamSource) this.getSource()).setBytesPerMessage(bytesPerMessage);
|
||||
}
|
||||
|
||||
public void setShouldTruncate(boolean shouldTruncate) {
|
||||
((ByteStreamSource) this.getSource()).setShouldTruncate(shouldTruncate);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,8 +18,10 @@ package org.springframework.integration.adapter.stream;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
|
||||
import org.springframework.integration.channel.MessageChannel;
|
||||
import org.springframework.integration.message.MessagingException;
|
||||
import org.springframework.integration.message.PollableSource;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
@@ -71,4 +73,9 @@ public class CharacterStreamSource implements PollableSource<String> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static final CharacterStreamSource stdin() {
|
||||
return new CharacterStreamSource(new InputStreamReader(System.in));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.integration.adapter.stream;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
|
||||
import org.springframework.integration.adapter.PollingSourceAdapter;
|
||||
import org.springframework.integration.channel.MessageChannel;
|
||||
|
||||
/**
|
||||
* A polling source adapter that wraps a {@link CharacterStreamSource}.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class CharacterStreamSourceAdapter extends PollingSourceAdapter<String> {
|
||||
|
||||
public CharacterStreamSourceAdapter(Reader reader) {
|
||||
super(new CharacterStreamSource(reader));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Factory method that creates an adapter for stdin (System.in).
|
||||
*/
|
||||
public static CharacterStreamSourceAdapter stdinAdapter(MessageChannel channel) {
|
||||
CharacterStreamSourceAdapter adapter =
|
||||
new CharacterStreamSourceAdapter(new InputStreamReader(System.in));
|
||||
adapter.setChannel(channel);
|
||||
return adapter;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user