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.commons.jxpath;
018    
019    import java.util.ArrayList;
020    import java.util.Collections;
021    import java.util.List;
022    
023    /**
024     * A simple implementation of {@link NodeSet} that behaves as a collection
025     * of pointers.
026     *
027     * @author Dmitri Plotnikov
028     * @version $Revision: 652845 $ $Date: 2008-05-02 12:46:46 -0500 (Fri, 02 May 2008) $
029     */
030    public class BasicNodeSet implements NodeSet {
031        private List pointers = new ArrayList();
032        private List readOnlyPointers;
033        private List nodes;
034        private List values;
035    
036        /**
037         * Add a pointer to this NodeSet.
038         * @param pointer to add
039         */
040        public void add(Pointer pointer) {
041            if (pointers.add(pointer)) {
042                clearCacheLists();
043            }
044        }
045    
046        /**
047         * Add the specified NodeSet to this NodeSet.
048         * @param nodeSet to add
049         */
050        public void add(NodeSet nodeSet) {
051            if (pointers.addAll(nodeSet.getPointers())) {
052                clearCacheLists();
053            }
054        }
055    
056        /**
057         * Remove a pointer from this NodeSet.
058         * @param pointer to remove
059         */
060        public void remove(Pointer pointer) {
061            if (pointers.remove(pointer)) {
062                clearCacheLists();
063            }
064        }
065    
066        public synchronized List getPointers() {
067            if (readOnlyPointers == null) {
068                readOnlyPointers = Collections.unmodifiableList(pointers);
069            }
070            return readOnlyPointers;
071        }
072    
073        public synchronized List getNodes() {
074            if (nodes == null) {
075                nodes = new ArrayList();
076                for (int i = 0; i < pointers.size(); i++) {
077                    Pointer pointer = (Pointer) pointers.get(i);
078                    nodes.add(pointer.getNode());
079                }
080                nodes = Collections.unmodifiableList(nodes);
081            }
082            return nodes;
083        }
084    
085        public synchronized List getValues() {
086            if (values == null) {
087                values = new ArrayList();
088                for (int i = 0; i < pointers.size(); i++) {
089                    Pointer pointer = (Pointer) pointers.get(i);
090                    values.add(pointer.getValue());
091                }
092                values = Collections.unmodifiableList(values);
093            }
094            return values;
095        }
096    
097        public String toString() {
098            return pointers.toString();
099        }
100    
101        /**
102         * Clear cache list members.
103         */
104        private synchronized void clearCacheLists() {
105            readOnlyPointers = null;
106            nodes = null;
107            values = null;
108        }
109    
110    }