001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jetspeed.page.document.impl;
018:
019: import java.util.Comparator;
020: import java.util.Iterator;
021: import java.util.List;
022: import java.util.Map;
023: import java.util.TreeMap;
024: import java.util.regex.Pattern;
025:
026: import org.apache.commons.collections.map.LRUMap;
027: import org.apache.jetspeed.page.document.Node;
028: import org.apache.jetspeed.page.document.NodeSet;
029:
030: /**
031: * NodeSetImpl
032: *
033: * @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
034: * @version $Id$
035: */
036: public class NodeSetImpl implements NodeSet {
037: public static final NodeSetImpl EMPTY_NODE_SET = new NodeSetImpl();
038:
039: private static final Map patternCache = new LRUMap(128);
040:
041: private Map nodes;
042: private Comparator comparator;
043:
044: public NodeSetImpl(List nodes, Comparator comparator) {
045: this .nodes = new TreeMap(comparator);
046: Object[] nodeToCopy = nodes.toArray();
047: for (int ix = 0; ix < nodeToCopy.length; ix++) {
048: Node node = (Node) nodeToCopy[ix];
049: if (!this .nodes.containsKey(node.getName())) {
050: this .nodes.put(node.getName(), node);
051: }
052: }
053: this .comparator = comparator;
054: }
055:
056: public NodeSetImpl(List nodes) {
057: this (nodes, null);
058: }
059:
060: public NodeSetImpl(Comparator comparator) {
061: this .comparator = comparator;
062: }
063:
064: public NodeSetImpl(NodeSet nodeSet) {
065: this (
066: (nodeSet instanceof NodeSetImpl) ? ((NodeSetImpl) nodeSet).comparator
067: : (Comparator) null);
068: }
069:
070: public NodeSetImpl() {
071: }
072:
073: /**
074: * getCachedPattern
075: *
076: * @param regex pattern
077: * @return cached pattern
078: */
079: private Pattern getCachedPattern(String regex) {
080: synchronized (patternCache) {
081: if (patternCache.containsKey(regex)) {
082: return (Pattern) patternCache.get(regex);
083: } else {
084: Pattern pattern = Pattern.compile(regex);
085: patternCache.put(regex, pattern);
086: return pattern;
087: }
088: }
089: }
090:
091: /* (non-Javadoc)
092: * @see org.apache.jetspeed.page.document.NodeSet#add(org.apache.jetspeed.page.document.Node)
093: */
094: public void add(Node node) {
095: if (nodes == null) {
096: nodes = new TreeMap(comparator);
097: }
098: if (!nodes.containsKey(node.getName())) {
099: nodes.put(node.getName(), node);
100: }
101: }
102:
103: /* (non-Javadoc)
104: * @see org.apache.jetspeed.page.document.NodeSet#get(java.lang.String)
105: */
106: public Node get(String name) {
107: if (nodes != null) {
108: return (Node) nodes.get(name);
109: }
110: return null;
111: }
112:
113: /* (non-Javadoc)
114: * @see org.apache.jetspeed.page.document.NodeSet#iterator()
115: */
116: public Iterator iterator() {
117: if (nodes == null) {
118: nodes = new TreeMap(comparator);
119: }
120: return nodes.values().iterator();
121: }
122:
123: /* (non-Javadoc)
124: * @see org.apache.jetspeed.page.document.NodeSet#subset(java.lang.String)
125: */
126: public NodeSet subset(String type) {
127: NodeSetImpl subset = new NodeSetImpl(comparator);
128: Iterator nodeItr = iterator();
129: while (nodeItr.hasNext()) {
130: Node node = (Node) nodeItr.next();
131: if (node.getType().equals(type)) {
132: subset.add(node);
133: }
134: }
135: return subset;
136: }
137:
138: /* (non-Javadoc)
139: * @see org.apache.jetspeed.page.document.NodeSet#inclusiveSubset(java.lang.String)
140: */
141: public NodeSet inclusiveSubset(String regex) {
142: Pattern pattern = getCachedPattern(regex);
143: NodeSetImpl subset = new NodeSetImpl(comparator);
144: Iterator nodeItr = iterator();
145: while (nodeItr.hasNext()) {
146: Node node = (Node) nodeItr.next();
147: if (pattern.matcher(node.getName()).matches()) {
148: subset.add(node);
149: }
150: }
151: return subset;
152: }
153:
154: /* (non-Javadoc)
155: * @see org.apache.jetspeed.page.document.NodeSet#exclusiveSubset(java.lang.String)
156: */
157: public NodeSet exclusiveSubset(String regex) {
158: Pattern pattern = getCachedPattern(regex);
159: NodeSetImpl subset = new NodeSetImpl(comparator);
160: Iterator nodeItr = iterator();
161: while (nodeItr.hasNext()) {
162: Node node = (Node) nodeItr.next();
163: if (!pattern.matcher(node.getName()).matches()) {
164: subset.add(node);
165: }
166: }
167: return subset;
168: }
169:
170: /* (non-Javadoc)
171: * @see org.apache.jetspeed.page.document.NodeSet#size()
172: */
173: public int size() {
174: if (nodes != null) {
175: return nodes.size();
176: }
177: return 0;
178: }
179:
180: /* (non-Javadoc)
181: * @see org.apache.jetspeed.page.document.NodeSet#contains(org.apache.jetspeed.page.document.Node)
182: */
183: public boolean contains(Node node) {
184: if (nodes != null) {
185: return nodes.containsValue(node);
186: }
187: return false;
188: }
189:
190: /* (non-Javadoc)
191: * @see org.apache.jetspeed.page.document.NodeSet#isEmpty()
192: */
193: public boolean isEmpty() {
194: if (nodes != null) {
195: return nodes.isEmpty();
196: }
197: return true;
198: }
199: }
|