diff --git a/spring-integration-core/src/main/java/org/springframework/integration/adapter/jms/config/JmsSourceAdapterParser.java b/spring-integration-core/src/main/java/org/springframework/integration/adapter/jms/config/JmsSourceAdapterParser.java index 9cfb286b35..0510175c15 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/adapter/jms/config/JmsSourceAdapterParser.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/adapter/jms/config/JmsSourceAdapterParser.java @@ -54,6 +54,10 @@ public class JmsSourceAdapterParser extends AbstractSingleBeanDefinitionParser { 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"; + protected Class getBeanClass(Element element) { if (StringUtils.hasText(element.getAttribute(POLL_PERIOD_ATTRIBUTE))) { @@ -87,6 +91,11 @@ public class JmsSourceAdapterParser extends AbstractSingleBeanDefinitionParser { throw new BeanCreationException("'" + POLL_PERIOD_ATTRIBUTE + "' is required for a " + JmsPollingSourceAdapter.class.getSimpleName()); } + 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 '" + JMS_TEMPLATE_ATTRIBUTE + + "' reference where the template contains a 'messageConverter' property instead."); + } builder.addPropertyValue(POLL_PERIOD_PROPERTY, pollPeriod); String jmsTemplate = element.getAttribute(JMS_TEMPLATE_ATTRIBUTE); String connectionFactory = element.getAttribute(CONNECTION_FACTORY_ATTRIBUTE); @@ -121,9 +130,10 @@ public class JmsSourceAdapterParser extends AbstractSingleBeanDefinitionParser { String connectionFactory = element.getAttribute(CONNECTION_FACTORY_ATTRIBUTE); String destination = element.getAttribute(DESTINATION_ATTRIBUTE); String destinationName = element.getAttribute(DESTINATION_NAME_ATTRIBUTE); + String messageConverter = element.getAttribute(MESSAGE_CONVERTER_ATTRIBUTE); if (StringUtils.hasText(element.getAttribute(JMS_TEMPLATE_ATTRIBUTE))) { throw new BeanCreationException(JmsMessageDrivenSourceAdapter.class.getSimpleName() + - " does not accept a '" + JMS_TEMPLATE_ATTRIBUTE + "' reference, both " + + " does not accept a '" + JMS_TEMPLATE_ATTRIBUTE + "' reference. Both " + "'" + CONNECTION_FACTORY_ATTRIBUTE + "' and '" + DESTINATION_ATTRIBUTE + "' (or '" + DESTINATION_NAME_ATTRIBUTE + "') must be provided."); } @@ -139,7 +149,10 @@ public class JmsSourceAdapterParser extends AbstractSingleBeanDefinitionParser { else { throw new BeanCreationException("Both '" + CONNECTION_FACTORY_ATTRIBUTE + "' and '" + DESTINATION_ATTRIBUTE + "' (or '" + DESTINATION_NAME_ATTRIBUTE + "') must be provided."); - } + } + if (StringUtils.hasText(messageConverter)) { + builder.addPropertyReference(MESSAGE_CONVERTER_PROPERTY, messageConverter); + } } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/spring-integration-1.0.xsd b/spring-integration-core/src/main/java/org/springframework/integration/config/spring-integration-1.0.xsd index d71b71a4f7..d3b53fa9fa 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/spring-integration-1.0.xsd +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/spring-integration-1.0.xsd @@ -248,6 +248,7 @@ + diff --git a/spring-integration-core/src/test/java/org/springframework/integration/adapter/jms/config/JmsSourceAdapterParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/adapter/jms/config/JmsSourceAdapterParserTests.java index 0ada773d62..ca3608b01c 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/adapter/jms/config/JmsSourceAdapterParserTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/adapter/jms/config/JmsSourceAdapterParserTests.java @@ -19,6 +19,10 @@ package org.springframework.integration.adapter.jms.config; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import javax.jms.JMSException; +import javax.jms.Session; +import javax.jms.TextMessage; + import org.junit.Test; import org.springframework.beans.factory.BeanCreationException; @@ -28,6 +32,8 @@ import org.springframework.integration.adapter.jms.JmsMessageDrivenSourceAdapter import org.springframework.integration.adapter.jms.JmsPollingSourceAdapter; import org.springframework.integration.channel.MessageChannel; import org.springframework.integration.message.Message; +import org.springframework.jms.support.converter.MessageConversionException; +import org.springframework.jms.support.converter.MessageConverter; /** * @author Mark Fisher @@ -104,6 +110,19 @@ public class JmsSourceAdapterParserTests { context.stop(); } + @Test + public void testMessageDrivenAdapterWithMessageConverter() { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "messageDrivenAdapterWithMessageConverter.xml", this.getClass()); + JmsMessageDrivenSourceAdapter adapter = (JmsMessageDrivenSourceAdapter) context.getBean("adapter"); + assertEquals(JmsMessageDrivenSourceAdapter.class, adapter.getClass()); + MessageChannel channel = (MessageChannel) context.getBean("channel"); + Message message = channel.receive(3000); + assertNotNull("message should not be null", message); + assertEquals("converted-test-message", message.getPayload()); + context.stop(); + } + @Test(expected=BeanDefinitionStoreException.class) public void testPollingAdapterWithConnectionFactoryOnly() { try { @@ -159,4 +178,19 @@ public class JmsSourceAdapterParserTests { } } + + public static class TestMessageConverter implements MessageConverter { + + public Object fromMessage(javax.jms.Message message) throws JMSException, MessageConversionException { + String original = ((TextMessage) message).getText(); + return "converted-" + original; + } + + public javax.jms.Message toMessage(Object object, Session session) throws JMSException, + MessageConversionException { + return null; + } + + } + } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/adapter/jms/config/messageDrivenAdapterWithMessageConverter.xml b/spring-integration-core/src/test/java/org/springframework/integration/adapter/jms/config/messageDrivenAdapterWithMessageConverter.xml new file mode 100644 index 0000000000..9589e6c7ed --- /dev/null +++ b/spring-integration-core/src/test/java/org/springframework/integration/adapter/jms/config/messageDrivenAdapterWithMessageConverter.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/EndpointParserTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/EndpointParserTests.java index 47d7a8781f..0a0dbcc3b5 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/EndpointParserTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/EndpointParserTests.java @@ -80,6 +80,18 @@ public class EndpointParserTests { assertEquals("test", bean.getMessage()); } + @Test + public void testHandlerChainEndpoint() throws InterruptedException { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + "endpointWithHandlerChainElement.xml", this.getClass()); + MessageChannel channel = (MessageChannel) context.getBean("testChannel"); + MessageChannel replyChannel = (MessageChannel) context.getBean("replyChannel"); + channel.send(new StringMessage("test")); + Message reply = replyChannel.receive(500); + assertNotNull(reply); + assertEquals("test-1-2-3", reply.getPayload()); + } + @Test public void testDefaultConcurrency() throws InterruptedException { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/TestConcatenatingHandler.java b/spring-integration-core/src/test/java/org/springframework/integration/config/TestConcatenatingHandler.java new file mode 100644 index 0000000000..928b5ba22d --- /dev/null +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/TestConcatenatingHandler.java @@ -0,0 +1,40 @@ +/* + * 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.config; + +import org.springframework.integration.handler.MessageHandler; +import org.springframework.integration.message.Message; +import org.springframework.integration.message.StringMessage; + +/** + * @author Mark Fisher + */ +public class TestConcatenatingHandler implements MessageHandler { + + private String value; + + + public TestConcatenatingHandler(String value) { + this.value = value; + } + + + public Message handle(Message message) { + return new StringMessage(message.getPayload() + this.value); + } + +} diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/endpointWithHandlerChainElement.xml b/spring-integration-core/src/test/java/org/springframework/integration/config/endpointWithHandlerChainElement.xml new file mode 100644 index 0000000000..a0b8bb7e8e --- /dev/null +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/endpointWithHandlerChainElement.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +