diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/SelectorChainParser.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/SelectorChainParser.java
index 43eab36fda..36958793f1 100644
--- a/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/SelectorChainParser.java
+++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/SelectorChainParser.java
@@ -22,9 +22,14 @@ import org.w3c.dom.NodeList;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.selector.MessageSelectorChain;
+import org.springframework.integration.selector.MessageSelectorChain.Strategy;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
/**
* Parser for the <selector-chain/> element.
@@ -38,14 +43,35 @@ public class SelectorChainParser extends AbstractSingleBeanDefinitionParser {
return MessageSelectorChain.class;
}
+ public void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
+ Assert.hasText(element.getAttribute("id"), "id is required");
+ this.parseSelectorChain(builder, element, parserContext);
+ }
+
@SuppressWarnings("unchecked")
- public void doParse(Element element, BeanDefinitionBuilder builder) {
+ private void parseSelectorChain(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) {
+ String strategy = element.getAttribute("strategy");
+ if (StringUtils.hasText(strategy)) {
+ builder.addPropertyValue("strategy", Strategy.valueOf(strategy));
+ }
ManagedList selectors = new ManagedList();
NodeList childNodes = element.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node child = childNodes.item(i);
- if (child.getNodeType() == Node.ELEMENT_NODE && "selector".equals(child.getLocalName())) {
- selectors.add(new RuntimeBeanReference(((Element) child).getAttribute("ref")));
+ if (child.getNodeType() == Node.ELEMENT_NODE) {
+ String nodeName = child.getLocalName();
+ if ("selector".equals(nodeName)) {
+ String ref = ((Element) child).getAttribute("ref");
+ selectors.add(new RuntimeBeanReference(ref));
+ }
+ else if ("selector-chain".equals(nodeName)) {
+ BeanDefinitionBuilder nestedBuilder =
+ BeanDefinitionBuilder.genericBeanDefinition(MessageSelectorChain.class);
+ this.parseSelectorChain(nestedBuilder, (Element) child, parserContext);
+ String nestedBeanName = BeanDefinitionReaderUtils.registerWithGeneratedName(
+ nestedBuilder.getBeanDefinition(), parserContext.getRegistry());
+ selectors.add(new RuntimeBeanReference(nestedBeanName));
+ }
}
}
builder.addPropertyValue("selectors", selectors);
diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/spring-integration-1.0.xsd b/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/spring-integration-1.0.xsd
index 6e4a854aa8..01192c72f1 100644
--- a/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/spring-integration-1.0.xsd
+++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/spring-integration-1.0.xsd
@@ -146,7 +146,7 @@
-
+
@@ -192,8 +192,8 @@
- Base type for handler endpoint elements that accept Messages from an input-channel
- and also produce Messages to be sent to an output-channel.
+ Base type for Message Endpoint elements that accept Messages from an input-channel
+ and also may produce reply Messages to be sent to an output-channel.
@@ -206,7 +206,7 @@
- Base type for handler endpoint elements that accept Messages from an input-channel.
+ Base type for Message Endpoint elements that accept Messages from an input-channel.
@@ -214,7 +214,7 @@
-
+
@@ -290,10 +290,26 @@
Defines a MessageSelector chain.
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/SelectorChainParserTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/config/SelectorChainParserTests.java
index ed42b2e96d..e41cc02e53 100644
--- a/org.springframework.integration/src/test/java/org/springframework/integration/config/SelectorChainParserTests.java
+++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/SelectorChainParserTests.java
@@ -17,6 +17,7 @@
package org.springframework.integration.config;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import java.util.List;
@@ -24,8 +25,10 @@ import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.integration.message.StringMessage;
import org.springframework.integration.selector.MessageSelector;
import org.springframework.integration.selector.MessageSelectorChain;
+import org.springframework.integration.selector.MessageSelectorChain.Strategy;
/**
* @author Mark Fisher
@@ -33,18 +36,65 @@ import org.springframework.integration.selector.MessageSelectorChain;
public class SelectorChainParserTests {
@Test
- @SuppressWarnings("unchecked")
- public void testSelectorChain() {
+ public void selectorChain() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"selectorChainParserTests.xml", this.getClass());
MessageSelector selector1 = (MessageSelector) context.getBean("selector1");
MessageSelector selector2 = (MessageSelector) context.getBean("selector2");
MessageSelectorChain chain = (MessageSelectorChain) context.getBean("selectorChain");
- DirectFieldAccessor accessor = new DirectFieldAccessor(chain);
- List selectors = (List)
- accessor.getPropertyValue("selectors");
+ List selectors = this.getSelectors(chain);
+ assertEquals(Strategy.ALL, this.getStrategy(chain));
assertEquals(selector1, selectors.get(0));
assertEquals(selector2, selectors.get(1));
+ assertTrue(chain.accept(new StringMessage("test")));
+ }
+
+ @Test
+ public void nestedSelectorChain() {
+ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
+ "selectorChainParserTests.xml", this.getClass());
+ MessageSelector selector1 = (MessageSelector) context.getBean("selector1");
+ MessageSelector selector2 = (MessageSelector) context.getBean("selector2");
+ MessageSelector selector3 = (MessageSelector) context.getBean("selector3");
+ MessageSelector selector4 = (MessageSelector) context.getBean("selector4");
+ MessageSelector selector5 = (MessageSelector) context.getBean("selector5");
+ MessageSelector selector6 = (MessageSelector) context.getBean("selector6");
+ MessageSelectorChain chain1 = (MessageSelectorChain) context.getBean("nestedSelectorChain");
+ assertEquals(Strategy.MORE_THAN_HALF, this.getStrategy(chain1));
+ List selectorList1 = this.getSelectors(chain1);
+ assertEquals(selector1, selectorList1.get(0));
+ assertTrue(selectorList1.get(1) instanceof MessageSelectorChain);
+ MessageSelectorChain chain2 = (MessageSelectorChain) selectorList1.get(1);
+ assertEquals(Strategy.ALL, this.getStrategy(chain2));
+ List selectorList2 = this.getSelectors(chain2);
+ assertEquals(selector2, selectorList2.get(0));
+ assertTrue(selectorList2.get(1) instanceof MessageSelectorChain);
+ MessageSelectorChain chain3 = (MessageSelectorChain) selectorList2.get(1);
+ assertEquals(Strategy.ANY, this.getStrategy(chain3));
+ List selectorList3 = this.getSelectors(chain3);
+ assertEquals(selector3, selectorList3.get(0));
+ assertEquals(selector4, selectorList3.get(1));
+ assertEquals(selector5, selectorList2.get(2));
+ assertTrue(selectorList1.get(2) instanceof MessageSelectorChain);
+ MessageSelectorChain chain4 = (MessageSelectorChain) selectorList1.get(2);
+ assertEquals(Strategy.AT_LEAST_HALF, this.getStrategy(chain4));
+ List selectorList4 = this.getSelectors(chain4);
+ assertEquals(selector6, selectorList4.get(0));
+ assertTrue(chain1.accept(new StringMessage("test1")));
+ assertTrue(chain2.accept(new StringMessage("test2")));
+ assertTrue(chain3.accept(new StringMessage("test3")));
+ assertTrue(chain4.accept(new StringMessage("test4")));
+ }
+
+
+ @SuppressWarnings("unchecked")
+ private List getSelectors(MessageSelectorChain chain) {
+ DirectFieldAccessor accessor = new DirectFieldAccessor(chain);
+ return (List) accessor.getPropertyValue("selectors");
+ }
+
+ private Strategy getStrategy(MessageSelectorChain chain) {
+ return (Strategy) new DirectFieldAccessor(chain).getPropertyValue("strategy");
}
}
diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/StubMessageSelector.java b/org.springframework.integration/src/test/java/org/springframework/integration/config/StubMessageSelector.java
index 9d005858da..7aec818886 100644
--- a/org.springframework.integration/src/test/java/org/springframework/integration/config/StubMessageSelector.java
+++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/StubMessageSelector.java
@@ -16,16 +16,28 @@
package org.springframework.integration.config;
+import org.springframework.beans.factory.BeanNameAware;
import org.springframework.integration.message.Message;
import org.springframework.integration.selector.MessageSelector;
/**
* @author Mark Fisher
*/
-public class StubMessageSelector implements MessageSelector {
+public class StubMessageSelector implements MessageSelector, BeanNameAware {
+
+ private String beanName;
+
+
+ public void setBeanName(String beanName) {
+ this.beanName = beanName;
+ }
public boolean accept(Message> message) {
return true;
}
+ public String toString() {
+ return this.beanName;
+ }
+
}
diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/selectorChainParserTests.xml b/org.springframework.integration/src/test/java/org/springframework/integration/config/selectorChainParserTests.xml
index 769e40f09c..2fed90c6e9 100644
--- a/org.springframework.integration/src/test/java/org/springframework/integration/config/selectorChainParserTests.xml
+++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/selectorChainParserTests.xml
@@ -12,8 +12,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+