diff --git a/activemq-core/src/main/java/org/apache/activemq/filter/DestinationMapEntry.java b/activemq-core/src/main/java/org/apache/activemq/filter/DestinationMapEntry.java index 077f0c486f..138df0a909 100644 --- a/activemq-core/src/main/java/org/apache/activemq/filter/DestinationMapEntry.java +++ b/activemq-core/src/main/java/org/apache/activemq/filter/DestinationMapEntry.java @@ -27,10 +27,24 @@ import org.springframework.beans.factory.InitializingBean; * * @version $Revision: 1.1 $ */ -public abstract class DestinationMapEntry implements InitializingBean { +public abstract class DestinationMapEntry implements InitializingBean, Comparable { private ActiveMQDestination destination; + + public int compareTo(Object that) { + if (that instanceof DestinationMapEntry) { + DestinationMapEntry thatEntry = (DestinationMapEntry) that; + return ActiveMQDestination.compare(destination, thatEntry.destination); + } + else if (that == null) { + return 1; + } + else { + return getClass().getName().compareTo(that.getClass().getName()); + } + } + /** * A helper method to set the destination from a configuration file */ diff --git a/activemq-core/src/main/java/org/apache/activemq/filter/DestinationMapNode.java b/activemq-core/src/main/java/org/apache/activemq/filter/DestinationMapNode.java index 478fb18543..cedcdab3e3 100755 --- a/activemq-core/src/main/java/org/apache/activemq/filter/DestinationMapNode.java +++ b/activemq-core/src/main/java/org/apache/activemq/filter/DestinationMapNode.java @@ -25,7 +25,7 @@ import java.util.Set; /** * An implementation class used to implement {@link DestinationMap} - * + * * @version $Revision: 1.2 $ */ public class DestinationMapNode { @@ -38,14 +38,13 @@ public class DestinationMapNode { protected static final String ANY_CHILD = DestinationMap.ANY_CHILD; protected static final String ANY_DESCENDENT = DestinationMap.ANY_DESCENDENT; - public DestinationMapNode(DestinationMapNode parent) { this.parent = parent; } - /** - * Returns the child node for the given named path or null if it does not exist + * Returns the child node for the given named path or null if it does not + * exist */ public DestinationMapNode getChild(String path) { return (DestinationMapNode) childNodes.get(path); @@ -54,10 +53,10 @@ public class DestinationMapNode { public int getChildCount() { return childNodes.size(); } - + /** - * Returns the child node for the given named path, lazily creating one if it does - * not yet exist + * Returns the child node for the given named path, lazily creating one if + * it does not yet exist */ public DestinationMapNode getChildOrCreate(String path) { DestinationMapNode answer = (DestinationMapNode) childNodes.get(path); @@ -169,10 +168,12 @@ public class DestinationMapNode { public void appendMatchingValues(Set answer, String[] paths, int startIndex) { DestinationMapNode node = this; + boolean couldMatchAny = true; for (int i = startIndex, size = paths.length; i < size && node != null; i++) { String path = paths[i]; if (path.equals(ANY_DESCENDENT)) { answer.addAll(node.getDesendentValues()); + couldMatchAny = false; break; } @@ -186,10 +187,16 @@ public class DestinationMapNode { } if (node != null) { answer.addAll(node.getValues()); + if (couldMatchAny) { + // lets allow FOO.BAR to match the FOO.BAR.> entry in the map + DestinationMapNode child = node.getChild(ANY_DESCENDENT); + if (child != null) { + answer.addAll(child.getValues()); + } + } } } - public String getPath() { return path; } @@ -200,7 +207,6 @@ public class DestinationMapNode { } } - protected void removeChild(DestinationMapNode node) { childNodes.remove(node.getPath()); pruneIfEmpty(); diff --git a/activemq-core/src/test/java/org/apache/activemq/filter/DestinationMapTest.java b/activemq-core/src/test/java/org/apache/activemq/filter/DestinationMapTest.java index 93beacebbf..a3ee8e1908 100755 --- a/activemq-core/src/test/java/org/apache/activemq/filter/DestinationMapTest.java +++ b/activemq-core/src/test/java/org/apache/activemq/filter/DestinationMapTest.java @@ -165,20 +165,34 @@ public class DestinationMapTest extends TestCase { put("TEST.XYZ.D4", v4); put("TEST.BAR.D3", v5); put("TEST.*.D2", v6); - - + + assertMapValue("TEST.*.D3", v2, v3, v5); assertMapValue("TEST.*.D4", v2, v4); - + assertMapValue("TEST.*", v1, v2); assertMapValue("TEST.*.*", v2, v3, v4, v5, v6); assertMapValue("*.*.D3", v2, v3, v5); assertMapValue("TEST.BAR.*", v2, v5, v6); - + assertMapValue("TEST.BAR.D2", v2, v6); assertMapValue("TEST.*.D2", v2, v6); assertMapValue("TEST.BAR.*", v2, v5, v6); } + + public void testAnyPathWildcardInMap() throws Exception { + put("TEST.FOO.>", v1); + + + assertMapValue("TEST.FOO.BAR.WHANOT.A.B.C", v1); + assertMapValue("TEST.FOO.BAR.WHANOT", v1); + assertMapValue("TEST.FOO.BAR", v1); + + assertMapValue("TEST.*.*", v1); + assertMapValue("TEST.BAR", null); + + assertMapValue("TEST.FOO", v1); + } public void testSimpleAddRemove() throws Exception { put("TEST.D1", v2);