KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ozoneDB > xml > dom4j > o3impl > AbstractBranch


1 /*
2  * Copyright 2001 (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  * $Id: AbstractBranch.java,v 1.1 2003/11/02 18:10:03 per_nyfelt Exp $
8  */

9
10 package org.ozoneDB.xml.dom4j.o3impl;
11
12 import org.dom4j.*;
13 import org.dom4j.io.OutputFormat;
14
15 import java.util.ArrayList JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.StringTokenizer JavaDoc;
19
20 /** <p><code>AbstractBranch</code> is an abstract base class for
21  * tree implementors to use for implementation inheritence.</p>
22  *
23  * @author <a HREF="mailto:jstrachan@apache.org">James Strachan</a>
24  * @version $Revision: 1.1 $
25  */

26 public abstract class AbstractBranch extends AbstractNode implements Branch {
27
28     /** The output format used by default */
29     protected static final OutputFormat outputFormat = new OutputFormat();
30
31     protected static final int DEFAULT_CONTENT_LIST_SIZE = 5;
32
33
34     public AbstractBranch() {
35     }
36
37
38     public boolean isReadOnly() {
39         return false;
40     }
41
42     public boolean hasContent() {
43         return nodeCount() > 0;
44     }
45
46     public List JavaDoc content() {
47         List JavaDoc backingList = contentList();
48         return new ContentListFacade(this, backingList);
49     }
50
51     public String JavaDoc getText() {
52         List JavaDoc content = contentList();
53         if (content != null) {
54             int size = content.size();
55             if (size >= 1) {
56                 Object JavaDoc first = content.get(0);
57                 String JavaDoc firstText = getContentAsText(first);
58                 if (size == 1) {
59                     // optimised to avoid StringBuffer creation
60
return firstText;
61                 } else {
62                     StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(firstText);
63                     for (int i = 1; i < size; i++) {
64                         Object JavaDoc node = content.get(i);
65                         buffer.append(getContentAsText(node));
66                     }
67                     return buffer.toString();
68                 }
69             }
70         }
71         return "";
72     }
73
74     /** @return the text value of the given content object
75      * as text which returns the text value of CDATA, Entity or Text nodes
76      */

77     protected String JavaDoc getContentAsText(Object JavaDoc content) {
78         if (content instanceof Node) {
79             Node node = (Node) content;
80             switch (node.getNodeType()) {
81                 case CDATA_SECTION_NODE:
82                     //case ENTITY_NODE:
83
case ENTITY_REFERENCE_NODE:
84                 case TEXT_NODE:
85                     return node.getText();
86             }
87         } else if (content instanceof String JavaDoc) {
88             return (String JavaDoc) content;
89         }
90         return "";
91     }
92
93     /** @return the XPath defined string-value of the given content object
94      */

95     protected String JavaDoc getContentAsStringValue(Object JavaDoc content) {
96         if (content instanceof Node) {
97             Node node = (Node) content;
98             switch (node.getNodeType()) {
99                 case CDATA_SECTION_NODE:
100                     //case ENTITY_NODE:
101
case ENTITY_REFERENCE_NODE:
102                 case TEXT_NODE:
103                 case ELEMENT_NODE:
104                     return node.getStringValue();
105             }
106         } else if (content instanceof String JavaDoc) {
107             return (String JavaDoc) content;
108         }
109         return "";
110     }
111
112
113     public String JavaDoc getTextTrim() {
114         String JavaDoc text = getText();
115
116         StringBuffer JavaDoc textContent = new StringBuffer JavaDoc();
117         StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(text);
118         while (tokenizer.hasMoreTokens()) {
119             String JavaDoc str = tokenizer.nextToken();
120             textContent.append(str);
121             if (tokenizer.hasMoreTokens()) {
122                 textContent.append(" "); // separator
123
}
124         }
125
126         return textContent.toString();
127     }
128
129     public void setProcessingInstructions(List JavaDoc listOfPIs) {
130         for (Iterator JavaDoc iter = listOfPIs.iterator(); iter.hasNext();) {
131             ProcessingInstruction pi = (ProcessingInstruction) iter.next();
132             addNode(pi);
133         }
134     }
135
136     public Element addElement(String JavaDoc name) {
137         Element node = getNodeFactory().createElement(name);
138         add(node);
139         return node;
140     }
141
142     public Element addElement(String JavaDoc qualifiedName, String JavaDoc namespaceURI) {
143         Element node = getNodeFactory().createElement(qualifiedName, namespaceURI);
144         add(node);
145         return node;
146     }
147
148     public Element addElement(QName qname) {
149         Element node = getNodeFactory().createElement(qname);
150         add(node);
151         return node;
152     }
153
154     public Element addElement(String JavaDoc name, String JavaDoc prefix, String JavaDoc uri) {
155         Namespace namespace = getNodeFactory().createNamespace(prefix, uri);
156         QName qName = getNodeFactory().createQName(name, namespace);
157         return addElement(qName);
158     }
159
160     // polymorphic node methods
161

162     public void add(Node node) {
163         switch (node.getNodeType()) {
164             case ELEMENT_NODE:
165                 add((Element) node);
166                 break;
167             case COMMENT_NODE:
168                 add((Comment) node);
169                 break;
170             case PROCESSING_INSTRUCTION_NODE:
171                 add((ProcessingInstruction) node);
172                 break;
173             default:
174                 invalidNodeTypeAddException(node);
175         }
176     }
177
178     public boolean remove(Node node) {
179         switch (node.getNodeType()) {
180             case ELEMENT_NODE:
181                 return remove((Element) node);
182             case COMMENT_NODE:
183                 return remove((Comment) node);
184             case PROCESSING_INSTRUCTION_NODE:
185                 return remove((ProcessingInstruction) node);
186             default:
187                 invalidNodeTypeAddException(node);
188                 return false;
189         }
190     }
191
192     // typesafe versions using node classes
193

194     public void add(Comment comment) {
195         addNode(comment);
196     }
197
198     public void add(Element element) {
199         addNode(element);
200     }
201
202     public void add(ProcessingInstruction pi) {
203         addNode(pi);
204     }
205
206     public boolean remove(Comment comment) {
207         return removeNode(comment);
208     }
209
210     public boolean remove(Element element) {
211         return removeNode(element);
212     }
213
214     public boolean remove(ProcessingInstruction pi) {
215         return removeNode(pi);
216     }
217
218
219     public Element elementByID(String JavaDoc elementID) {
220         for (int i = 0, size = nodeCount(); i < size; i++) {
221             Node node = node(i);
222             if (node instanceof Element) {
223                 Element element = (Element) node;
224                 String JavaDoc id = elementID(element);
225                 if (id != null && id.equals(elementID)) {
226                     return element;
227                 } else {
228                     element = element.elementByID(elementID);
229                     if (element != null) {
230                         return element;
231                     }
232                 }
233             }
234         }
235         return null;
236     }
237
238     public void appendContent(Branch branch) {
239         for (int i = 0, size = branch.nodeCount(); i < size; i++) {
240             Node node = branch.node(i);
241             add((Node) node.clone());
242         }
243     }
244
245
246     public Node node(int index) {
247         Object JavaDoc object = contentList().get(index);
248         if (object instanceof Node) {
249             return (Node) object;
250         }
251         if (object instanceof String JavaDoc) {
252             return getNodeFactory().createText(object.toString());
253         }
254         return null;
255     }
256
257     public int nodeCount() {
258         return contentList().size();
259     }
260
261     public int indexOf(Node node) {
262         return contentList().indexOf(node);
263     }
264
265     public Iterator JavaDoc nodeIterator() {
266         return contentList().iterator();
267     }
268
269
270     // Implementation methods
271

272     /** @return the ID of the given <code>Element</code>
273      */

274     protected String JavaDoc elementID(Element element) {
275         // XXX: there will be other ways of finding the ID
276
// XXX: should probably have an IDResolver or something
277
return element.attributeValue("ID");
278     }
279
280     /** @return the internal List used to manage the content */
281     protected abstract List JavaDoc contentList();
282
283     /** A Factory Method pattern which creates
284      * a List implementation used to store content
285      */

286     protected List JavaDoc createContentList() {
287         return new ArrayList JavaDoc(DEFAULT_CONTENT_LIST_SIZE);
288     }
289
290     /** A Factory Method pattern which creates
291      * a List implementation used to store content
292      */

293     protected List JavaDoc createContentList(int size) {
294         return new ArrayList JavaDoc(size);
295     }
296
297
298     /** A Factory Method pattern which creates
299      * a BackedList implementation used to store results of
300      * a filtered content query. */

301     protected BackedList createResultList() {
302         return new BackedList(this, contentList());
303     }
304
305     /** A Factory Method pattern which creates
306      * a BackedList implementation which contains a single result
307      */

308     protected List JavaDoc createSingleResultList(Object JavaDoc result) {
309         BackedList list = new BackedList(this, contentList(), 1);
310         list.addLocal(result);
311         return list;
312     }
313
314     /** A Factory Method pattern which creates an empty
315      * a BackedList implementation
316      */

317     protected List JavaDoc createEmptyList() {
318         return new BackedList(this, contentList(), 0);
319     }
320
321
322     protected abstract void addNode(Node node);
323
324     protected abstract void addNode(int index, Node node);
325
326     protected abstract boolean removeNode(Node node);
327
328
329     /** Called when a new child node has been added to me
330      * to allow any parent relationships to be created or
331      * events to be fired.
332      */

333     protected abstract void childAdded(Node node);
334
335     /** Called when a child node has been removed
336      * to allow any parent relationships to be deleted or
337      * events to be fired.
338      */

339     protected abstract void childRemoved(Node node);
340
341     /** Called when the given List content has been removed so
342      * each node should have its parent and document relationships
343      * cleared
344      */

345     protected void contentRemoved() {
346         List JavaDoc content = contentList();
347         for (int i = 0, size = content.size(); i < size; i++) {
348             Object JavaDoc object = content.get(i);
349             if (object instanceof Node) {
350                 childRemoved((Node) object);
351             }
352         }
353     }
354
355     /** Called when an invalid node has been added.
356      * Throws an {@link IllegalAddException}.
357      */

358     protected void invalidNodeTypeAddException(Node node) {
359         throw new IllegalAddException("Invalid node type. Cannot add node: " + node + " to this branch: " + this);
360     }
361
362
363 }
364
365
366 /*
367  * Redistribution and use of this software and associated documentation
368  * ("Software"), with or without modification, are permitted provided
369  * that the following conditions are met:
370  *
371  * 1. Redistributions of source code must retain copyright
372  * statements and notices. Redistributions must also contain a
373  * copy of this document.
374  *
375  * 2. Redistributions in binary form must reproduce the
376  * above copyright notice, this list of conditions and the
377  * following disclaimer in the documentation and/or other
378  * materials provided with the distribution.
379  *
380  * 3. The name "DOM4J" must not be used to endorse or promote
381  * products derived from this Software without prior written
382  * permission of MetaStuff, Ltd. For written permission,
383  * please contact dom4j-info@metastuff.com.
384  *
385  * 4. Products derived from this Software may not be called "DOM4J"
386  * nor may "DOM4J" appear in their names without prior written
387  * permission of MetaStuff, Ltd. DOM4J is a registered
388  * trademark of MetaStuff, Ltd.
389  *
390  * 5. Due credit should be given to the DOM4J Project
391  * (http://dom4j.org/).
392  *
393  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
394  * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
395  * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
396  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
397  * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
398  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
399  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
400  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
401  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
402  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
403  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
404  * OF THE POSSIBILITY OF SUCH DAMAGE.
405  *
406  * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
407  *
408  * $Id: AbstractBranch.java,v 1.1 2003/11/02 18:10:03 per_nyfelt Exp $
409  */

410
Popular Tags