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