1
2
3
4
5
6
7
8 package org.dom4j.tree;
9
10 import java.util.Collections;
11 import java.util.Iterator;
12 import java.util.List;
13
14 import org.dom4j.Document;
15 import org.dom4j.DocumentFactory;
16 import org.dom4j.DocumentType;
17 import org.dom4j.Element;
18 import org.dom4j.IllegalAddException;
19 import org.dom4j.Node;
20 import org.dom4j.ProcessingInstruction;
21
22 import org.xml.sax.EntityResolver;
23
24 /***
25 * <p>
26 * <code>DefaultDocument</code> is the default DOM4J default implementation of
27 * an XML document.
28 * </p>
29 *
30 * @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
31 * @version $Revision: 1.34 $
32 */
33 public class DefaultDocument extends AbstractDocument {
34 protected static final List EMPTY_LIST = Collections.EMPTY_LIST;
35
36 protected static final Iterator EMPTY_ITERATOR = EMPTY_LIST.iterator();
37
38 /*** The name of the document */
39 private String name;
40
41 /*** The root element of this document */
42 private Element rootElement;
43
44 /***
45 * Store the contents of the document as a lazily created <code>List</code>
46 */
47 private List content;
48
49 /*** The document type for this document */
50 private DocumentType docType;
51
52 /*** The document factory used by default */
53 private DocumentFactory documentFactory = DocumentFactory.getInstance();
54
55 /*** The resolver of URIs */
56 private transient EntityResolver entityResolver;
57
58 public DefaultDocument() {
59 }
60
61 public DefaultDocument(String name) {
62 this.name = name;
63 }
64
65 public DefaultDocument(Element rootElement) {
66 this.rootElement = rootElement;
67 }
68
69 public DefaultDocument(DocumentType docType) {
70 this.docType = docType;
71 }
72
73 public DefaultDocument(Element rootElement, DocumentType docType) {
74 this.rootElement = rootElement;
75 this.docType = docType;
76 }
77
78 public DefaultDocument(String name, Element rootElement,
79 DocumentType docType) {
80 this.name = name;
81 this.rootElement = rootElement;
82 this.docType = docType;
83 }
84
85 public String getName() {
86 return name;
87 }
88
89 public void setName(String name) {
90 this.name = name;
91 }
92
93 public Element getRootElement() {
94 return rootElement;
95 }
96
97 public DocumentType getDocType() {
98 return docType;
99 }
100
101 public void setDocType(DocumentType docType) {
102 this.docType = docType;
103 }
104
105 public Document addDocType(String docTypeName, String publicId,
106 String systemId) {
107 setDocType(getDocumentFactory().createDocType(docTypeName, publicId,
108 systemId));
109
110 return this;
111 }
112
113 public String getXMLEncoding() {
114 return encoding;
115 }
116
117 public EntityResolver getEntityResolver() {
118 return entityResolver;
119 }
120
121 public void setEntityResolver(EntityResolver entityResolver) {
122 this.entityResolver = entityResolver;
123 }
124
125 public Object clone() {
126 DefaultDocument document = (DefaultDocument) super.clone();
127 document.rootElement = null;
128 document.content = null;
129 document.appendContent(this);
130
131 return document;
132 }
133
134 public List processingInstructions() {
135 List source = contentList();
136 List answer = createResultList();
137 int size = source.size();
138
139 for (int i = 0; i < size; i++) {
140 Object object = source.get(i);
141
142 if (object instanceof ProcessingInstruction) {
143 answer.add(object);
144 }
145 }
146
147 return answer;
148 }
149
150 public List processingInstructions(String target) {
151 List source = contentList();
152 List answer = createResultList();
153 int size = source.size();
154
155 for (int i = 0; i < size; i++) {
156 Object object = source.get(i);
157
158 if (object instanceof ProcessingInstruction) {
159 ProcessingInstruction pi = (ProcessingInstruction) object;
160
161 if (target.equals(pi.getName())) {
162 answer.add(pi);
163 }
164 }
165 }
166
167 return answer;
168 }
169
170 public ProcessingInstruction processingInstruction(String target) {
171 List source = contentList();
172 int size = source.size();
173
174 for (int i = 0; i < size; i++) {
175 Object object = source.get(i);
176
177 if (object instanceof ProcessingInstruction) {
178 ProcessingInstruction pi = (ProcessingInstruction) object;
179
180 if (target.equals(pi.getName())) {
181 return pi;
182 }
183 }
184 }
185
186 return null;
187 }
188
189 public boolean removeProcessingInstruction(String target) {
190 List source = contentList();
191
192 for (Iterator iter = source.iterator(); iter.hasNext();) {
193 Object object = iter.next();
194
195 if (object instanceof ProcessingInstruction) {
196 ProcessingInstruction pi = (ProcessingInstruction) object;
197
198 if (target.equals(pi.getName())) {
199 iter.remove();
200
201 return true;
202 }
203 }
204 }
205
206 return false;
207 }
208
209 public void setContent(List content) {
210 rootElement = null;
211 contentRemoved();
212
213 if (content instanceof ContentListFacade) {
214 content = ((ContentListFacade) content).getBackingList();
215 }
216
217 if (content == null) {
218 this.content = null;
219 } else {
220 int size = content.size();
221 List newContent = createContentList(size);
222
223 for (int i = 0; i < size; i++) {
224 Object object = content.get(i);
225
226 if (object instanceof Node) {
227 Node node = (Node) object;
228 Document doc = node.getDocument();
229
230 if ((doc != null) && (doc != this)) {
231 node = (Node) node.clone();
232 }
233
234 if (node instanceof Element) {
235 if (rootElement == null) {
236 rootElement = (Element) node;
237 } else {
238 throw new IllegalAddException(
239 "A document may only "
240 + "contain one root " + "element: "
241 + content);
242 }
243 }
244
245 newContent.add(node);
246 childAdded(node);
247 }
248 }
249
250 this.content = newContent;
251 }
252 }
253
254 public void clearContent() {
255 contentRemoved();
256 content = null;
257 rootElement = null;
258 }
259
260 public void setDocumentFactory(DocumentFactory documentFactory) {
261 this.documentFactory = documentFactory;
262 }
263
264
265
266 protected List contentList() {
267 if (content == null) {
268 content = createContentList();
269
270 if (rootElement != null) {
271 content.add(rootElement);
272 }
273 }
274
275 return content;
276 }
277
278 protected void addNode(Node node) {
279 if (node != null) {
280 Document document = node.getDocument();
281
282 if ((document != null) && (document != this)) {
283
284 String message = "The Node already has an existing document: "
285 + document;
286 throw new IllegalAddException(this, node, message);
287 }
288
289 contentList().add(node);
290 childAdded(node);
291 }
292 }
293
294 protected void addNode(int index, Node node) {
295 if (node != null) {
296 Document document = node.getDocument();
297
298 if ((document != null) && (document != this)) {
299
300 String message = "The Node already has an existing document: "
301 + document;
302 throw new IllegalAddException(this, node, message);
303 }
304
305 contentList().add(index, node);
306 childAdded(node);
307 }
308 }
309
310 protected boolean removeNode(Node node) {
311 if (node == rootElement) {
312 rootElement = null;
313 }
314
315 if (contentList().remove(node)) {
316 childRemoved(node);
317
318 return true;
319 }
320
321 return false;
322 }
323
324 protected void rootElementAdded(Element element) {
325 this.rootElement = element;
326 element.setDocument(this);
327 }
328
329 protected DocumentFactory getDocumentFactory() {
330 return documentFactory;
331 }
332 }
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369