KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > activemq > filter > DestinationMap


1 /**
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one or more
4  * contributor license agreements. See the NOTICE file distributed with
5  * this work for additional information regarding copyright ownership.
6  * The ASF licenses this file to You under the Apache License, Version 2.0
7  * (the "License"); you may not use this file except in compliance with
8  * the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package org.apache.activemq.filter;
19
20 import java.util.HashSet JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Set JavaDoc;
24 import java.util.SortedSet JavaDoc;
25 import java.util.TreeSet JavaDoc;
26
27 import org.apache.activemq.command.ActiveMQDestination;
28
29 /**
30  * A Map-like data structure allowing values to be indexed by
31  * {@link ActiveMQDestination} and retrieved by destination - supporting both *
32  * and &gt; style of wildcard as well as composite destinations. <br>
33  * This class assumes that the index changes rarely but that fast lookup into
34  * the index is required. So this class maintains a pre-calculated index for
35  * destination steps. So looking up the values for "TEST.*" or "*.TEST" will be
36  * pretty fast. <br>
37  * Looking up of a value could return a single value or a List of matching
38  * values if a wildcard or composite destination is used.
39  *
40  * @version $Revision: 1.3 $
41  */

42 public class DestinationMap {
43     protected static final String JavaDoc ANY_DESCENDENT = DestinationFilter.ANY_DESCENDENT;
44     protected static final String JavaDoc ANY_CHILD = DestinationFilter.ANY_CHILD;
45
46     private DestinationMapNode queueRootNode = new DestinationMapNode(null);
47     private DestinationMapNode topicRootNode = new DestinationMapNode(null);
48
49     /**
50      * Looks up the value(s) matching the given Destination key. For simple
51      * destinations this is typically a List of one single value, for wildcards
52      * or composite destinations this will typically be a List of matching
53      * values.
54      *
55      * @param key
56      * the destination to lookup
57      * @return a List of matching values or an empty list if there are no
58      * matching values.
59      */

60     public synchronized Set JavaDoc get(ActiveMQDestination key) {
61         if (key.isComposite()) {
62             ActiveMQDestination[] destinations = key.getCompositeDestinations();
63             Set JavaDoc answer = new HashSet JavaDoc(destinations.length);
64             for (int i = 0; i < destinations.length; i++) {
65                 ActiveMQDestination childDestination = destinations[i];
66                 Object JavaDoc value = get(childDestination);
67                 if (value instanceof Set JavaDoc) {
68                     answer.addAll((Set JavaDoc) value);
69                 }
70                 else if (value != null) {
71                     answer.add(value);
72                 }
73             }
74             return answer;
75         }
76         return findWildcardMatches(key);
77     }
78
79     public synchronized void put(ActiveMQDestination key, Object JavaDoc value) {
80         if (key.isComposite()) {
81             ActiveMQDestination[] destinations = key.getCompositeDestinations();
82             for (int i = 0; i < destinations.length; i++) {
83                 ActiveMQDestination childDestination = destinations[i];
84                 put(childDestination, value);
85             }
86             return;
87         }
88         String JavaDoc[] paths = key.getDestinationPaths();
89         getRootNode(key).add(paths, 0, value);
90     }
91
92     /**
93      * Removes the value from the associated destination
94      */

95     public synchronized void remove(ActiveMQDestination key, Object JavaDoc value) {
96         if (key.isComposite()) {
97             ActiveMQDestination[] destinations = key.getCompositeDestinations();
98             for (int i = 0; i < destinations.length; i++) {
99                 ActiveMQDestination childDestination = destinations[i];
100                 remove(childDestination, value);
101             }
102             return;
103         }
104         String JavaDoc[] paths = key.getDestinationPaths();
105         getRootNode(key).remove(paths, 0, value);
106
107     }
108
109     public int getTopicRootChildCount() {
110         return topicRootNode.getChildCount();
111     }
112     
113     public int getQueueRootChildCount() {
114         return queueRootNode.getChildCount();
115     }
116
117     public DestinationMapNode getQueueRootNode() {
118         return queueRootNode;
119     }
120
121     public DestinationMapNode getTopicRootNode() {
122         return topicRootNode;
123     }
124
125     
126     // Implementation methods
127
// -------------------------------------------------------------------------
128

129     /**
130      * A helper method to allow the destination map to be populated from a
131      * dependency injection framework such as Spring
132      */

133     protected void setEntries(List JavaDoc entries) {
134         for (Iterator JavaDoc iter = entries.iterator(); iter.hasNext();) {
135             Object JavaDoc element = (Object JavaDoc) iter.next();
136             Class JavaDoc type = getEntryClass();
137             if (type.isInstance(element)) {
138                 DestinationMapEntry entry = (DestinationMapEntry) element;
139                 put(entry.getDestination(), entry.getValue());
140             }
141             else {
142                 throw new IllegalArgumentException JavaDoc("Each entry must be an instance of type: " + type.getName() + " but was: " + element);
143             }
144         }
145     }
146
147     /**
148      * Returns the type of the allowed entries which can be set via the
149      * {@link #setEntries(List)} method. This allows derived classes to further
150      * restrict the type of allowed entries to make a type safe destination map
151      * for custom policies.
152      */

153     protected Class JavaDoc getEntryClass() {
154         return DestinationMapEntry.class;
155     }
156
157     protected Set JavaDoc findWildcardMatches(ActiveMQDestination key) {
158         String JavaDoc[] paths = key.getDestinationPaths();
159         Set JavaDoc answer = new HashSet JavaDoc();
160         getRootNode(key).appendMatchingValues(answer, paths, 0);
161         return answer;
162     }
163
164     /**
165      * @param key
166      * @return
167      */

168     public Set JavaDoc removeAll(ActiveMQDestination key) {
169         Set JavaDoc rc = new HashSet JavaDoc();
170         if (key.isComposite()) {
171             ActiveMQDestination[] destinations = key.getCompositeDestinations();
172             for (int i = 0; i < destinations.length; i++) {
173                 rc.add( removeAll(destinations[i]) );
174             }
175             return rc;
176         }
177         String JavaDoc[] paths = key.getDestinationPaths();
178         getRootNode(key).removeAll(rc, paths, 0);
179         return rc;
180     }
181
182     /**
183      * Returns the value which matches the given destination or null if there is
184      * no matching value. If there are multiple values, the results are sorted
185      * and the last item (the biggest) is returned.
186      *
187      * @param destination
188      * the destination to find the value for
189      * @return the largest matching value or null if no value matches
190      */

191     public Object JavaDoc chooseValue(ActiveMQDestination destination) {
192         Set JavaDoc set = get(destination);
193         if (set == null || set.isEmpty()) {
194             return null;
195         }
196         SortedSet JavaDoc sortedSet = new TreeSet JavaDoc(set);
197         return sortedSet.last();
198     }
199
200     /**
201      * Returns the root node for the given destination type
202      */

203     protected DestinationMapNode getRootNode(ActiveMQDestination key) {
204         if (key.isQueue()) {
205             return queueRootNode;
206         }
207         else {
208             return topicRootNode;
209         }
210     }
211 }
212
Popular Tags