INT-1363 JmsDestinationPollingSource no longer extends from AbstractJmsTemplateBasedAdapter

This commit is contained in:
Mark Fisher
2010-09-13 17:54:50 -04:00
parent 44b6490cda
commit bf0da16684
3 changed files with 56 additions and 249 deletions

View File

@@ -1,218 +0,0 @@
/*
* Copyright 2002-2010 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.jms;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import org.springframework.integration.context.IntegrationObjectSupport;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.SimpleMessageConverter;
import org.springframework.jms.support.destination.DestinationResolver;
import org.springframework.util.Assert;
/**
* Base class for adapters that delegate to a {@link JmsTemplate}.
*
* @author Mark Fisher
* @author Oleg Zhurakousky
*/
public abstract class AbstractJmsTemplateBasedAdapter extends IntegrationObjectSupport {
private volatile ConnectionFactory connectionFactory;
private volatile Destination destination;
private volatile String destinationName;
private volatile boolean pubSubDomain;
private volatile DestinationResolver destinationResolver;
private volatile int deliveryMode = javax.jms.Message.DEFAULT_DELIVERY_MODE;
private volatile long timeToLive = javax.jms.Message.DEFAULT_TIME_TO_LIVE;
private volatile int priority = javax.jms.Message.DEFAULT_PRIORITY;
private volatile boolean explicitQosEnabled;
private volatile JmsTemplate jmsTemplate;
private volatile MessageConverter messageConverter;
private volatile JmsHeaderMapper headerMapper = new DefaultJmsHeaderMapper();
private volatile boolean initialized;
private final Object initializationMonitor = new Object();
public AbstractJmsTemplateBasedAdapter(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
public AbstractJmsTemplateBasedAdapter(ConnectionFactory connectionFactory, Destination destination) {
this.connectionFactory = connectionFactory;
this.destination = destination;
}
public AbstractJmsTemplateBasedAdapter(ConnectionFactory connectionFactory, String destinationName) {
this.connectionFactory = connectionFactory;
this.destinationName = destinationName;
}
/**
* No-arg constructor provided for convenience when configuring with
* setters. Note that the initialization callback will validate.
*/
public AbstractJmsTemplateBasedAdapter() {
}
public void setConnectionFactory(ConnectionFactory connectionFactory) {
this.connectionFactory = connectionFactory;
}
public void setDestination(Destination destination) {
this.destination = destination;
}
Destination getDestination() {
return this.destination;
}
public void setDestinationName(String destinationName) {
this.destinationName = destinationName;
}
String getDestinationName() {
return this.destinationName;
}
public void setPubSubDomain(boolean pubSubDomain) {
this.pubSubDomain = pubSubDomain;
}
/**
* Provide a {@link MessageConverter} strategy to use for converting
* between Spring Integration Messages and JMS Messages.
* <p>
* The default is a {@link DefaultMessageConverter} that delegates to
* a {@link SimpleMessageConverter}.
*/
public void setMessageConverter(MessageConverter messageConverter) {
this.messageConverter = messageConverter;
}
public void setDestinationResolver(DestinationResolver destinationResolver) {
this.destinationResolver = destinationResolver;
}
public void setHeaderMapper(JmsHeaderMapper headerMapper) {
this.headerMapper = headerMapper;
}
JmsHeaderMapper getHeaderMapper() {
return this.headerMapper;
}
/**
* @see JmsTemplate#setExplicitQosEnabled(boolean)
*/
public void setExplicitQosEnabled(boolean explicitQosEnabled) {
this.explicitQosEnabled = explicitQosEnabled;
}
/**
* @see JmsTemplate#setTimeToLive(long)
*/
public void setTimeToLive(long timeToLive) {
this.timeToLive = timeToLive;
}
/**
* @see JmsTemplate#setDeliveryMode(int)
*/
public void setDeliveryMode(int deliveryMode) {
this.deliveryMode = deliveryMode;
}
/**
* @see JmsTemplate#setDeliveryPersistent(boolean)
*/
public void setDeliveryPersistent(boolean deliveryPersistent) {
this.deliveryMode = deliveryPersistent ?
DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT;
}
/**
* @see JmsTemplate#setPriority(int)
*/
public void setPriority(int priority) {
this.priority = priority;
}
protected JmsTemplate getJmsTemplate() {
if (this.jmsTemplate == null) {
this.afterPropertiesSet();
}
return this.jmsTemplate;
}
public void onInit() {
synchronized (this.initializationMonitor) {
if (this.initialized) {
return;
}
if (this.jmsTemplate == null) {
this.jmsTemplate = this.createJmsTemplate();
}
this.initialized = true;
}
}
private JmsTemplate createJmsTemplate() {
Assert.isTrue(this.connectionFactory != null
&& (this.destination != null || this.destinationName != null),
"Either a 'jmsTemplate' or *both* 'connectionFactory' and"
+ " 'destination' (or 'destination-name') are required.");
JmsTemplate jmsTemplate = new JmsTemplate();
jmsTemplate.setConnectionFactory(this.connectionFactory);
if (this.destination != null) {
jmsTemplate.setDefaultDestination(this.destination);
}
else {
jmsTemplate.setDefaultDestinationName(this.destinationName);
jmsTemplate.setPubSubDomain(this.pubSubDomain);
}
if (this.destinationResolver != null) {
jmsTemplate.setDestinationResolver(this.destinationResolver);
}
jmsTemplate.setExplicitQosEnabled(this.explicitQosEnabled);
jmsTemplate.setTimeToLive(this.timeToLive);
jmsTemplate.setPriority(this.priority);
jmsTemplate.setDeliveryMode(this.deliveryMode);
if (this.messageConverter != null) {
jmsTemplate.setMessageConverter(this.messageConverter);
}
return jmsTemplate;
}
}

View File

@@ -18,15 +18,16 @@ package org.springframework.integration.jms;
import java.util.Map;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import org.springframework.integration.Message;
import org.springframework.integration.MessagingException;
import org.springframework.integration.context.IntegrationObjectSupport;
import org.springframework.integration.core.MessageSource;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.util.Assert;
/**
* A source for receiving JMS Messages with a polling listener. This source is
@@ -37,24 +38,35 @@ import org.springframework.jms.support.converter.MessageConverter;
* @author Mark Fisher
* @author Oleg Zhurakousky
*/
public class JmsDestinationPollingSource extends AbstractJmsTemplateBasedAdapter implements MessageSource<Object> {
public class JmsDestinationPollingSource extends IntegrationObjectSupport implements MessageSource<Object> {
private final JmsTemplate jmsTemplate;
private volatile Destination destination;
private volatile String destinationName;
private volatile String messageSelector;
private volatile JmsHeaderMapper headerMapper = new DefaultJmsHeaderMapper();
public JmsDestinationPollingSource(JmsTemplate jmsTemplate) {
super(jmsTemplate);
}
public JmsDestinationPollingSource(ConnectionFactory connectionFactory, Destination destination) {
super(connectionFactory, destination);
}
public JmsDestinationPollingSource(ConnectionFactory connectionFactory, String destinationName) {
super(connectionFactory, destinationName);
this.jmsTemplate = jmsTemplate;
}
public void setDestination(Destination destination) {
Assert.isNull(this.destinationName, "The 'destination' and 'destinationName' properties are mutually exclusive.");
this.destination = destination;
}
public void setDestinationName(String destinationName) {
Assert.isNull(this.destination, "The 'destination' and 'destinationName' properties are mutually exclusive.");
this.destinationName = destinationName;
}
@Override
public String getComponentType() {
return "jms:inbound-channel-adapter";
}
@@ -65,7 +77,11 @@ public class JmsDestinationPollingSource extends AbstractJmsTemplateBasedAdapter
public void setMessageSelector(String messageSelector) {
this.messageSelector = messageSelector;
}
public void setHeaderMapper(JmsHeaderMapper headerMapper) {
this.headerMapper = headerMapper;
}
/**
* Will receive a JMS {@link javax.jms.Message} converting and returning it as
* a Spring Integration {@link Message}. This method will also use the current
@@ -74,15 +90,14 @@ public class JmsDestinationPollingSource extends AbstractJmsTemplateBasedAdapter
@SuppressWarnings("unchecked")
public Message<Object> receive() {
Message<Object> convertedMessage = null;
// receive JMS Message
javax.jms.Message jmsMessage = this.getJmsTemplate().receiveSelected(this.messageSelector);
javax.jms.Message jmsMessage = this.doReceiveJmsMessage();
if (jmsMessage == null) {
return null;
}
try {
// Map headers
Map<String, Object> mappedHeaders = (Map<String, Object>) this.getHeaderMapper().toHeaders(jmsMessage);
MessageConverter converter = this.getJmsTemplate().getMessageConverter();
Map<String, Object> mappedHeaders = (Map<String, Object>) this.headerMapper.toHeaders(jmsMessage);
MessageConverter converter = this.jmsTemplate.getMessageConverter();
Object convertedObject = converter.fromMessage(jmsMessage);
MessageBuilder<Object> builder = (convertedObject instanceof Message)
? MessageBuilder.fromMessage((Message<Object>) convertedObject) : MessageBuilder.withPayload(convertedObject);
@@ -94,4 +109,18 @@ public class JmsDestinationPollingSource extends AbstractJmsTemplateBasedAdapter
return convertedMessage;
}
private javax.jms.Message doReceiveJmsMessage() {
javax.jms.Message jmsMessage = null;
if (this.destination != null) {
jmsMessage = this.jmsTemplate.receiveSelected(this.destination, this.messageSelector);
}
else if (this.destinationName != null) {
jmsMessage = this.jmsTemplate.receiveSelected(this.destinationName, this.messageSelector);
}
else {
jmsMessage = this.jmsTemplate.receiveSelected(this.messageSelector);
}
return jmsMessage;
}
}

View File

@@ -45,41 +45,39 @@ public class JmsInboundChannelAdapterParser extends AbstractPollingInboundChanne
@Override
protected String parseSource(Element element, ParserContext parserContext) {
Object source = parserContext.extractSource(element);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(
"org.springframework.integration.jms.JmsDestinationPollingSource");
String componentName = this.resolveId(element, builder.getBeanDefinition(), parserContext);
if (StringUtils.hasText(componentName)){
if (StringUtils.hasText(componentName)) {
builder.addPropertyValue("componentName", componentName);
}
String jmsTemplate = element.getAttribute(JmsAdapterParserUtils.JMS_TEMPLATE_ATTRIBUTE);
String destination = element.getAttribute(JmsAdapterParserUtils.DESTINATION_ATTRIBUTE);
String destinationName = element.getAttribute(JmsAdapterParserUtils.DESTINATION_NAME_ATTRIBUTE);
String pubSubDomain = element.getAttribute(JmsAdapterParserUtils.PUB_SUB_DOMAIN_ATTRIBUTE);
String headerMapper = element.getAttribute(JmsAdapterParserUtils.HEADER_MAPPER_ATTRIBUTE);
boolean hasJmsTemplate = StringUtils.hasText(jmsTemplate);
boolean hasDestinationRef = StringUtils.hasText(destination);
boolean hasDestinationName = StringUtils.hasText(destinationName);
if (StringUtils.hasText(jmsTemplate)) {
if (hasJmsTemplate) {
JmsAdapterParserUtils.verifyNoJmsTemplateAttributes(element, parserContext);
builder.addConstructorArgReference(jmsTemplate);
}
else if (hasDestinationRef || hasDestinationName) {
builder.addConstructorArgReference(JmsAdapterParserUtils.determineConnectionFactoryBeanName(element, parserContext));
else {
builder.addConstructorArgValue(JmsAdapterParserUtils.parseJmsTemplateBeanDefinition(element, parserContext));
}
if (hasDestinationRef || hasDestinationName) {
if (hasDestinationRef) {
if (hasDestinationName) {
parserContext.getReaderContext().error("The 'destination-name' " +
"and 'destination' attributes are mutually exclusive.", source);
"and 'destination' attributes are mutually exclusive.", parserContext.extractSource(element));
}
builder.addConstructorArgReference(destination);
builder.addPropertyReference("destination", destination);
}
else if (hasDestinationName) {
builder.addConstructorArgValue(destinationName);
if (StringUtils.hasText(pubSubDomain)) {
builder.addPropertyValue(JmsAdapterParserUtils.PUB_SUB_DOMAIN_PROPERTY, pubSubDomain);
}
builder.addPropertyValue("destinationName", destinationName);
}
}
else {
else if (!hasJmsTemplate) {
throw new BeanCreationException("either a '" + JmsAdapterParserUtils.JMS_TEMPLATE_ATTRIBUTE +
"' or one of '" + JmsAdapterParserUtils.DESTINATION_ATTRIBUTE + "' or '"
+ JmsAdapterParserUtils.DESTINATION_NAME_ATTRIBUTE +
@@ -88,9 +86,7 @@ public class JmsInboundChannelAdapterParser extends AbstractPollingInboundChanne
if (StringUtils.hasText(headerMapper)) {
builder.addPropertyReference(JmsAdapterParserUtils.HEADER_MAPPER_PROPERTY, headerMapper);
}
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "message-converter");
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "selector", "messageSelector");
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "destination-resolver");
BeanDefinition beanDefinition = builder.getBeanDefinition();
String beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, parserContext.getRegistry());
BeanComponentDefinition component = new BeanComponentDefinition(beanDefinition, beanName);