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