1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.jxpath.ri.model.beans;
19
20 import java.util.Locale;
21
22 import org.apache.commons.jxpath.JXPathContext;
23 import org.apache.commons.jxpath.JXPathIntrospector;
24 import org.apache.commons.jxpath.ri.Compiler;
25 import org.apache.commons.jxpath.ri.QName;
26 import org.apache.commons.jxpath.ri.compiler.NodeNameTest;
27 import org.apache.commons.jxpath.ri.compiler.NodeTest;
28 import org.apache.commons.jxpath.ri.compiler.NodeTypeTest;
29 import org.apache.commons.jxpath.ri.model.NodeIterator;
30 import org.apache.commons.jxpath.ri.model.NodePointer;
31 import org.apache.commons.jxpath.util.ValueUtils;
32
33
34
35
36 public class CollectionPointer extends NodePointer {
37
38 private static final long serialVersionUID = 8620254915563256588L;
39
40
41
42
43 private Object collection;
44
45
46
47
48 private NodePointer valuePointer;
49
50
51
52
53
54
55
56 public CollectionPointer(final NodePointer parent, final Object collection) {
57 super(parent);
58 this.collection = collection;
59 }
60
61
62
63
64
65
66
67 public CollectionPointer(final Object collection, final Locale locale) {
68 super(null, locale);
69 this.collection = collection;
70 }
71
72 @Override
73 public String asPath() {
74 final StringBuilder buffer = new StringBuilder();
75 final NodePointer parent = getImmediateParentPointer();
76 if (parent != null) {
77 buffer.append(parent.asPath());
78 if (index != WHOLE_COLLECTION) {
79
80 if (parent.getIndex() != WHOLE_COLLECTION) {
81 buffer.append("/.");
82 }
83 buffer.append("[").append(index + 1).append(']');
84 }
85 } else if (index != WHOLE_COLLECTION) {
86 buffer.append("/.[").append(index + 1).append(']');
87 } else {
88 buffer.append("/");
89 }
90 return buffer.toString();
91 }
92
93 @Override
94 public NodeIterator attributeIterator(final QName qName) {
95 return index == WHOLE_COLLECTION ? new CollectionAttributeNodeIterator(this, qName) : getValuePointer().attributeIterator(qName);
96 }
97
98 @Override
99 public NodeIterator childIterator(final NodeTest test, final boolean reverse, final NodePointer startWith) {
100 if (index == WHOLE_COLLECTION) {
101 return new CollectionChildNodeIterator(this, test, reverse, startWith);
102 }
103 return getValuePointer().childIterator(test, reverse, startWith);
104 }
105
106 @Override
107 public int compareChildNodePointers(final NodePointer pointer1, final NodePointer pointer2) {
108 return pointer1.getIndex() - pointer2.getIndex();
109 }
110
111 @Override
112 public NodePointer createChild(final JXPathContext context, final QName qName, final int index) {
113 final NodePointer ptr = (NodePointer) clone();
114 ptr.setIndex(index);
115 return ptr.createPath(context);
116 }
117
118 @Override
119 public NodePointer createChild(final JXPathContext context, final QName qName, final int index, final Object value) {
120 final NodePointer ptr = (NodePointer) clone();
121 ptr.setIndex(index);
122 return ptr.createPath(context, value);
123 }
124
125 @Override
126 public NodePointer createPath(final JXPathContext context) {
127 if (ValueUtils.getLength(getBaseValue()) <= index) {
128 collection = ValueUtils.expandCollection(getNode(), index + 1);
129 }
130 return this;
131 }
132
133 @Override
134 public NodePointer createPath(final JXPathContext context, final Object value) {
135 final NodePointer ptr = createPath(context);
136 ptr.setValue(value);
137 return ptr;
138 }
139
140 @Override
141 public boolean equals(final Object object) {
142 if (object == this) {
143 return true;
144 }
145 if (!(object instanceof CollectionPointer)) {
146 return false;
147 }
148 final CollectionPointer other = (CollectionPointer) object;
149 return collection == other.collection && index == other.index;
150 }
151
152 @Override
153 public Object getBaseValue() {
154 return collection;
155 }
156
157 @Override
158 public Object getImmediateNode() {
159 return index == WHOLE_COLLECTION ? ValueUtils.getValue(collection) : ValueUtils.getValue(collection, index);
160 }
161
162 @Override
163 public int getLength() {
164 return ValueUtils.getLength(getBaseValue());
165 }
166
167 @Override
168 public QName getName() {
169 return null;
170 }
171
172 @Override
173 public NodePointer getValuePointer() {
174 if (valuePointer == null) {
175 if (index == WHOLE_COLLECTION) {
176 valuePointer = this;
177 } else {
178 final Object value = getImmediateNode();
179 valuePointer = newChildNodePointer(this, getName(), value);
180 }
181 }
182 return valuePointer;
183 }
184
185 @Override
186 public int hashCode() {
187 return System.identityHashCode(collection) + index;
188 }
189
190 @Override
191 public boolean isCollection() {
192 return true;
193 }
194
195 @Override
196 public boolean isContainer() {
197 return index != WHOLE_COLLECTION;
198 }
199
200 @Override
201 public boolean isLeaf() {
202 final Object value = getNode();
203 return value == null || JXPathIntrospector.getBeanInfo(value.getClass()).isAtomic();
204 }
205
206 @Override
207 public NodeIterator namespaceIterator() {
208 return index == WHOLE_COLLECTION ? null : getValuePointer().namespaceIterator();
209 }
210
211 @Override
212 public NodePointer namespacePointer(final String namespace) {
213 return index == WHOLE_COLLECTION ? null : getValuePointer().namespacePointer(namespace);
214 }
215
216 @Override
217 public void setIndex(final int index) {
218 super.setIndex(index);
219 valuePointer = null;
220 }
221
222 @Override
223 public void setValue(final Object value) {
224 if (index == WHOLE_COLLECTION) {
225 parent.setValue(value);
226 } else {
227 ValueUtils.setValue(collection, index, value);
228 }
229 }
230
231 @Override
232 public boolean testNode(final NodeTest test) {
233 if (index == WHOLE_COLLECTION) {
234 if (test == null) {
235 return true;
236 }
237 if (test instanceof NodeNameTest) {
238 return false;
239 }
240 return test instanceof NodeTypeTest && ((NodeTypeTest) test).getNodeType() == Compiler.NODE_TYPE_NODE;
241 }
242 return getValuePointer().testNode(test);
243 }
244 }