Mercurial > repos > pfrommolt > ngsrich
comparison NGSrich_0.5.5/src/org/jdom/Document.java @ 0:89ad0a9cca52 default tip
Uploaded
author | pfrommolt |
---|---|
date | Mon, 21 Nov 2011 08:12:19 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:89ad0a9cca52 |
---|---|
1 /*-- | |
2 | |
3 $Id: Document.java,v 1.85 2007/11/10 05:28:58 jhunter Exp $ | |
4 | |
5 Copyright (C) 2000-2007 Jason Hunter & Brett McLaughlin. | |
6 All rights reserved. | |
7 | |
8 Redistribution and use in source and binary forms, with or without | |
9 modification, are permitted provided that the following conditions | |
10 are met: | |
11 | |
12 1. Redistributions of source code must retain the above copyright | |
13 notice, this list of conditions, and the following disclaimer. | |
14 | |
15 2. Redistributions in binary form must reproduce the above copyright | |
16 notice, this list of conditions, and the disclaimer that follows | |
17 these conditions in the documentation and/or other materials | |
18 provided with the distribution. | |
19 | |
20 3. The name "JDOM" must not be used to endorse or promote products | |
21 derived from this software without prior written permission. For | |
22 written permission, please contact <request_AT_jdom_DOT_org>. | |
23 | |
24 4. Products derived from this software may not be called "JDOM", nor | |
25 may "JDOM" appear in their name, without prior written permission | |
26 from the JDOM Project Management <request_AT_jdom_DOT_org>. | |
27 | |
28 In addition, we request (but do not require) that you include in the | |
29 end-user documentation provided with the redistribution and/or in the | |
30 software itself an acknowledgement equivalent to the following: | |
31 "This product includes software developed by the | |
32 JDOM Project (http://www.jdom.org/)." | |
33 Alternatively, the acknowledgment may be graphical using the logos | |
34 available at http://www.jdom.org/images/logos. | |
35 | |
36 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |
37 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
38 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
39 DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT | |
40 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
41 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
42 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |
43 USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
44 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
45 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |
46 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
47 SUCH DAMAGE. | |
48 | |
49 This software consists of voluntary contributions made by many | |
50 individuals on behalf of the JDOM Project and was originally | |
51 created by Jason Hunter <jhunter_AT_jdom_DOT_org> and | |
52 Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information | |
53 on the JDOM Project, please see <http://www.jdom.org/>. | |
54 | |
55 */ | |
56 | |
57 package org.jdom; | |
58 | |
59 import java.util.*; | |
60 import org.jdom.filter.*; | |
61 | |
62 /** | |
63 * An XML document. Methods allow access to the root element as well as the | |
64 * {@link DocType} and other document-level information. | |
65 * | |
66 * @version $Revision: 1.85 $, $Date: 2007/11/10 05:28:58 $ | |
67 * @author Brett McLaughlin | |
68 * @author Jason Hunter | |
69 * @author Jools Enticknap | |
70 * @author Bradley S. Huffman | |
71 */ | |
72 public class Document implements Parent { | |
73 | |
74 private static final String CVS_ID = | |
75 "@(#) $RCSfile: Document.java,v $ $Revision: 1.85 $ $Date: 2007/11/10 05:28:58 $ $Name: jdom_1_1_1 $"; | |
76 | |
77 /** | |
78 * This document's content including comments, PIs, a possible | |
79 * DocType, and a root element. | |
80 * Subclassers have to track content using their own | |
81 * mechanism. | |
82 */ | |
83 ContentList content = new ContentList(this); | |
84 | |
85 /** | |
86 * See http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/core.html#baseURIs-Considerations | |
87 */ | |
88 protected String baseURI = null; | |
89 | |
90 // Supports the setProperty/getProperty calls | |
91 private HashMap propertyMap = null; | |
92 | |
93 /** | |
94 * Creates a new empty document. A document must have a root element, | |
95 * so this document will not be well-formed and accessor methods will | |
96 * throw an IllegalStateException if this document is accessed before a | |
97 * root element is added. This method is most useful for build tools. | |
98 */ | |
99 public Document() {} | |
100 | |
101 /** | |
102 * This will create a new <code>Document</code>, | |
103 * with the supplied <code>{@link Element}</code> | |
104 * as the root element, the supplied | |
105 * <code>{@link DocType}</code> declaration, and the specified | |
106 * base URI. | |
107 * | |
108 * @param rootElement <code>Element</code> for document root. | |
109 * @param docType <code>DocType</code> declaration. | |
110 * @param baseURI the URI from which this doucment was loaded. | |
111 * @throws IllegalAddException if the given docType object | |
112 * is already attached to a document or the given | |
113 * rootElement already has a parent | |
114 */ | |
115 public Document(Element rootElement, DocType docType, String baseURI) { | |
116 if (rootElement != null) { | |
117 setRootElement(rootElement); | |
118 } | |
119 if (docType != null) { | |
120 setDocType(docType); | |
121 } | |
122 if (baseURI != null) { | |
123 setBaseURI(baseURI); | |
124 } | |
125 } | |
126 | |
127 /** | |
128 * This will create a new <code>Document</code>, | |
129 * with the supplied <code>{@link Element}</code> | |
130 * as the root element and the supplied | |
131 * <code>{@link DocType}</code> declaration. | |
132 * | |
133 * @param rootElement <code>Element</code> for document root. | |
134 * @param docType <code>DocType</code> declaration. | |
135 * @throws IllegalAddException if the given DocType object | |
136 * is already attached to a document or the given | |
137 * rootElement already has a parent | |
138 */ | |
139 public Document(Element rootElement, DocType docType) { | |
140 this(rootElement, docType, null); | |
141 } | |
142 | |
143 /** | |
144 * This will create a new <code>Document</code>, | |
145 * with the supplied <code>{@link Element}</code> | |
146 * as the root element, and no <code>{@link DocType}</code> | |
147 * declaration. | |
148 * | |
149 * @param rootElement <code>Element</code> for document root | |
150 * @throws IllegalAddException if the given rootElement already has | |
151 * a parent. | |
152 */ | |
153 public Document(Element rootElement) { | |
154 this(rootElement, null, null); | |
155 } | |
156 | |
157 /** | |
158 * This will create a new <code>Document</code>, | |
159 * with the supplied list of content, and a | |
160 * <code>{@link DocType}</code> declaration only if the content | |
161 * contains a DocType instance. A null list is treated the | |
162 * same as the no-arg constructor. | |
163 * | |
164 * @param content <code>List</code> of starter content | |
165 * @throws IllegalAddException if the List contains more than | |
166 * one Element or objects of illegal types. | |
167 */ | |
168 public Document(List content) { | |
169 setContent(content); | |
170 } | |
171 | |
172 public int getContentSize() { | |
173 return content.size(); | |
174 } | |
175 | |
176 public int indexOf(Content child) { | |
177 return content.indexOf(child); | |
178 } | |
179 | |
180 // /** | |
181 // * Starting at the given index (inclusive), return the index of | |
182 // * the first child matching the supplied filter, or -1 | |
183 // * if none is found. | |
184 // * | |
185 // * @return index of child, or -1 if none found. | |
186 // */ | |
187 // private int indexOf(int start, Filter filter) { | |
188 // int size = getContentSize(); | |
189 // for (int i = start; i < size; i++) { | |
190 // if (filter.matches(getContent(i))) { | |
191 // return i; | |
192 // } | |
193 // } | |
194 // return -1; | |
195 // } | |
196 | |
197 /** | |
198 * This will return <code>true</code> if this document has a | |
199 * root element, <code>false</code> otherwise. | |
200 * | |
201 * @return <code>true</code> if this document has a root element, | |
202 * <code>false</code> otherwise. | |
203 */ | |
204 public boolean hasRootElement() { | |
205 return (content.indexOfFirstElement() < 0) ? false : true; | |
206 } | |
207 | |
208 /** | |
209 * This will return the root <code>Element</code> | |
210 * for this <code>Document</code> | |
211 * | |
212 * @return <code>Element</code> - the document's root element | |
213 * @throws IllegalStateException if the root element hasn't been set | |
214 */ | |
215 public Element getRootElement() { | |
216 int index = content.indexOfFirstElement(); | |
217 if (index < 0) { | |
218 throw new IllegalStateException("Root element not set"); | |
219 } | |
220 return (Element) content.get(index); | |
221 } | |
222 | |
223 /** | |
224 * This sets the root <code>{@link Element}</code> for the | |
225 * <code>Document</code>. If the document already has a root | |
226 * element, it is replaced. | |
227 * | |
228 * @param rootElement <code>Element</code> to be new root. | |
229 * @return <code>Document</code> - modified Document. | |
230 * @throws IllegalAddException if the given rootElement already has | |
231 * a parent. | |
232 */ | |
233 public Document setRootElement(Element rootElement) { | |
234 int index = content.indexOfFirstElement(); | |
235 if (index < 0) { | |
236 content.add(rootElement); | |
237 } | |
238 else { | |
239 content.set(index, rootElement); | |
240 } | |
241 return this; | |
242 } | |
243 | |
244 /** | |
245 * Detach the root <code>{@link Element}</code> from this document. | |
246 * | |
247 * @return removed root <code>Element</code> | |
248 */ | |
249 public Element detachRootElement() { | |
250 int index = content.indexOfFirstElement(); | |
251 if (index < 0) | |
252 return null; | |
253 return (Element) removeContent(index); | |
254 } | |
255 | |
256 /** | |
257 * This will return the <code>{@link DocType}</code> | |
258 * declaration for this <code>Document</code>, or | |
259 * <code>null</code> if none exists. | |
260 * | |
261 * @return <code>DocType</code> - the DOCTYPE declaration. | |
262 */ | |
263 public DocType getDocType() { | |
264 int index = content.indexOfDocType(); | |
265 if (index < 0) { | |
266 return null; | |
267 } | |
268 else { | |
269 return (DocType) content.get(index); | |
270 } | |
271 } | |
272 | |
273 /** | |
274 * This will set the <code>{@link DocType}</code> | |
275 * declaration for this <code>Document</code>. Note | |
276 * that a DocType can only be attached to one Document. | |
277 * Attempting to set the DocType to a DocType object | |
278 * that already belongs to a Document will result in an | |
279 * IllegalAddException being thrown. | |
280 * | |
281 * @param docType <code>DocType</code> declaration. | |
282 * @return object on which the method was invoked | |
283 * @throws IllegalAddException if the given docType is | |
284 * already attached to a Document. | |
285 */ | |
286 public Document setDocType(DocType docType) { | |
287 if (docType == null) { | |
288 // Remove any existing doctype | |
289 int docTypeIndex = content.indexOfDocType(); | |
290 if (docTypeIndex >= 0) content.remove(docTypeIndex); | |
291 return this; | |
292 } | |
293 | |
294 if (docType.getParent() != null) { | |
295 throw new IllegalAddException(docType, | |
296 "The DocType already is attached to a document"); | |
297 } | |
298 | |
299 // Add DocType to head if new, replace old otherwise | |
300 int docTypeIndex = content.indexOfDocType(); | |
301 if (docTypeIndex < 0) { | |
302 content.add(0, docType); | |
303 } | |
304 else { | |
305 content.set(docTypeIndex, docType); | |
306 } | |
307 | |
308 return this; | |
309 } | |
310 | |
311 /** | |
312 * Appends the child to the end of the content list. | |
313 * | |
314 * @param child child to append to end of content list | |
315 * @return the document on which the method was called | |
316 * @throws IllegalAddException if the given child already has a parent. | |
317 */ | |
318 public Document addContent(Content child) { | |
319 content.add(child); | |
320 return this; | |
321 } | |
322 | |
323 /** | |
324 * Appends all children in the given collection to the end of | |
325 * the content list. In event of an exception during add the | |
326 * original content will be unchanged and the objects in the supplied | |
327 * collection will be unaltered. | |
328 * | |
329 * @param c collection to append | |
330 * @return the document on which the method was called | |
331 * @throws IllegalAddException if any item in the collection | |
332 * already has a parent or is of an illegal type. | |
333 */ | |
334 public Document addContent(Collection c) { | |
335 content.addAll(c); | |
336 return this; | |
337 } | |
338 | |
339 /** | |
340 * Inserts the child into the content list at the given index. | |
341 * | |
342 * @param index location for adding the collection | |
343 * @param child child to insert | |
344 * @return the parent on which the method was called | |
345 * @throws IndexOutOfBoundsException if index is negative or beyond | |
346 * the current number of children | |
347 * @throws IllegalAddException if the given child already has a parent. | |
348 */ | |
349 public Document addContent(int index, Content child) { | |
350 content.add(index, child); | |
351 return this; | |
352 } | |
353 | |
354 /** | |
355 * Inserts the content in a collection into the content list | |
356 * at the given index. In event of an exception the original content | |
357 * will be unchanged and the objects in the supplied collection will be | |
358 * unaltered. | |
359 * | |
360 * @param index location for adding the collection | |
361 * @param c collection to insert | |
362 * @return the parent on which the method was called | |
363 * @throws IndexOutOfBoundsException if index is negative or beyond | |
364 * the current number of children | |
365 * @throws IllegalAddException if any item in the collection | |
366 * already has a parent or is of an illegal type. | |
367 */ | |
368 public Document addContent(int index, Collection c) { | |
369 content.addAll(index, c); | |
370 return this; | |
371 } | |
372 | |
373 public List cloneContent() { | |
374 int size = getContentSize(); | |
375 List list = new ArrayList(size); | |
376 for (int i = 0; i < size; i++) { | |
377 Content child = getContent(i); | |
378 list.add(child.clone()); | |
379 } | |
380 return list; | |
381 } | |
382 | |
383 public Content getContent(int index) { | |
384 return (Content) content.get(index); | |
385 } | |
386 | |
387 // public Content getChild(Filter filter) { | |
388 // int i = indexOf(0, filter); | |
389 // return (i < 0) ? null : getContent(i); | |
390 // } | |
391 | |
392 /** | |
393 * This will return all content for the <code>Document</code>. | |
394 * The returned list is "live" in document order and changes to it | |
395 * affect the document's actual content. | |
396 * | |
397 * <p> | |
398 * Sequential traversal through the List is best done with a Iterator | |
399 * since the underlying implement of List.size() may require walking the | |
400 * entire list. | |
401 * </p> | |
402 * | |
403 * @return <code>List</code> - all Document content | |
404 * @throws IllegalStateException if the root element hasn't been set | |
405 */ | |
406 public List getContent() { | |
407 if (!hasRootElement()) | |
408 throw new IllegalStateException("Root element not set"); | |
409 return content; | |
410 } | |
411 | |
412 /** | |
413 * Return a filtered view of this <code>Document</code>'s content. | |
414 * | |
415 * <p> | |
416 * Sequential traversal through the List is best done with a Iterator | |
417 * since the underlying implement of List.size() may require walking the | |
418 * entire list. | |
419 * </p> | |
420 * | |
421 * @param filter <code>Filter</code> to apply | |
422 * @return <code>List</code> - filtered Document content | |
423 * @throws IllegalStateException if the root element hasn't been set | |
424 */ | |
425 public List getContent(Filter filter) { | |
426 if (!hasRootElement()) | |
427 throw new IllegalStateException("Root element not set"); | |
428 return content.getView(filter); | |
429 } | |
430 | |
431 /** | |
432 * Removes all child content from this parent. | |
433 * | |
434 * @return list of the old children detached from this parent | |
435 */ | |
436 public List removeContent() { | |
437 List old = new ArrayList(content); | |
438 content.clear(); | |
439 return old; | |
440 } | |
441 | |
442 /** | |
443 * Remove all child content from this parent matching the supplied filter. | |
444 * | |
445 * @param filter filter to select which content to remove | |
446 * @return list of the old children detached from this parent | |
447 */ | |
448 public List removeContent(Filter filter) { | |
449 List old = new ArrayList(); | |
450 Iterator itr = content.getView(filter).iterator(); | |
451 while (itr.hasNext()) { | |
452 Content child = (Content) itr.next(); | |
453 old.add(child); | |
454 itr.remove(); | |
455 } | |
456 return old; | |
457 } | |
458 | |
459 /** | |
460 * This sets the content of the <code>Document</code>. The supplied | |
461 * List should contain only objects of type <code>Element</code>, | |
462 * <code>Comment</code>, and <code>ProcessingInstruction</code>. | |
463 * | |
464 * <p> | |
465 * When all objects in the supplied List are legal and before the new | |
466 * content is added, all objects in the old content will have their | |
467 * parentage set to null (no parent) and the old content list will be | |
468 * cleared. This has the effect that any active list (previously obtained | |
469 * with a call to {@link #getContent}) will also | |
470 * change to reflect the new content. In addition, all objects in the | |
471 * supplied List will have their parentage set to this document, but the | |
472 * List itself will not be "live" and further removals and additions will | |
473 * have no effect on this document content. If the user wants to continue | |
474 * working with a "live" list, then a call to setContent should be | |
475 * followed by a call to {@link #getContent} to | |
476 * obtain a "live" version of the content. | |
477 * </p> | |
478 * | |
479 * <p> | |
480 * Passing a null or empty List clears the existing content. | |
481 * </p> | |
482 * | |
483 * <p> | |
484 * In event of an exception the original content will be unchanged and | |
485 * the objects in the supplied content will be unaltered. | |
486 * </p> | |
487 * | |
488 * @param newContent <code>List</code> of content to set | |
489 * @return this document modified | |
490 * @throws IllegalAddException if the List contains objects of | |
491 * illegal types or with existing parentage. | |
492 */ | |
493 public Document setContent(Collection newContent) { | |
494 content.clearAndSet(newContent); | |
495 return this; | |
496 } | |
497 | |
498 /** | |
499 * | |
500 * <p> | |
501 * Sets the effective URI from which this document was loaded, | |
502 * and against which relative URLs in this document will be resolved. | |
503 * </p> | |
504 * | |
505 * @param uri the base URI of this document | |
506 */ | |
507 public final void setBaseURI(String uri) { | |
508 this.baseURI = uri; // XXX We don't check the URI | |
509 } | |
510 | |
511 /** | |
512 * <p> | |
513 * Returns the URI from which this document was loaded, | |
514 * or null if this is not known. | |
515 * </p> | |
516 * | |
517 * @return the base URI of this document | |
518 */ | |
519 public final String getBaseURI() { | |
520 return baseURI; | |
521 } | |
522 | |
523 /* | |
524 * Replace the current child the given index with the supplied child. | |
525 * <p> | |
526 * In event of an exception the original content will be unchanged and | |
527 * the supplied child will be unaltered. | |
528 * </p> | |
529 * | |
530 * @param index - index of child to replace. | |
531 * @param child - child to add. | |
532 * @throws IllegalAddException if the supplied child is already attached | |
533 * or not legal content for this parent. | |
534 * @throws IndexOutOfBoundsException if index is negative or greater | |
535 * than the current number of children. | |
536 */ | |
537 public Document setContent(int index, Content child) { | |
538 content.set(index, child); | |
539 return this; | |
540 } | |
541 | |
542 /** | |
543 * Replace the child at the given index whith the supplied | |
544 * collection. | |
545 * <p> | |
546 * In event of an exception the original content will be unchanged and | |
547 * the content in the supplied collection will be unaltered. | |
548 * </p> | |
549 * | |
550 * @param index - index of child to replace. | |
551 * @param collection - collection of content to add. | |
552 * @return object on which the method was invoked | |
553 * @throws IllegalAddException if the collection contains objects of | |
554 * illegal types. | |
555 * @throws IndexOutOfBoundsException if index is negative or greater | |
556 * than the current number of children. | |
557 */ | |
558 public Document setContent(int index, Collection collection) { | |
559 content.remove(index); | |
560 content.addAll(index, collection); | |
561 return this; | |
562 } | |
563 | |
564 public boolean removeContent(Content child) { | |
565 return content.remove(child); | |
566 } | |
567 | |
568 public Content removeContent(int index) { | |
569 return (Content) content.remove(index); | |
570 } | |
571 | |
572 /** | |
573 * Set this document's content to be the supplied child. | |
574 * <p> | |
575 * If the supplied child is legal content for a Document and before | |
576 * it is added, all content in the current content list will | |
577 * be cleared and all current children will have their parentage set to | |
578 * null. | |
579 * <p> | |
580 * This has the effect that any active list (previously obtained with | |
581 * a call to one of the {@link #getContent} methods will also change | |
582 * to reflect the new content. In addition, all content in the supplied | |
583 * collection will have their parentage set to this Document. If the user | |
584 * wants to continue working with a <b>"live"</b> list of this Document's | |
585 * child, then a call to setContent should be followed by a call to one | |
586 * of the {@link #getContent} methods to obtain a <b>"live"</b> | |
587 * version of the children. | |
588 * <p> | |
589 * Passing a null child clears the existing content. | |
590 * <p> | |
591 * In event of an exception the original content will be unchanged and | |
592 * the supplied child will be unaltered. | |
593 * | |
594 * @param child new content to replace existing content | |
595 * @return the parent on which the method was called | |
596 * @throws IllegalAddException if the supplied child is already attached | |
597 * or not legal content for this parent | |
598 */ | |
599 public Document setContent(Content child) { | |
600 content.clear(); | |
601 content.add(child); | |
602 return this; | |
603 } | |
604 | |
605 /** | |
606 * This returns a <code>String</code> representation of the | |
607 * <code>Document</code>, suitable for debugging. If the XML | |
608 * representation of the <code>Document</code> is desired, | |
609 * {@link org.jdom.output.XMLOutputter#outputString(Document)} | |
610 * should be used. | |
611 * | |
612 * @return <code>String</code> - information about the | |
613 * <code>Document</code> | |
614 */ | |
615 public String toString() { | |
616 StringBuffer stringForm = new StringBuffer() | |
617 .append("[Document: "); | |
618 | |
619 DocType docType = getDocType(); | |
620 if (docType != null) { | |
621 stringForm.append(docType.toString()) | |
622 .append(", "); | |
623 } else { | |
624 stringForm.append(" No DOCTYPE declaration, "); | |
625 } | |
626 | |
627 Element rootElement = getRootElement(); | |
628 if (rootElement != null) { | |
629 stringForm.append("Root is ") | |
630 .append(rootElement.toString()); | |
631 } else { | |
632 stringForm.append(" No root element"); // shouldn't happen | |
633 } | |
634 | |
635 stringForm.append("]"); | |
636 | |
637 return stringForm.toString(); | |
638 } | |
639 | |
640 /** | |
641 * This tests for equality of this <code>Document</code> to the supplied | |
642 * <code>Object</code>. | |
643 * | |
644 * @param ob <code>Object</code> to compare to | |
645 * @return <code>boolean</code> whether the <code>Document</code> is | |
646 * equal to the supplied <code>Object</code> | |
647 */ | |
648 public final boolean equals(Object ob) { | |
649 return (ob == this); | |
650 } | |
651 | |
652 /** | |
653 * This returns the hash code for this <code>Document</code>. | |
654 * | |
655 * @return <code>int</code> hash code | |
656 */ | |
657 public final int hashCode() { | |
658 return super.hashCode(); | |
659 } | |
660 | |
661 /** | |
662 * This will return a deep clone of this <code>Document</code>. | |
663 * | |
664 * @return <code>Object</code> clone of this <code>Document</code> | |
665 */ | |
666 public Object clone() { | |
667 Document doc = null; | |
668 | |
669 try { | |
670 doc = (Document) super.clone(); | |
671 } catch (CloneNotSupportedException ce) { | |
672 // Can't happen | |
673 } | |
674 | |
675 // The clone has a reference to this object's content list, so | |
676 // owerwrite with a empty list | |
677 doc.content = new ContentList(doc); | |
678 | |
679 // Add the cloned content to clone | |
680 | |
681 for (int i = 0; i < content.size(); i++) { | |
682 Object obj = content.get(i); | |
683 if (obj instanceof Element) { | |
684 Element element = (Element)((Element)obj).clone(); | |
685 doc.content.add(element); | |
686 } | |
687 else if (obj instanceof Comment) { | |
688 Comment comment = (Comment)((Comment)obj).clone(); | |
689 doc.content.add(comment); | |
690 } | |
691 else if (obj instanceof ProcessingInstruction) { | |
692 ProcessingInstruction pi = (ProcessingInstruction) | |
693 ((ProcessingInstruction)obj).clone(); | |
694 doc.content.add(pi); | |
695 } | |
696 else if (obj instanceof DocType) { | |
697 DocType dt = (DocType) ((DocType)obj).clone(); | |
698 doc.content.add(dt); | |
699 } | |
700 } | |
701 | |
702 return doc; | |
703 } | |
704 | |
705 /** | |
706 * Returns an iterator that walks over all descendants in document order. | |
707 * | |
708 * @return an iterator to walk descendants | |
709 */ | |
710 public Iterator getDescendants() { | |
711 return new DescendantIterator(this); | |
712 } | |
713 | |
714 /** | |
715 * Returns an iterator that walks over all descendants in document order | |
716 * applying the Filter to return only elements that match the filter rule. | |
717 * With filters you can match only Elements, only Comments, Elements or | |
718 * Comments, only Elements with a given name and/or prefix, and so on. | |
719 * | |
720 * @param filter filter to select which descendants to see | |
721 * @return an iterator to walk descendants within a filter | |
722 */ | |
723 public Iterator getDescendants(Filter filter) { | |
724 return new FilterIterator(new DescendantIterator(this), filter); | |
725 } | |
726 | |
727 public Parent getParent() { | |
728 return null; // documents never have parents | |
729 } | |
730 | |
731 | |
732 | |
733 /** | |
734 * @see org.jdom.Parent#getDocument() | |
735 */ | |
736 public Document getDocument() { | |
737 return this; | |
738 } | |
739 | |
740 /** | |
741 * Assigns an arbitrary object to be associated with this document under | |
742 * the given "id" string. Null values are permitted. Strings beginning | |
743 * with "http://www.jdom.org/ are reserved for JDOM use. | |
744 * | |
745 * @param id the id of the stored object | |
746 * @param value the object to store | |
747 */ | |
748 public void setProperty(String id, Object value) { | |
749 if (propertyMap == null) { | |
750 propertyMap = new HashMap(); | |
751 } | |
752 propertyMap.put(id, value); | |
753 } | |
754 | |
755 /** | |
756 * Returns the object associated with this document under the given "id" | |
757 * string, or null if there is no binding or if the binding explicitly | |
758 * stored a null value. | |
759 * | |
760 * @param id the id of the stored object to return | |
761 * @return the object associated with the given id | |
762 */ | |
763 public Object getProperty(String id) { | |
764 if (propertyMap == null) return null; | |
765 return propertyMap.get(id); | |
766 } | |
767 } |