1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.page.document.psml;
18
19 import java.util.Comparator;
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.Map;
23 import java.util.TreeMap;
24 import java.util.regex.Pattern;
25
26 import org.apache.jetspeed.page.document.Node;
27 import org.apache.jetspeed.page.document.NodeSet;
28
29 /***
30 * <p>
31 * PageSetImpl
32 * </p>
33 * <p>
34 *
35 * </p>
36 *
37 * @author <a href="mailto:weaver@apache.org">Scott T. Weaver </a>
38 * @version $Id: NodeSetImpl.java 568811 2007-08-23 03:00:37Z woonsan $
39 *
40 */
41 public class NodeSetImpl implements NodeSet
42 {
43 private Map nodes;
44 private Map subsets;
45 private String resolveToPath;
46 private Comparator comparator;
47 protected static final Map patternCache = new HashMap();
48
49 public NodeSetImpl( String resolveToPath )
50 {
51 this.resolveToPath = resolveToPath;
52 nodes = new TreeMap();
53 subsets = new HashMap();
54 }
55
56 /***
57 *
58 * @param resolveToPath
59 * @param comparator
60 */
61 public NodeSetImpl( String resolveToPath, Comparator comparator )
62 {
63 this.resolveToPath = resolveToPath;
64 nodes = new TreeMap(comparator);
65 this.comparator = comparator;
66 subsets = new HashMap();
67 }
68
69 /***
70 *
71 * <p>
72 * get
73 * </p>
74 *
75 * @see org.apache.jetspeed.page.document.NodeSet#get(java.lang.String)
76 * @param name
77 * @return
78 */
79 public Node get( String name )
80 {
81
82 if (nodes.containsKey(name))
83 {
84 return (Node) nodes.get(name);
85 }
86 else if (resolveToPath != null)
87 {
88 if (resolveToPath.endsWith(Node.PATH_SEPARATOR))
89 {
90 return (Node) nodes.get(resolveToPath + name);
91 }
92 else
93 {
94 return (Node) nodes.get(resolveToPath + Node.PATH_SEPARATOR + name);
95 }
96 }
97
98 return null;
99 }
100
101 /***
102 *
103 * <p>
104 * add
105 * </p>
106 *
107 * @see org.apache.jetspeed.page.document.NodeSet#add(org.apache.jetspeed.page.document.Node)
108 * @param document
109 */
110 public void add( Node node )
111 {
112 String path = node.getPath();
113 nodes.put(path, node);
114 if (subsets.containsKey(node.getType()))
115 {
116 ((NodeSet) subsets.get(node.getType())).add(node);
117 }
118 }
119
120 /***
121 * <p>
122 * size
123 * </p>
124 *
125 * @see org.apache.jetspeed.page.document.NodeSet#size()
126 * @return
127 */
128 public int size()
129 {
130 return nodes.size();
131 }
132
133 /***
134 *
135 * <p>
136 * iterator
137 * </p>
138 *
139 * @see org.apache.jetspeed.page.document.NodeSet#iterator()
140 * @return
141 */
142 public Iterator iterator()
143 {
144 return nodes.values().iterator();
145 }
146
147 /***
148 * <p>
149 * subset
150 * </p>
151 *
152 * @see org.apache.jetspeed.page.document.NodeSet#subset(java.lang.String)
153 * @param type
154 * @return
155 */
156 public NodeSet subset( String type )
157 {
158 NodeSet subset = (NodeSet) subsets.get(type);
159 if (subset == null)
160 {
161 subset = new NodeSetImpl(resolveToPath, comparator);
162
163 Iterator nodeItr = nodes.values().iterator();
164 while (nodeItr.hasNext())
165 {
166 Node node = (Node) nodeItr.next();
167 if (node.getType().equals(type))
168 {
169 subset.add(node);
170 }
171 }
172
173 synchronized (subsets)
174 {
175 subsets.put(type, subset);
176 }
177 }
178
179 return subset;
180 }
181
182 /***
183 * <p>
184 * exclusiveSubset
185 * </p>
186 *
187 * @see org.apache.jetspeed.page.document.NodeSet#exclusiveSubset(java.lang.String)
188 * @param regex
189 * @return
190 */
191 public NodeSet exclusiveSubset( String regex )
192 {
193 Iterator allNodes = nodes.entrySet().iterator();
194 NodeSetImpl subset = new NodeSetImpl(resolveToPath, comparator);
195 final Pattern pattern = getPattern(regex);
196 while (allNodes.hasNext())
197 {
198 Map.Entry entry = (Map.Entry) allNodes.next();
199 Node node = (Node) entry.getValue();
200 String key = (String) entry.getKey();
201 if (!matches(pattern, key) && !matches(pattern, node.getName()))
202 {
203 subset.add(node);
204 }
205 }
206
207 return subset;
208 }
209
210 /***
211 * <p>
212 * inclusiveSubset
213 * </p>
214 *
215 * @see org.apache.jetspeed.page.document.NodeSet#inclusiveSubset(java.lang.String)
216 * @param regex
217 * @return
218 */
219 public NodeSet inclusiveSubset( String regex )
220 {
221 Iterator allNodes = nodes.entrySet().iterator();
222 NodeSetImpl subset = new NodeSetImpl(resolveToPath, comparator);
223 final Pattern pattern = getPattern(regex);
224 while (allNodes.hasNext())
225 {
226 Map.Entry entry = (Map.Entry) allNodes.next();
227 String key = (String) entry.getKey();
228 Node node = (Node) entry.getValue();
229 if (matches(pattern, key) || matches(pattern, node.getName()))
230 {
231 subset.add(node);
232 }
233 }
234
235 return subset;
236 }
237
238 /***
239 *
240 * <p>
241 * getComparator
242 * </p>
243 *
244 * @return comparator used to order nodes
245 */
246 public Comparator getComparator()
247 {
248 return comparator;
249 }
250
251 /***
252 *
253 * <p>
254 * matches
255 * </p>
256 *
257 * @param pattern
258 * @param value
259 * @return
260 */
261 protected final boolean matches(Pattern pattern, String value)
262 {
263 return pattern.matcher(value).matches();
264 }
265
266 /***
267 *
268 * <p>
269 * getPattern
270 * </p>
271 *
272 * @param regex
273 * @return
274 */
275 protected final Pattern getPattern(String regex)
276 {
277 if(patternCache.containsKey(regex))
278 {
279 return (Pattern)patternCache.get(regex);
280 }
281 else
282 {
283 Pattern pattern = Pattern.compile(regex);
284 patternCache.put(regex, pattern);
285 return pattern;
286 }
287 }
288
289 /***
290 * <p>
291 * contains
292 * </p>
293 *
294 * @see org.apache.jetspeed.page.document.NodeSet#contains()
295 * @return
296 */
297 public boolean contains( Node node )
298 {
299 return nodes.values().contains(node);
300 }
301
302 /***
303 * <p>
304 * isEmpty
305 * </p>
306 *
307 * @see org.apache.jetspeed.page.document.NodeSet#isEmpty()
308 * @return
309 */
310 public boolean isEmpty()
311 {
312 return nodes.isEmpty();
313 }
314
315 /***
316 * <p>
317 * remove
318 * </p>
319 *
320 * @param node to remove
321 * @return removed node
322 */
323 public Node remove(Node node)
324 {
325 String path = node.getPath();
326 if (nodes.get(path) == node)
327 {
328 nodes.remove(path);
329 if (subsets.containsKey(node.getType()))
330 {
331 ((NodeSetImpl) subsets.get(node.getType())).remove(node);
332 }
333 }
334 return null;
335 }
336 }