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 36958793f1..0d46c70399 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 @@ -27,9 +27,7 @@ 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. @@ -50,10 +48,7 @@ public class SelectorChainParser extends AbstractSingleBeanDefinitionParser { @SuppressWarnings("unchecked") private void parseSelectorChain(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) { - String strategy = element.getAttribute("strategy"); - if (StringUtils.hasText(strategy)) { - builder.addPropertyValue("strategy", Strategy.valueOf(strategy)); - } + IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "voting-strategy"); ManagedList selectors = new ManagedList(); NodeList childNodes = element.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { 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 01192c72f1..5684f0b21d 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 @@ -295,18 +295,18 @@ - + - - + + diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/MessageEndpoint.java b/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/MessageEndpoint.java index a20050d448..3e6dfcf25a 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/MessageEndpoint.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/MessageEndpoint.java @@ -16,9 +16,8 @@ package org.springframework.integration.endpoint; - /** - * Base interface for message endpoints. + * Base interface for Message Endpoints. * * @author Mark Fisher */ diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/selector/MessageSelectorChain.java b/org.springframework.integration/src/main/java/org/springframework/integration/selector/MessageSelectorChain.java index 6282ead2af..8dd3401c34 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/selector/MessageSelectorChain.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/selector/MessageSelectorChain.java @@ -24,24 +24,29 @@ import org.springframework.util.Assert; /** * A message selector implementation that passes incoming messages through a - * chain of selectors. The chain will be broken by any selector that returns - * false. + * chain of selectors. Whether the Message is {@link #accept(Message) accepted} + * is based upon the tallied results of the individual selectors' responses in + * accordance with this chain's {@link VotingStrategy}. * * @author Mark Fisher */ public class MessageSelectorChain implements MessageSelector { - public static enum Strategy { ALL, MORE_THAN_HALF, AT_LEAST_HALF, ANY }; + public static enum VotingStrategy { ALL, ANY, MAJORITY, MAJORITY_OR_TIE }; - private volatile Strategy strategy = Strategy.ALL; + private volatile VotingStrategy votingStrategy = VotingStrategy.ALL; private final List selectors = new CopyOnWriteArrayList(); - public void setStrategy(Strategy strategy) { - Assert.notNull(strategy, "strategy must not be null"); - this.strategy = strategy; + /** + * Specify the voting strategy for this selector chain. + *

The default is {@link VotingStrategy#ALL}. + */ + public void setVotingStrategy(VotingStrategy votingStrategy) { + Assert.notNull(votingStrategy, "votingStrategy must not be null"); + this.votingStrategy = votingStrategy; } /** @@ -70,9 +75,10 @@ public class MessageSelectorChain implements MessageSelector { } /** - * Pass the message through the selector chain. As soon as a - * selector returns 'false', this method will return 'false'. - * If all selectors accept, this method will return 'true'. + * Pass the message through the selector chain. Whether the Message is + * {@link #accept(Message) accepted} is based upon the tallied results of + * the individual selectors' responses in accordance with this chain's + * {@link VotingStrategy}. */ public final boolean accept(Message message) { int count = 0; @@ -80,12 +86,12 @@ public class MessageSelectorChain implements MessageSelector { for (MessageSelector next : this.selectors) { count++; if (next.accept(message)) { - if (this.strategy.equals(Strategy.ANY)) { + if (this.votingStrategy.equals(VotingStrategy.ANY)) { return true; } accepted++; } - else if (this.strategy.equals(Strategy.ALL)) { + else if (this.votingStrategy.equals(VotingStrategy.ALL)) { return false; } } @@ -96,17 +102,17 @@ public class MessageSelectorChain implements MessageSelector { if (accepted == 0) { return false; } - switch (this.strategy) { - case ANY: - return true; - case ALL: - return (accepted == total); - case MORE_THAN_HALF: - return (2 * accepted) > total; - case AT_LEAST_HALF: - return (2 * accepted) >= total; - default: - throw new IllegalArgumentException("unsupported strategy " + this.strategy); + switch (this.votingStrategy) { + case ANY: + return true; + case ALL: + return (accepted == total); + case MAJORITY: + return (2 * accepted) > total; + case MAJORITY_OR_TIE: + return (2 * accepted) >= total; + default: + throw new IllegalArgumentException("unsupported voting strategy " + this.votingStrategy); } } 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 e41cc02e53..6d2a3d7363 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 @@ -28,7 +28,7 @@ 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; +import org.springframework.integration.selector.MessageSelectorChain.VotingStrategy; /** * @author Mark Fisher @@ -43,7 +43,7 @@ public class SelectorChainParserTests { MessageSelector selector2 = (MessageSelector) context.getBean("selector2"); MessageSelectorChain chain = (MessageSelectorChain) context.getBean("selectorChain"); List selectors = this.getSelectors(chain); - assertEquals(Strategy.ALL, this.getStrategy(chain)); + assertEquals(VotingStrategy.ALL, this.getStrategy(chain)); assertEquals(selector1, selectors.get(0)); assertEquals(selector2, selectors.get(1)); assertTrue(chain.accept(new StringMessage("test"))); @@ -60,24 +60,24 @@ public class SelectorChainParserTests { 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)); + assertEquals(VotingStrategy.MAJORITY, 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)); + assertEquals(VotingStrategy.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)); + assertEquals(VotingStrategy.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)); + assertEquals(VotingStrategy.MAJORITY_OR_TIE, this.getStrategy(chain4)); List selectorList4 = this.getSelectors(chain4); assertEquals(selector6, selectorList4.get(0)); assertTrue(chain1.accept(new StringMessage("test1"))); @@ -93,8 +93,8 @@ public class SelectorChainParserTests { return (List) accessor.getPropertyValue("selectors"); } - private Strategy getStrategy(MessageSelectorChain chain) { - return (Strategy) new DirectFieldAccessor(chain).getPropertyValue("strategy"); + private VotingStrategy getStrategy(MessageSelectorChain chain) { + return (VotingStrategy) new DirectFieldAccessor(chain).getPropertyValue("votingStrategy"); } } 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 2fed90c6e9..df1b66514c 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,17 +12,17 @@ - + - + - + - + diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/selector/MessageSelectorChainTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/selector/MessageSelectorChainTests.java index a286e96e30..997b79a9fe 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/selector/MessageSelectorChainTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/selector/MessageSelectorChainTests.java @@ -35,7 +35,7 @@ public class MessageSelectorChainTests { @Test public void anyStrategyAccepts() { MessageSelectorChain chain = new MessageSelectorChain(); - chain.setStrategy(MessageSelectorChain.Strategy.ANY); + chain.setVotingStrategy(MessageSelectorChain.VotingStrategy.ANY); chain.add(new TestSelector(false)); chain.add(new TestSelector(false)); chain.add(new TestSelector(true)); @@ -46,7 +46,7 @@ public class MessageSelectorChainTests { @Test public void anyStrategyRejects() { MessageSelectorChain chain = new MessageSelectorChain(); - chain.setStrategy(MessageSelectorChain.Strategy.ANY); + chain.setVotingStrategy(MessageSelectorChain.VotingStrategy.ANY); chain.add(new TestSelector(false)); chain.add(new TestSelector(false)); chain.add(new TestSelector(false)); @@ -57,7 +57,7 @@ public class MessageSelectorChainTests { @Test public void allStrategyAccepts() { MessageSelectorChain chain = new MessageSelectorChain(); - chain.setStrategy(MessageSelectorChain.Strategy.ALL); + chain.setVotingStrategy(MessageSelectorChain.VotingStrategy.ALL); chain.add(new TestSelector(true)); chain.add(new TestSelector(true)); chain.add(new TestSelector(true)); @@ -67,7 +67,7 @@ public class MessageSelectorChainTests { @Test public void allStrategyRejects() { MessageSelectorChain chain = new MessageSelectorChain(); - chain.setStrategy(MessageSelectorChain.Strategy.ALL); + chain.setVotingStrategy(MessageSelectorChain.VotingStrategy.ALL); chain.add(new TestSelector(true)); chain.add(new TestSelector(false)); chain.add(new TestSelector(true)); @@ -75,9 +75,9 @@ public class MessageSelectorChainTests { } @Test - public void atLeastHalfStrategyWithOddNumberAccepts() { + public void majorityOrTieStrategyWithOddNumberAccepts() { MessageSelectorChain chain = new MessageSelectorChain(); - chain.setStrategy(MessageSelectorChain.Strategy.AT_LEAST_HALF); + chain.setVotingStrategy(MessageSelectorChain.VotingStrategy.MAJORITY_OR_TIE); chain.add(new TestSelector(true)); chain.add(new TestSelector(true)); chain.add(new TestSelector(false)); @@ -85,9 +85,9 @@ public class MessageSelectorChainTests { } @Test - public void atLeastHalfStrategyWithEvenNumberAccepts() { + public void majorityOrTieStrategyWithEvenNumberAccepts() { MessageSelectorChain chain = new MessageSelectorChain(); - chain.setStrategy(MessageSelectorChain.Strategy.AT_LEAST_HALF); + chain.setVotingStrategy(MessageSelectorChain.VotingStrategy.MAJORITY_OR_TIE); chain.add(new TestSelector(true)); chain.add(new TestSelector(true)); chain.add(new TestSelector(false)); @@ -96,9 +96,9 @@ public class MessageSelectorChainTests { } @Test - public void atLeastHalfStrategyWithOddNumberRejects() { + public void majorityOrTieStrategyWithOddNumberRejects() { MessageSelectorChain chain = new MessageSelectorChain(); - chain.setStrategy(MessageSelectorChain.Strategy.AT_LEAST_HALF); + chain.setVotingStrategy(MessageSelectorChain.VotingStrategy.MAJORITY_OR_TIE); chain.add(new TestSelector(false)); chain.add(new TestSelector(true)); chain.add(new TestSelector(false)); @@ -106,9 +106,9 @@ public class MessageSelectorChainTests { } @Test - public void atLeastHalfStrategyWithEvenNumberRejects() { + public void majorityOrTieStrategyWithEvenNumberRejects() { MessageSelectorChain chain = new MessageSelectorChain(); - chain.setStrategy(MessageSelectorChain.Strategy.AT_LEAST_HALF); + chain.setVotingStrategy(MessageSelectorChain.VotingStrategy.MAJORITY_OR_TIE); chain.add(new TestSelector(false)); chain.add(new TestSelector(true)); chain.add(new TestSelector(false)); @@ -117,9 +117,9 @@ public class MessageSelectorChainTests { } @Test - public void moreThanHalfStrategyWithOddNumberAccepts() { + public void majorityStrategyWithOddNumberAccepts() { MessageSelectorChain chain = new MessageSelectorChain(); - chain.setStrategy(MessageSelectorChain.Strategy.MORE_THAN_HALF); + chain.setVotingStrategy(MessageSelectorChain.VotingStrategy.MAJORITY); chain.add(new TestSelector(true)); chain.add(new TestSelector(true)); chain.add(new TestSelector(false)); @@ -127,9 +127,9 @@ public class MessageSelectorChainTests { } @Test - public void moreThanHalfStrategyWithEvenNumberAccepts() { + public void majorityStrategyWithEvenNumberAccepts() { MessageSelectorChain chain = new MessageSelectorChain(); - chain.setStrategy(MessageSelectorChain.Strategy.MORE_THAN_HALF); + chain.setVotingStrategy(MessageSelectorChain.VotingStrategy.MAJORITY); chain.add(new TestSelector(true)); chain.add(new TestSelector(true)); chain.add(new TestSelector(false)); @@ -138,9 +138,9 @@ public class MessageSelectorChainTests { } @Test - public void moreThanHalfStrategyWithOddNumberRejects() { + public void majorityStrategyWithOddNumberRejects() { MessageSelectorChain chain = new MessageSelectorChain(); - chain.setStrategy(MessageSelectorChain.Strategy.MORE_THAN_HALF); + chain.setVotingStrategy(MessageSelectorChain.VotingStrategy.MAJORITY); chain.add(new TestSelector(false)); chain.add(new TestSelector(true)); chain.add(new TestSelector(false)); @@ -148,9 +148,9 @@ public class MessageSelectorChainTests { } @Test - public void moreThanHalfStrategyWithEvenNumberRejects() { + public void majorityStrategyWithEvenNumberRejects() { MessageSelectorChain chain = new MessageSelectorChain(); - chain.setStrategy(MessageSelectorChain.Strategy.MORE_THAN_HALF); + chain.setVotingStrategy(MessageSelectorChain.VotingStrategy.MAJORITY); chain.add(new TestSelector(false)); chain.add(new TestSelector(true)); chain.add(new TestSelector(true));