KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dom4j > tree > AbstractBranch


1 /*
2  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
3  *
4  * This software is open source.
5  * See the bottom of this file for the licence.
6  */

7
8 package org.dom4j.tree;
9
10 import java.util.ArrayList JavaDoc;
11 import java.util.Iterator JavaDoc;
12 import java.util.List JavaDoc;
13 import java.util.StringTokenizer JavaDoc;
14
15 import org.dom4j.Branch;
16 import org.dom4j.Comment;
17 import org.dom4j.Element;
18 import org.dom4j.IllegalAddException;
19 import org.dom4j.Namespace;
20 import org.dom4j.Node;
21 import org.dom4j.ProcessingInstruction;
22 import org.dom4j.QName;
23
24 /**
25  * <p>
26  * <code>AbstractBranch</code> is an abstract base class for tree implementors
27  * to use for implementation inheritence.
28  * </p>
29  *
30  * @author <a HREF="mailto:jstrachan@apache.org">James Strachan </a>
31  * @version $Revision: 1.44 $
32  */

33 public abstract class AbstractBranch extends AbstractNode implements Branch {
34     protected static final int DEFAULT_CONTENT_LIST_SIZE = 5;
35
36     public AbstractBranch() {
37     }
38
39     public boolean isReadOnly() {
40         return false;
41     }
42
43     public boolean hasContent() {
44         return nodeCount() > 0;
45     }
46
47     public List JavaDoc content() {
48         List JavaDoc backingList = contentList();
49
50         return new ContentListFacade(this, backingList);
51     }
52
53     public String JavaDoc getText() {
54         List JavaDoc content = contentList();
55
56         if (content != null) {
57             int size = content.size();
58
59             if (size >= 1) {
60                 Object JavaDoc first = content.get(0);
61                 String JavaDoc firstText = getContentAsText(first);
62
63                 if (size == 1) {
64                     // optimised to avoid StringBuffer creation
65
return firstText;
66                 } else {
67                     StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(firstText);
68
69                     for (int i = 1; i < size; i++) {
70                         Object JavaDoc node = content.get(i);
71                         buffer.append(getContentAsText(node));
72                     }
73
74                     return buffer.toString();
75                 }
76             }
77         }
78
79         return "";
80     }
81
82     /**
83      * DOCUMENT ME!
84      *
85      * @param content
86      * DOCUMENT ME!
87      *
88      * @return the text value of the given content object as text which returns
89      * the text value of CDATA, Entity or Text nodes
90      */

91     protected String JavaDoc getContentAsText(Object JavaDoc content) {
92         if (content instanceof Node) {
93             Node node = (Node) content;
94
95             switch (node.getNodeType()) {
96                 case CDATA_SECTION_NODE:
97
98                 // case ENTITY_NODE:
99
case ENTITY_REFERENCE_NODE:
100                 case TEXT_NODE:
101                     return node.getText();
102
103                 default:
104                     break;
105             }
106         } else if (content instanceof String JavaDoc) {
107             return (String JavaDoc) content;
108         }
109
110         return "";
111     }
112
113     /**
114      * DOCUMENT ME!
115      *
116      * @param content
117      * DOCUMENT ME!
118      *
119      * @return the XPath defined string-value of the given content object
120      */

121     protected String JavaDoc getContentAsStringValue(Object JavaDoc content) {
122         if (content instanceof Node) {
123             Node node = (Node) content;
124
125             switch (node.getNodeType()) {
126                 case CDATA_SECTION_NODE:
127
128                 // case ENTITY_NODE:
129
case ENTITY_REFERENCE_NODE:
130                 case TEXT_NODE:
131                 case ELEMENT_NODE:
132                     return node.getStringValue();
133
134                 default:
135                     break;
136             }
137         } else if (content instanceof String JavaDoc) {
138             return (String JavaDoc) content;
139         }
140
141         return "";
142     }
143
144     public String JavaDoc getTextTrim() {
145         String JavaDoc text = getText();
146
147         StringBuffer JavaDoc textContent = new StringBuffer JavaDoc();
148         StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(text);
149
150         while (tokenizer.hasMoreTokens()) {
151             String JavaDoc str = tokenizer.nextToken();
152             textContent.append(str);
153
154             if (tokenizer.hasMoreTokens()) {
155                 textContent.append(" "); // separator
156
}
157         }
158
159         return textContent.toString();
160     }
161
162     public void setProcessingInstructions(List JavaDoc listOfPIs) {
163         for (Iterator JavaDoc iter = listOfPIs.iterator(); iter.hasNext();) {
164             ProcessingInstruction pi = (ProcessingInstruction) iter.next();
165             addNode(pi);
166         }
167     }
168
169     public Element addElement(String JavaDoc name) {
170         Element node = getDocumentFactory().createElement(name);
171         add(node);
172
173         return node;
174     }
175
176     public Element addElement(String JavaDoc qualifiedName, String JavaDoc namespaceURI) {
177         Element node = getDocumentFactory().createElement(qualifiedName,
178                 namespaceURI);
179         add(node);
180
181         return node;
182     }
183
184     public Element addElement(QName qname) {
185         Element node = getDocumentFactory().createElement(qname);
186         add(node);
187
188         return node;
189     }
190
191     public Element addElement(String JavaDoc name, String JavaDoc prefix, String JavaDoc uri) {
192         Namespace namespace = Namespace.get(prefix, uri);
193         QName qName = getDocumentFactory().createQName(name, namespace);
194
195         return addElement(qName);
196     }
197
198     // polymorphic node methods
199
public void add(Node node) {
200         switch (node.getNodeType()) {
201             case ELEMENT_NODE:
202                 add((Element) node);
203
204                 break;
205
206             case COMMENT_NODE:
207                 add((Comment) node);
208
209                 break;
210
211             case PROCESSING_INSTRUCTION_NODE:
212                 add((ProcessingInstruction) node);
213
214                 break;
215
216             default:
217                 invalidNodeTypeAddException(node);
218         }
219     }
220
221     public boolean remove(Node node) {
222         switch (node.getNodeType()) {
223             case ELEMENT_NODE:
224                 return remove((Element) node);
225
226             case COMMENT_NODE:
227                 return remove((Comment) node);
228
229             case PROCESSING_INSTRUCTION_NODE:
230                 return remove((ProcessingInstruction) node);
231
232             default:
233                 invalidNodeTypeAddException(node);
234
235                 return false;
236         }
237     }
238
239     // typesafe versions using node classes
240
public void add(Comment comment) {
241         addNode(comment);
242     }
243
244     public void add(Element element) {
245         addNode(element);
246     }
247
248     public void add(ProcessingInstruction pi) {
249         addNode(pi);
250     }
251
252     public boolean remove(Comment comment) {
253         return removeNode(comment);
254     }
255
256     public boolean remove(Element element) {
257         return removeNode(element);
258     }
259
260     public boolean remove(ProcessingInstruction pi) {
261         return removeNode(pi);
262     }
263
264     public Element elementByID(String JavaDoc elementID) {
265         for (int i = 0, size = nodeCount(); i < size; i++) {
266             Node node = node(i);
267
268             if (node instanceof Element) {
269                 Element element = (Element) node;
270                 String JavaDoc id = elementID(element);
271
272                 if ((id != null) && id.equals(elementID)) {
273                     return element;
274                 } else {
275                     element = element.elementByID(elementID);
276
277                     if (element != null) {
278                         return element;
279                     }
280                 }
281             }
282         }
283
284         return null;
285     }
286
287     public void appendContent(Branch branch) {
288         for (int i = 0, size = branch.nodeCount(); i < size; i++) {
289             Node node = branch.node(i);
290             add((Node) node.clone());
291         }
292     }
293
294     public Node node(int index) {
295         Object JavaDoc object = contentList().get(index);
296
297         if (object instanceof Node) {
298             return (Node) object;
299         }
300
301         if (object instanceof String JavaDoc) {
302             return getDocumentFactory().createText(object.toString());
303         }
304
305         return null;
306     }
307
308     public int nodeCount() {
309         return contentList().size();
310     }
311
312     public int indexOf(Node node) {
313         return contentList().indexOf(node);
314     }
315
316     public Iterator JavaDoc nodeIterator() {
317         return contentList().iterator();
318     }
319
320     // Implementation methods
321

322     /**
323      * DOCUMENT ME!
324      *
325      * @param element
326      * DOCUMENT ME!
327      *
328      * @return the ID of the given <code>Element</code>
329      */

330     protected String JavaDoc elementID(Element element) {
331         // XXX: there will be other ways of finding the ID
332
// XXX: should probably have an IDResolver or something
333
return element.attributeValue("ID");
334     }
335
336     /**
337      * DOCUMENT ME!
338      *
339      * @return the internal List used to manage the content
340      */

341     protected abstract List JavaDoc contentList();
342
343     /**
344      * A Factory Method pattern which creates a List implementation used to
345      * store content
346      *
347      * @return DOCUMENT ME!
348      */

349     protected List JavaDoc createContentList() {
350         return new ArrayList JavaDoc(DEFAULT_CONTENT_LIST_SIZE);
351     }
352
353     /**
354      * A Factory Method pattern which creates a List implementation used to
355      * store content
356      *
357      * @param size
358      * DOCUMENT ME!
359      *
360      * @return DOCUMENT ME!
361      */

362     protected List JavaDoc createContentList(int size) {
363         return new ArrayList JavaDoc(size);
364     }
365
366     /**
367      * A Factory Method pattern which creates a BackedList implementation used
368      * to store results of a filtered content query.
369      *
370      * @return DOCUMENT ME!
371      */

372     protected BackedList createResultList() {
373         return new BackedList(this, contentList());
374     }
375
376     /**
377      * A Factory Method pattern which creates a BackedList implementation which
378      * contains a single result
379      *
380      * @param result
381      * DOCUMENT ME!
382      *
383      * @return DOCUMENT ME!
384      */

385     protected List JavaDoc createSingleResultList(Object JavaDoc result) {
386         BackedList list = new BackedList(this, contentList(), 1);
387         list.addLocal(result);
388
389         return list;
390     }
391
392     /**
393      * A Factory Method pattern which creates an empty a BackedList
394      * implementation
395      *
396      * @return DOCUMENT ME!
397      */

398     protected List JavaDoc createEmptyList() {
399         return new BackedList(this, contentList(), 0);
400     }
401
402     protected abstract void addNode(Node node);
403
404     protected abstract void addNode(int index, Node node);
405
406     protected abstract boolean removeNode(Node node);
407
408     /**
409      * Called when a new child node has been added to me to allow any parent
410      * relationships to be created or events to be fired.
411      *
412      * @param node
413      * DOCUMENT ME!
414      */

415     protected abstract void childAdded(Node node);
416
417     /**
418      * Called when a child node has been removed to allow any parent
419      * relationships to be deleted or events to be fired.
420      *
421      * @param node
422      * DOCUMENT ME!
423      */

424     protected abstract void childRemoved(Node node);
425
426     /**
427      * Called when the given List content has been removed so each node should
428      * have its parent and document relationships cleared
429      */

430     protected void contentRemoved() {
431         List JavaDoc content = contentList();
432
433         for (int i = 0, size = content.size(); i < size; i++) {
434             Object JavaDoc object = content.get(i);
435
436             if (object instanceof Node) {
437                 childRemoved((Node) object);
438             }
439         }
440     }
441
442     /**
443      * Called when an invalid node has been added. Throws an {@link
444      * IllegalAddException}.
445      *
446      * @param node
447      * DOCUMENT ME!
448      *
449      * @throws IllegalAddException
450      * DOCUMENT ME!
451      */

452     protected void invalidNodeTypeAddException(Node node) {
453         throw new IllegalAddException("Invalid node type. Cannot add node: "
454                 + node + " to this branch: " + this);
455     }
456 }
457
458 /*
459  * Redistribution and use of this software and associated documentation
460  * ("Software"), with or without modification, are permitted provided that the
461  * following conditions are met:
462  *
463  * 1. Redistributions of source code must retain copyright statements and
464  * notices. Redistributions must also contain a copy of this document.
465  *
466  * 2. Redistributions in binary form must reproduce the above copyright notice,
467  * this list of conditions and the following disclaimer in the documentation
468  * and/or other materials provided with the distribution.
469  *
470  * 3. The name "DOM4J" must not be used to endorse or promote products derived
471  * from this Software without prior written permission of MetaStuff, Ltd. For
472  * written permission, please contact dom4j-info@metastuff.com.
473  *
474  * 4. Products derived from this Software may not be called "DOM4J" nor may
475  * "DOM4J" appear in their names without prior written permission of MetaStuff,
476  * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
477  *
478  * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
479  *
480  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
481  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
482  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
483  * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
484  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
485  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
486  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
487  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
488  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
489  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
490  * POSSIBILITY OF SUCH DAMAGE.
491  *
492  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
493  */

494
Popular Tags