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
18 package org.apache.commons.jxpath;
19
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.List;
23 import java.util.stream.Collectors;
24
25 /**
26 * A simple implementation of {@link NodeSet} that behaves as a collection of pointers.
27 */
28 public class BasicNodeSet implements NodeSet {
29
30 private final List<Pointer> pointers = new ArrayList<>();
31 private List<Pointer> readOnlyPointers;
32 private List nodes;
33 private List values;
34
35 /**
36 * Constructs a new instance.
37 */
38 public BasicNodeSet() {
39 // empty
40 }
41
42 /**
43 * Add the specified NodeSet to this NodeSet.
44 *
45 * @param nodeSet to add
46 */
47 public void add(final NodeSet nodeSet) {
48 if (pointers.addAll(nodeSet.getPointers())) {
49 clear();
50 }
51 }
52
53 /**
54 * Add a pointer to this NodeSet.
55 *
56 * @param pointer to add
57 */
58 public void add(final Pointer pointer) {
59 if (pointers.add(pointer)) {
60 clear();
61 }
62 }
63
64 /**
65 * Clear cache list members.
66 */
67 private synchronized void clear() {
68 readOnlyPointers = null;
69 nodes = null;
70 values = null;
71 }
72
73 @Override
74 public synchronized List getNodes() {
75 if (nodes == null) {
76 nodes = Collections.unmodifiableList(pointers.stream().map(Pointer::getNode).collect(Collectors.toList()));
77 }
78 return nodes;
79 }
80
81 @Override
82 public synchronized List<Pointer> getPointers() {
83 if (readOnlyPointers == null) {
84 readOnlyPointers = Collections.unmodifiableList(pointers);
85 }
86 return readOnlyPointers;
87 }
88
89 @Override
90 public synchronized List getValues() {
91 if (values == null) {
92 values = Collections.unmodifiableList(pointers.stream().map(Pointer::getValue).collect(Collectors.toList()));
93 }
94 return values;
95 }
96
97 /**
98 * Remove a pointer from this NodeSet.
99 *
100 * @param pointer to remove
101 */
102 public void remove(final Pointer pointer) {
103 if (pointers.remove(pointer)) {
104 clear();
105 }
106 }
107
108 @Override
109 public String toString() {
110 return pointers.toString();
111 }
112 }