1 /***
2 *
3 * Copyright 2004 Protique Ltd
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 **/
18 package org.codehaus.activemq.filter;
19
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26
27 /***
28 * An implementation class used to implement {@link DestinationMap}
29 *
30 * @version $Revision: 1.4 $
31 */
32 public class DestinationMapNode {
33
34 private List values = new ArrayList();
35 private Map childNodes = new HashMap();
36 private DestinationMapNode anyChild;
37 protected static final String ANY_CHILD = DestinationMap.ANY_CHILD;
38 protected static final String ANY_DESCENDENT = DestinationMap.ANY_DESCENDENT;
39
40
41 /***
42 * Returns the child node for the given named path or null if it does not exist
43 */
44 public DestinationMapNode getChild(String path) {
45 return (DestinationMapNode) childNodes.get(path);
46 }
47
48 /***
49 * Returns the child node for the given named path, lazily creating one if it does
50 * not yet exist
51 */
52 public DestinationMapNode getChildOrCreate(String path) {
53 DestinationMapNode answer = (DestinationMapNode) childNodes.get(path);
54 if (answer == null) {
55 answer = createChildNode();
56 childNodes.put(path, answer);
57 }
58 return answer;
59 }
60
61 /***
62 * Returns the node which represents all children (i.e. the * node)
63 */
64 public DestinationMapNode getAnyChildNode() {
65 if (anyChild == null) {
66 anyChild = createChildNode();
67 }
68 return anyChild;
69 }
70
71 /***
72 * Returns a mutable List of the values available at this node in the tree
73 */
74 public List getValues() {
75 return values;
76 }
77
78 /***
79 * Returns a list of all the values from this node down the tree
80 */
81 public Set getDesendentValues() {
82 Set answer = new HashSet();
83 appendDescendantValues(answer);
84 return answer;
85 }
86
87 public void add(String[] paths, int idx, Object value) {
88 if (idx >= paths.length) {
89 values.add(value);
90 }
91 else {
92 if (idx == paths.length - 1) {
93 getAnyChildNode().getValues().add(value);
94 }
95 else {
96 getAnyChildNode().add(paths, idx + 1, value);
97 }
98 getChildOrCreate(paths[idx]).add(paths, idx + 1, value);
99 }
100 }
101
102 public void remove(String[] paths, int idx, Object value) {
103 if (idx >= paths.length) {
104 values.remove(value);
105 }
106 else {
107 if (idx == paths.length - 1) {
108 getAnyChildNode().getValues().remove(value);
109 }
110 else {
111 getAnyChildNode().remove(paths, idx + 1, value);
112 }
113 getChildOrCreate(paths[idx]).remove(paths, ++idx, value);
114 }
115 }
116
117 protected void appendDescendantValues(Set answer) {
118 answer.addAll(values);
119 if (anyChild != null) {
120 anyChild.appendDescendantValues(answer);
121 }
122 }
123
124 /***
125 * Factory method to create a child node
126 */
127 protected DestinationMapNode createChildNode() {
128 return new DestinationMapNode();
129 }
130
131 public void appendMatchingWildcards(Set answer, String[] paths, int idx) {
132 DestinationMapNode wildCardNode = getChild(ANY_CHILD);
133 if (wildCardNode != null) {
134 wildCardNode.appendMatchingValues(answer, paths, idx + 1);
135 }
136 wildCardNode = getChild(ANY_DESCENDENT);
137 if (wildCardNode != null) {
138 answer.addAll(wildCardNode.getDesendentValues());
139 }
140 }
141
142 public void appendMatchingValues(Set answer, String[] paths, int startIndex) {
143 DestinationMapNode node = this;
144 for (int i = startIndex, size = paths.length; i < size && node != null; i++) {
145 String path = paths[i];
146 if (path.equals(ANY_DESCENDENT)) {
147 answer.addAll(node.getDesendentValues());
148 break;
149 }
150
151 node.appendMatchingWildcards(answer, paths, i);
152 if (path.equals(ANY_CHILD)) {
153 node = node.getAnyChildNode();
154 }
155 else {
156 node = node.getChild(path);
157 }
158 }
159 if (node != null) {
160 answer.addAll(node.getValues());
161 }
162 }
163 }