1 package org.apache.velocity.anakia;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.IOException;
23 import java.io.StringWriter;
24 import java.io.Writer;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.ListIterator;
30
31 import org.jdom.Attribute;
32 import org.jdom.CDATA;
33 import org.jdom.Comment;
34 import org.jdom.DocType;
35 import org.jdom.Document;
36 import org.jdom.Element;
37 import org.jdom.EntityRef;
38 import org.jdom.ProcessingInstruction;
39 import org.jdom.Text;
40 import org.jdom.output.XMLOutputter;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public class NodeList implements List, Cloneable
57 {
58 private static final AttributeXMLOutputter DEFAULT_OUTPUTTER =
59 new AttributeXMLOutputter();
60
61
62 private List nodes;
63
64
65
66
67 public NodeList()
68 {
69 nodes = new ArrayList();
70 }
71
72
73
74
75
76 public NodeList(Document document)
77 {
78 this((Object)document);
79 }
80
81
82
83
84
85 public NodeList(Element element)
86 {
87 this((Object)element);
88 }
89
90 private NodeList(Object object)
91 {
92 if(object == null)
93 {
94 throw new IllegalArgumentException(
95 "Cannot construct NodeList with null.");
96 }
97 nodes = new ArrayList(1);
98 nodes.add(object);
99 }
100
101
102
103
104
105
106
107 public NodeList(List nodes)
108 {
109 this(nodes, true);
110 }
111
112
113
114
115
116
117
118
119
120 public NodeList(List nodes, boolean copy)
121 {
122 if(nodes == null)
123 {
124 throw new IllegalArgumentException(
125 "Cannot initialize NodeList with null list");
126 }
127 this.nodes = copy ? new ArrayList(nodes) : nodes;
128 }
129
130
131
132
133
134
135
136
137 public List getList()
138 {
139 return nodes;
140 }
141
142
143
144
145
146
147
148
149
150
151 public String toString()
152 {
153 if(nodes.isEmpty())
154 {
155 return "";
156 }
157
158 StringWriter sw = new StringWriter(nodes.size() * 128);
159 try
160 {
161 for(Iterator i = nodes.iterator(); i.hasNext();)
162 {
163 Object node = i.next();
164 if(node instanceof Element)
165 {
166 DEFAULT_OUTPUTTER.output((Element)node, sw);
167 }
168 else if(node instanceof Attribute)
169 {
170 DEFAULT_OUTPUTTER.output((Attribute)node, sw);
171 }
172 else if(node instanceof Text)
173 {
174 DEFAULT_OUTPUTTER.output((Text)node, sw);
175 }
176 else if(node instanceof Document)
177 {
178 DEFAULT_OUTPUTTER.output((Document)node, sw);
179 }
180 else if(node instanceof ProcessingInstruction)
181 {
182 DEFAULT_OUTPUTTER.output((ProcessingInstruction)node, sw);
183 }
184 else if(node instanceof Comment)
185 {
186 DEFAULT_OUTPUTTER.output((Comment)node, sw);
187 }
188 else if(node instanceof CDATA)
189 {
190 DEFAULT_OUTPUTTER.output((CDATA)node, sw);
191 }
192 else if(node instanceof DocType)
193 {
194 DEFAULT_OUTPUTTER.output((DocType)node, sw);
195 }
196 else if(node instanceof EntityRef)
197 {
198 DEFAULT_OUTPUTTER.output((EntityRef)node, sw);
199 }
200 else
201 {
202 throw new IllegalArgumentException(
203 "Cannot process a " +
204 (node == null
205 ? "null node"
206 : "node of class " + node.getClass().getName()));
207 }
208 }
209 }
210 catch(IOException e)
211 {
212
213 throw new Error();
214 }
215 return sw.toString();
216 }
217
218
219
220
221
222
223
224 public Object clone()
225 throws CloneNotSupportedException
226 {
227 NodeList clonedList = (NodeList)super.clone();
228 clonedList.cloneNodes();
229 return clonedList;
230 }
231
232 private void cloneNodes()
233 throws CloneNotSupportedException
234 {
235 Class listClass = nodes.getClass();
236 try
237 {
238 List clonedNodes = (List)listClass.newInstance();
239 clonedNodes.addAll(nodes);
240 nodes = clonedNodes;
241 }
242 catch(IllegalAccessException e)
243 {
244 throw new CloneNotSupportedException("Cannot clone NodeList since"
245 + " there is no accessible no-arg constructor on class "
246 + listClass.getName());
247 }
248 catch(InstantiationException e)
249 {
250
251
252
253 throw new Error();
254 }
255 }
256
257
258
259
260
261 public int hashCode()
262 {
263 return nodes.hashCode();
264 }
265
266
267
268
269
270
271
272 public boolean equals(Object o)
273 {
274 return o instanceof NodeList
275 ? ((NodeList)o).nodes.equals(nodes)
276 : false;
277 }
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293 public NodeList selectNodes(String xpathString)
294 {
295 return new NodeList(XPathCache.getXPath(xpathString).applyTo(nodes), false);
296 }
297
298
299
300
301
302
303 public boolean add(Object o)
304 {
305 return nodes.add(o);
306 }
307
308
309
310
311 public void add(int index, Object o)
312 {
313 nodes.add(index, o);
314 }
315
316
317
318
319 public boolean addAll(Collection c)
320 {
321 return nodes.addAll(c);
322 }
323
324
325
326
327 public boolean addAll(int index, Collection c)
328 {
329 return nodes.addAll(index, c);
330 }
331
332
333
334
335 public void clear()
336 {
337 nodes.clear();
338 }
339
340
341
342
343 public boolean contains(Object o)
344 {
345 return nodes.contains(o);
346 }
347
348
349
350
351 public boolean containsAll(Collection c)
352 {
353 return nodes.containsAll(c);
354 }
355
356
357
358
359 public Object get(int index)
360 {
361 return nodes.get(index);
362 }
363
364
365
366
367 public int indexOf(Object o)
368 {
369 return nodes.indexOf(o);
370 }
371
372
373
374
375 public boolean isEmpty()
376 {
377 return nodes.isEmpty();
378 }
379
380
381
382
383 public Iterator iterator()
384 {
385 return nodes.iterator();
386 }
387
388
389
390
391 public int lastIndexOf(Object o)
392 {
393 return nodes.lastIndexOf(o);
394 }
395
396
397
398
399 public ListIterator listIterator()
400 {
401 return nodes.listIterator();
402 }
403
404
405
406
407 public ListIterator listIterator(int index)
408 {
409 return nodes.listIterator(index);
410 }
411
412
413
414
415 public Object remove(int index)
416 {
417 return nodes.remove(index);
418 }
419
420
421
422
423 public boolean remove(Object o)
424 {
425 return nodes.remove(o);
426 }
427
428
429
430
431 public boolean removeAll(Collection c)
432 {
433 return nodes.removeAll(c);
434 }
435
436
437
438
439 public boolean retainAll(Collection c)
440 {
441 return nodes.retainAll(c);
442 }
443
444
445
446
447 public Object set(int index, Object o)
448 {
449 return nodes.set(index, o);
450 }
451
452
453
454
455 public int size()
456 {
457 return nodes.size();
458 }
459
460
461
462
463 public List subList(int fromIndex, int toIndex)
464 {
465 return new NodeList(nodes.subList(fromIndex, toIndex));
466 }
467
468
469
470
471 public Object[] toArray()
472 {
473 return nodes.toArray();
474 }
475
476
477
478
479 public Object[] toArray(Object[] a)
480 {
481 return nodes.toArray(a);
482 }
483
484
485
486
487
488
489
490 private static final class AttributeXMLOutputter extends XMLOutputter
491 {
492
493
494
495
496
497 public void output(Attribute attribute, Writer out)
498 throws IOException
499 {
500 out.write(" ");
501 out.write(attribute.getQualifiedName());
502 out.write("=");
503
504 out.write("\"");
505 out.write(escapeAttributeEntities(attribute.getValue()));
506 out.write("\"");
507 }
508 }
509 }