From 372af610763f9fb9b5fa2115e6d6589a9cef6563 Mon Sep 17 00:00:00 2001 From: "selva.andre" Date: Tue, 7 Aug 2012 23:38:32 +0200 Subject: [PATCH] Fixed the matching of topic with multi selector --- .../spi/impl/SubscriptionsStore.java | 83 ++++++++++++++----- 1 file changed, 60 insertions(+), 23 deletions(-) diff --git a/parser/src/main/java/org/dna/mqtt/moquette/messaging/spi/impl/SubscriptionsStore.java b/parser/src/main/java/org/dna/mqtt/moquette/messaging/spi/impl/SubscriptionsStore.java index 868326ef..f1335450 100644 --- a/parser/src/main/java/org/dna/mqtt/moquette/messaging/spi/impl/SubscriptionsStore.java +++ b/parser/src/main/java/org/dna/mqtt/moquette/messaging/spi/impl/SubscriptionsStore.java @@ -2,8 +2,9 @@ package org.dna.mqtt.moquette.messaging.spi.impl; import java.text.ParseException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; +import java.util.Queue; +import java.util.concurrent.LinkedBlockingQueue; import java.util.logging.Level; import java.util.logging.Logger; @@ -68,22 +69,33 @@ public class SubscriptionsStore { } - /** - * Return next matching node on the tree path, or null if not found any - * match. - */ - TreeNode matchNext(Token token) { - //quite similar to childWithToken - //TODO this should take care of # and + management + void matches(Queue tokens, List matchingSubs) { + Token t = tokens.poll(); + if (t == null) { + matchingSubs.addAll(m_subscriptions); + return; + } + + //check the matching of the current token + //TODO take care of MULTI and SINGLE + + List matchingChildren = new ArrayList(); for (TreeNode child : m_children) { - if (child.getToken().equals(token)) { - return child; + if (child.getToken().match(t)) { + matchingChildren.add(child); } } - return null; + if (matchingChildren.isEmpty()) { + return; + } + + for (TreeNode child : matchingChildren) { + child.matches(tokens, matchingSubs); + } } + /** * Return the number of registered subscriptions */ @@ -112,6 +124,26 @@ public class SubscriptionsStore { return name; } + /** + * Return true iff the current token is compatible with t. + * + * TODO define the rules of compatibility + * if this is a MULTI or SINGLE and the other is any string => match + * of this is a normal token and also the other, and they are equals => match + * if the other is not normal token => don't match + */ + protected boolean match(Token t) { + if (t == MULTI || t == SINGLE) { + return false; + } + + if (this == MULTI || this == SINGLE) { + return true; + } else { + return equals(t); + } + } + @Override public int hashCode() { int hash = 7; @@ -147,6 +179,7 @@ public class SubscriptionsStore { Logger.getLogger(SubscriptionsStore.class.getName()).log(Level.SEVERE, null, ex); } + //Deep into the tree creating missing nodes where necessary TreeNode current = subscriptionsRoot; for (Token token : tokens) { TreeNode matchingChildren; @@ -158,6 +191,7 @@ public class SubscriptionsStore { //create a new node for the newly inserted token matchingChildren = new TreeNode(current); matchingChildren.setToken(token); + current.addChild(matchingChildren); current = matchingChildren; } } @@ -172,18 +206,21 @@ public class SubscriptionsStore { //TODO handle the parse exception Logger.getLogger(SubscriptionsStore.class.getName()).log(Level.SEVERE, null, ex); } - TreeNode current = subscriptionsRoot; - for (Token token : tokens) { - current = current.matchNext(token); - if (current == null) { - break; - } - } - if (current != null) { - return current.subscriptions(); - } else { - return Collections.EMPTY_LIST; - } +// TreeNode current = subscriptionsRoot; + List matchingSubscriptions = new ArrayList(); + subscriptionsRoot.matches(new LinkedBlockingQueue(tokens), matchingSubscriptions); + return matchingSubscriptions; +// for (Token token : tokens) { +// current = current.matchNext(token); +// if (current == null) { +// break; +// } +// } +// if (current != null) { +// return current.subscriptions(); +// } else { +// return Collections.EMPTY_LIST; +// } } public boolean contains(Subscription sub) {