View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  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  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 }