1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package groovy.util.slurpersupport;
19
20 import groovy.lang.Buildable;
21 import groovy.lang.Closure;
22 import groovy.lang.GroovyObject;
23 import groovy.lang.GroovyRuntimeException;
24
25 import java.io.IOException;
26 import java.io.Writer;
27 import java.util.Iterator;
28 import java.util.Map;
29
30 import org.codehaus.groovy.runtime.InvokerHelper;
31
32 /***
33 * @author John Wilson
34 *
35 */
36
37 class NodeChildren extends GPathResult {
38 private int size = -1;
39
40 /***
41 * @param parent
42 * @param name
43 * @param namespacePrefix
44 */
45 public NodeChildren(final GPathResult parent, final String name, final String namespacePrefix, final Map namespaceTagHints) {
46 super(parent, name, namespacePrefix, namespaceTagHints);
47 }
48
49 /***
50 * @param parent
51 * @param name
52 */
53 public NodeChildren(final GPathResult parent, final String name, final Map namespaceTagHints) {
54 this(parent, name, "*", namespaceTagHints);
55 }
56
57 /***
58 * @param parent
59 */
60 public NodeChildren(final GPathResult parent, final Map namespaceTagHints) {
61 this(parent, "*", namespaceTagHints);
62 }
63
64
65
66
67 public Iterator childNodes() {
68 return new Iterator() {
69 private final Iterator iter = NodeChildren.this.parent.childNodes();
70 private Iterator childIter = nextChildIter();
71
72
73
74
75 public boolean hasNext() {
76 return this.childIter != null;
77 }
78
79
80
81
82 public Object next() {
83 while (this.childIter != null) {
84 try {
85 if (this.childIter.hasNext()) {
86 return this.childIter.next();
87 }
88 } finally {
89 if (!this.childIter.hasNext()) {
90 this.childIter = nextChildIter();
91 }
92 }
93 }
94
95 return null;
96 }
97
98
99
100
101 public void remove() {
102 throw new UnsupportedOperationException();
103 }
104
105 /***
106 * @return
107 */
108 private Iterator nextChildIter() {
109 while (this.iter.hasNext()) {
110 final Node node = (Node)this.iter.next();
111
112 if (NodeChildren.this.name.equals(node.name())) {
113 final Iterator result = node.childNodes();
114
115 if (result.hasNext()) {
116 if ("*".equals(NodeChildren.this.namespacePrefix) ||
117 ("".equals(NodeChildren.this.namespacePrefix) && "".equals(node.namespaceURI())) ||
118 node.namespaceURI().equals(NodeChildren.this.namespaceMap.get(NodeChildren.this.namespacePrefix)))
119 {
120 return result;
121 }
122 }
123 }
124 }
125
126 return null;
127 }
128 };
129 }
130
131
132
133
134 public Iterator iterator() {
135 return new Iterator() {
136 final Iterator iter = nodeIterator();
137
138 public boolean hasNext() {
139 return this.iter.hasNext();
140 }
141
142 public Object next() {
143 return new NodeChild((Node)this.iter.next(), NodeChildren.this.parent, NodeChildren.this.namespaceTagHints);
144 }
145
146 public void remove() {
147 throw new UnsupportedOperationException();
148 }
149 };
150 }
151
152
153
154
155 public Iterator nodeIterator() {
156 if ("*".equals(this.name)) {
157 return this.parent.childNodes();
158 } else {
159 return new NodeIterator(this.parent.childNodes()) {
160
161
162
163 protected Object getNextNode(Iterator iter) {
164 while (iter.hasNext()) {
165 final Node node = (Node)iter.next();
166
167 if (NodeChildren.this.name.equals(node.name())) {
168 if ("*".equals(NodeChildren.this.namespacePrefix) ||
169 ("".equals(NodeChildren.this.namespacePrefix) && "".equals(node.namespaceURI())) ||
170 node.namespaceURI().equals(NodeChildren.this.namespaceMap.get(NodeChildren.this.namespacePrefix)))
171 {
172 return node;
173 }
174 }
175 }
176
177 return null;
178 }
179 };
180 }
181 }
182
183
184
185
186 public GPathResult parents() {
187
188 throw new GroovyRuntimeException("parents() not implemented yet");
189 }
190
191
192
193
194 public synchronized int size() {
195 if (this.size == -1) {
196 final Iterator iter = nodeIterator();
197
198 this.size = 0;
199 while (iter.hasNext()) {
200 iter.next();
201 this.size++;
202 }
203 }
204
205 return this.size;
206 }
207
208
209
210
211 public String text() {
212 final StringBuffer buf = new StringBuffer();
213 final Iterator iter = nodeIterator();
214
215 while (iter.hasNext()) {
216 buf.append(((Node)iter.next()).text());
217 }
218
219 return buf.toString();
220 }
221
222
223
224
225 public GPathResult find(final Closure closure) {
226 final Iterator iter = iterator();
227
228 while (iter.hasNext()) {
229 final Object node = iter.next();
230
231 if (InvokerHelper.asBool(closure.call(new Object[]{node}))) {
232 return (GPathResult)node;
233 }
234 }
235
236 return new NoChildren(this, this.name, this.namespaceTagHints);
237 }
238
239
240
241
242 public GPathResult findAll(final Closure closure) {
243 return new FilteredNodeChildren(this, closure, this.namespaceTagHints);
244 }
245
246
247
248
249 public void build(final GroovyObject builder) {
250 final Iterator iter = nodeIterator();
251
252 while (iter.hasNext()) {
253 final Object next = iter.next();
254
255 if (next instanceof Buildable) {
256 ((Buildable)next).build(builder);
257 } else {
258 ((Node)next).build(builder, this.namespaceMap, this.namespaceTagHints);
259 }
260 }
261 }
262
263
264
265
266 public Writer writeTo(final Writer out) throws IOException {
267 final Iterator iter = nodeIterator();
268
269 while (iter.hasNext()) {
270 ((Node)iter.next()).writeTo(out);
271 }
272
273 return out;
274 }
275 }