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 516448 2007-03-09 16:25:47Z ate $
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 subsets.put(type, subset);
163
164 Iterator nodeItr = nodes.values().iterator();
165 while (nodeItr.hasNext())
166 {
167 Node node = (Node) nodeItr.next();
168 if (node.getType().equals(type))
169 {
170 subset.add(node);
171 }
172 }
173 }
174
175 return subset;
176 }
177
178 /***
179 * <p>
180 * exclusiveSubset
181 * </p>
182 *
183 * @see org.apache.jetspeed.page.document.NodeSet#exclusiveSubset(java.lang.String)
184 * @param regex
185 * @return
186 */
187 public NodeSet exclusiveSubset( String regex )
188 {
189 Iterator allNodes = nodes.entrySet().iterator();
190 NodeSetImpl subset = new NodeSetImpl(resolveToPath, comparator);
191 final Pattern pattern = getPattern(regex);
192 while (allNodes.hasNext())
193 {
194 Map.Entry entry = (Map.Entry) allNodes.next();
195 Node node = (Node) entry.getValue();
196 String key = (String) entry.getKey();
197 if (!matches(pattern, key) && !matches(pattern, node.getName()))
198 {
199 subset.add(node);
200 }
201 }
202
203 return subset;
204 }
205
206 /***
207 * <p>
208 * inclusiveSubset
209 * </p>
210 *
211 * @see org.apache.jetspeed.page.document.NodeSet#inclusiveSubset(java.lang.String)
212 * @param regex
213 * @return
214 */
215 public NodeSet inclusiveSubset( String regex )
216 {
217 Iterator allNodes = nodes.entrySet().iterator();
218 NodeSetImpl subset = new NodeSetImpl(resolveToPath, comparator);
219 final Pattern pattern = getPattern(regex);
220 while (allNodes.hasNext())
221 {
222 Map.Entry entry = (Map.Entry) allNodes.next();
223 String key = (String) entry.getKey();
224 Node node = (Node) entry.getValue();
225 if (matches(pattern, key) || matches(pattern, node.getName()))
226 {
227 subset.add(node);
228 }
229 }
230
231 return subset;
232 }
233
234 /***
235 *
236 * <p>
237 * getComparator
238 * </p>
239 *
240 * @return comparator used to order nodes
241 */
242 public Comparator getComparator()
243 {
244 return comparator;
245 }
246
247 /***
248 *
249 * <p>
250 * matches
251 * </p>
252 *
253 * @param pattern
254 * @param value
255 * @return
256 */
257 protected final boolean matches(Pattern pattern, String value)
258 {
259 return pattern.matcher(value).matches();
260 }
261
262 /***
263 *
264 * <p>
265 * getPattern
266 * </p>
267 *
268 * @param regex
269 * @return
270 */
271 protected final Pattern getPattern(String regex)
272 {
273 if(patternCache.containsKey(regex))
274 {
275 return (Pattern)patternCache.get(regex);
276 }
277 else
278 {
279 Pattern pattern = Pattern.compile(regex);
280 patternCache.put(regex, pattern);
281 return pattern;
282 }
283 }
284
285 /***
286 * <p>
287 * contains
288 * </p>
289 *
290 * @see org.apache.jetspeed.page.document.NodeSet#contains()
291 * @return
292 */
293 public boolean contains( Node node )
294 {
295 return nodes.values().contains(node);
296 }
297
298 /***
299 * <p>
300 * isEmpty
301 * </p>
302 *
303 * @see org.apache.jetspeed.page.document.NodeSet#isEmpty()
304 * @return
305 */
306 public boolean isEmpty()
307 {
308 return nodes.isEmpty();
309 }
310
311 /***
312 * <p>
313 * remove
314 * </p>
315 *
316 * @param node to remove
317 * @return removed node
318 */
319 public Node remove(Node node)
320 {
321 String path = node.getPath();
322 if (nodes.get(path) == node)
323 {
324 nodes.remove(path);
325 if (subsets.containsKey(node.getType()))
326 {
327 ((NodeSetImpl) subsets.get(node.getType())).remove(node);
328 }
329 }
330 return null;
331 }
332 }