Fix for https://issues.apache.org/jira/browse/AMQ-4884
Project: http://git-wip-us.apache.org/repos/asf/activemq/repo Commit: http://git-wip-us.apache.org/repos/asf/activemq/commit/ad0bcd35 Tree: http://git-wip-us.apache.org/repos/asf/activemq/tree/ad0bcd35 Diff: http://git-wip-us.apache.org/repos/asf/activemq/diff/ad0bcd35 Branch: refs/heads/activemq-5.9 Commit: ad0bcd35c59ce8116e786c96722e29918a6ccd40 Parents: d5904df Author: rajdavies <[email protected]> Authored: Wed Nov 13 18:50:24 2013 +0000 Committer: Hadrian Zbarcea <[email protected]> Committed: Wed Mar 12 12:05:26 2014 -0400 ---------------------------------------------------------------------- .../activemq/filter/DestinationFilter.java | 27 +++++++++++++++-- .../apache/activemq/filter/DestinationMap.java | 32 ++++++++++---------- 2 files changed, 40 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/activemq/blob/ad0bcd35/activemq-client/src/main/java/org/apache/activemq/filter/DestinationFilter.java ---------------------------------------------------------------------- diff --git a/activemq-client/src/main/java/org/apache/activemq/filter/DestinationFilter.java b/activemq-client/src/main/java/org/apache/activemq/filter/DestinationFilter.java index bb16fe6..34f4b8a 100755 --- a/activemq-client/src/main/java/org/apache/activemq/filter/DestinationFilter.java +++ b/activemq-client/src/main/java/org/apache/activemq/filter/DestinationFilter.java @@ -20,14 +20,11 @@ package org.apache.activemq.filter; import java.io.IOException; import javax.jms.JMSException; - import org.apache.activemq.command.ActiveMQDestination; import org.apache.activemq.util.JMSExceptionSupport; /** * Represents a filter which only operates on Destinations - * - * */ public abstract class DestinationFilter implements BooleanExpression { @@ -56,6 +53,7 @@ public abstract class DestinationFilter implements BooleanExpression { return new CompositeDestinationFilter(destination); } String[] paths = DestinationPath.getDestinationPaths(destination); + paths = rationalizePaths(paths); int idx = paths.length - 1; if (idx >= 0) { String lastPath = paths[idx]; @@ -74,4 +72,27 @@ public abstract class DestinationFilter implements BooleanExpression { // if none of the paths contain a wildcard then use equality return new SimpleDestinationFilter(destination); } + + /** + * Look for the case where any CHILD is followed by any decsendant + */ + public static String[] rationalizePaths(String[] paths) { + String[] result = paths; + if (paths != null && paths.length > 1) { + int last = paths.length - 1; + if (paths[last].equals(ANY_DESCENDENT)) { + last -= 1; + if (paths[last].equals(ANY_DESCENDENT) || paths[last].equals(ANY_CHILD)) { + + result = new String[paths.length-1]; + System.arraycopy(paths,0,result,0,result.length); + result[result.length-1] = ANY_DESCENDENT; + result = rationalizePaths(result); + } + } + } + + return result; + } + } http://git-wip-us.apache.org/repos/asf/activemq/blob/ad0bcd35/activemq-client/src/main/java/org/apache/activemq/filter/DestinationMap.java ---------------------------------------------------------------------- diff --git a/activemq-client/src/main/java/org/apache/activemq/filter/DestinationMap.java b/activemq-client/src/main/java/org/apache/activemq/filter/DestinationMap.java index 0ff894e..2c71578 100755 --- a/activemq-client/src/main/java/org/apache/activemq/filter/DestinationMap.java +++ b/activemq-client/src/main/java/org/apache/activemq/filter/DestinationMap.java @@ -35,8 +35,6 @@ import org.apache.activemq.command.ActiveMQDestination; * pretty fast. <br> * Looking up of a value could return a single value or a List of matching * values if a wildcard or composite destination is used. - * - * */ public class DestinationMap { protected static final String ANY_DESCENDENT = DestinationFilter.ANY_DESCENDENT; @@ -57,7 +55,7 @@ public class DestinationMap { * @return a List of matching values or an empty list if there are no * matching values. */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({"rawtypes", "unchecked"}) public synchronized Set get(ActiveMQDestination key) { if (key.isComposite()) { ActiveMQDestination[] destinations = key.getCompositeDestinations(); @@ -66,7 +64,7 @@ public class DestinationMap { ActiveMQDestination childDestination = destinations[i]; Object value = get(childDestination); if (value instanceof Set) { - answer.addAll((Set)value); + answer.addAll((Set) value); } else if (value != null) { answer.add(value); } @@ -86,9 +84,11 @@ public class DestinationMap { return; } String[] paths = key.getDestinationPaths(); + paths = DestinationFilter.rationalizePaths(paths); getRootNode(key).add(paths, 0, value); } + /** * Removes the value from the associated destination */ @@ -137,12 +137,12 @@ public class DestinationMap { * A helper method to allow the destination map to be populated from a * dependency injection framework such as Spring */ - @SuppressWarnings({ "rawtypes" }) - protected void setEntries(List<DestinationMapEntry> entries) { + @SuppressWarnings({"rawtypes"}) + protected void setEntries(List<DestinationMapEntry> entries) { for (Object element : entries) { Class<? extends DestinationMapEntry> type = getEntryClass(); if (type.isInstance(element)) { - DestinationMapEntry entry = (DestinationMapEntry)element; + DestinationMapEntry entry = (DestinationMapEntry) element; put(entry.getDestination(), entry.getValue()); } else { throw new IllegalArgumentException("Each entry must be an instance of type: " + type.getName() + " but was: " + element); @@ -156,12 +156,12 @@ public class DestinationMap { * restrict the type of allowed entries to make a type safe destination map * for custom policies. */ - @SuppressWarnings({ "rawtypes" }) + @SuppressWarnings({"rawtypes"}) protected Class<? extends DestinationMapEntry> getEntryClass() { return DestinationMapEntry.class; } - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({"rawtypes", "unchecked"}) protected Set findWildcardMatches(ActiveMQDestination key) { String[] paths = key.getDestinationPaths(); Set answer = new HashSet(); @@ -173,7 +173,7 @@ public class DestinationMap { * @param key * @return */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({"rawtypes", "unchecked"}) public Set removeAll(ActiveMQDestination key) { Set rc = new HashSet(); if (key.isComposite()) { @@ -196,7 +196,7 @@ public class DestinationMap { * @param destination the destination to find the value for * @return the largest matching value or null if no value matches */ - @SuppressWarnings({ "rawtypes", "unchecked" }) + @SuppressWarnings({"rawtypes", "unchecked"}) public Object chooseValue(ActiveMQDestination destination) { Set set = get(destination); if (set == null || set.isEmpty()) { @@ -210,7 +210,7 @@ public class DestinationMap { * Returns the root node for the given destination type */ protected DestinationMapNode getRootNode(ActiveMQDestination key) { - if (key.isTemporary()){ + if (key.isTemporary()) { if (key.isQueue()) { return tempQueueRootNode; } else { @@ -232,14 +232,14 @@ public class DestinationMap { tempTopicRootNode = new DestinationMapNode(null); } - public boolean isEmpty(){ + public boolean isEmpty() { return queueRootNode.isEmpty() && topicRootNode.isEmpty() && tempQueueRootNode.isEmpty() && tempTopicRootNode.isEmpty(); } public static Set union(Set existing, Set candidates) { - if ( candidates != null ) { + if (candidates != null) { if (existing != null) { - for (Iterator<Object> iterator = existing.iterator(); iterator.hasNext();) { + for (Iterator<Object> iterator = existing.iterator(); iterator.hasNext(); ) { Object toMatch = iterator.next(); if (!candidates.contains(toMatch)) { iterator.remove(); @@ -248,7 +248,7 @@ public class DestinationMap { } else { existing = candidates; } - } else if ( existing != null ) { + } else if (existing != null) { existing.clear(); } return existing;
