KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xml > dtm > ref > DTMTreeWalker


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: DTMTreeWalker.java,v 1.6 2004/02/16 23:06:11 minchau Exp $
18  */

19 package org.apache.xml.dtm.ref;
20
21 import org.apache.xml.dtm.DTM;
22 import org.apache.xml.utils.NodeConsumer;
23 import org.apache.xml.utils.XMLString;
24
25 import org.xml.sax.ContentHandler JavaDoc;
26 import org.xml.sax.ext.LexicalHandler JavaDoc;
27
28 /**
29  * This class does a pre-order walk of the DTM tree, calling a ContentHandler
30  * interface as it goes. As such, it's more like the Visitor design pattern
31  * than like the DOM's TreeWalker.
32  *
33  * I think normally this class should not be needed, because
34  * of DTM#dispatchToEvents.
35  * @xsl.usage advanced
36  */

37 public class DTMTreeWalker
38 {
39
40   /** Local reference to a ContentHandler */
41   private ContentHandler JavaDoc m_contentHandler = null;
42
43   /** DomHelper for this TreeWalker */
44   protected DTM m_dtm;
45   
46   /**
47    * Set the DTM to be traversed.
48    *
49    * @param dtm The Document Table Model to be used.
50    */

51   public void setDTM(DTM dtm)
52   {
53     m_dtm = dtm;
54   }
55
56   /**
57    * Get the ContentHandler used for the tree walk.
58    *
59    * @return the ContentHandler used for the tree walk
60    */

61   public ContentHandler JavaDoc getcontentHandler()
62   {
63     return m_contentHandler;
64   }
65   
66   /**
67    * Set the ContentHandler used for the tree walk.
68    *
69    * @param ch the ContentHandler to be the result of the tree walk.
70    */

71   public void setcontentHandler(ContentHandler JavaDoc ch)
72   {
73     m_contentHandler = ch;
74   }
75
76   
77   /**
78    * Constructor.
79    * @param contentHandler The implemention of the
80    * contentHandler operation (toXMLString, digest, ...)
81    */

82   public DTMTreeWalker()
83   {
84   }
85   
86   /**
87    * Constructor.
88    * @param contentHandler The implemention of the
89    * contentHandler operation (toXMLString, digest, ...)
90    */

91   public DTMTreeWalker(ContentHandler JavaDoc contentHandler, DTM dtm)
92   {
93     this.m_contentHandler = contentHandler;
94     m_dtm = dtm;
95   }
96   
97   /** Perform a non-recursive pre-order/post-order traversal,
98    * operating as a Visitor. startNode (preorder) and endNode
99    * (postorder) are invoked for each node as we traverse over them,
100    * with the result that the node is written out to m_contentHandler.
101    *
102    * @param pos Node in the tree at which to start (and end) traversal --
103    * in other words, the root of the subtree to traverse over.
104    *
105    * @throws TransformerException */

106   public void traverse(int pos) throws org.xml.sax.SAXException JavaDoc
107   {
108     // %REVIEW% Why isn't this just traverse(pos,pos)?
109

110     int top = pos; // Remember the root of this subtree
111

112     while (DTM.NULL != pos)
113     {
114       startNode(pos);
115       int nextNode = m_dtm.getFirstChild(pos);
116       while (DTM.NULL == nextNode)
117       {
118         endNode(pos);
119
120         if (top == pos)
121           break;
122
123         nextNode = m_dtm.getNextSibling(pos);
124
125         if (DTM.NULL == nextNode)
126         {
127           pos = m_dtm.getParent(pos);
128
129           if ((DTM.NULL == pos) || (top == pos))
130           {
131             // %REVIEW% This condition isn't tested in traverse(pos,top)
132
// -- bug?
133
if (DTM.NULL != pos)
134               endNode(pos);
135
136             nextNode = DTM.NULL;
137
138             break;
139           }
140         }
141       }
142
143       pos = nextNode;
144     }
145   }
146
147   /** Perform a non-recursive pre-order/post-order traversal,
148    * operating as a Visitor. startNode (preorder) and endNode
149    * (postorder) are invoked for each node as we traverse over them,
150    * with the result that the node is written out to m_contentHandler.
151    *
152    * @param pos Node in the tree where to start traversal
153    * @param top Node in the tree where to end traversal.
154    * If top==DTM.NULL, run through end of document.
155    *
156    * @throws TransformerException
157    */

158   public void traverse(int pos, int top) throws org.xml.sax.SAXException JavaDoc
159   {
160     // %OPT% Can we simplify the loop conditionals by adding:
161
// if(top==DTM.NULL) top=0
162
// -- or by simply ignoring this case and relying on the fact that
163
// pos will never equal DTM.NULL until we're ready to exit?
164

165     while (DTM.NULL != pos)
166     {
167       startNode(pos);
168       int nextNode = m_dtm.getFirstChild(pos);
169       while (DTM.NULL == nextNode)
170       {
171         endNode(pos);
172
173         if ((DTM.NULL != top) && top == pos)
174           break;
175
176         nextNode = m_dtm.getNextSibling(pos);
177
178         if (DTM.NULL == nextNode)
179         {
180           pos = m_dtm.getParent(pos);
181
182           if ((DTM.NULL == pos) || ((DTM.NULL != top) && (top == pos)))
183           {
184             nextNode = DTM.NULL;
185
186             break;
187           }
188         }
189       }
190
191       pos = nextNode;
192     }
193   }
194
195   /** Flag indicating whether following text to be processed is raw text */
196   boolean nextIsRaw = false;
197   
198   /**
199    * Optimized dispatch of characters.
200    */

201   private final void dispatachChars(int node)
202      throws org.xml.sax.SAXException JavaDoc
203   {
204     m_dtm.dispatchCharactersEvents(node, m_contentHandler, false);
205   }
206
207   /**
208    * Start processing given node
209    *
210    *
211    * @param node Node to process
212    *
213    * @throws org.xml.sax.SAXException
214    */

215   protected void startNode(int node) throws org.xml.sax.SAXException JavaDoc
216   {
217
218     if (m_contentHandler instanceof NodeConsumer)
219     {
220       // %TBD%
221
// ((NodeConsumer) m_contentHandler).setOriginatingNode(node);
222
}
223
224     switch (m_dtm.getNodeType(node))
225     {
226     case DTM.COMMENT_NODE :
227     {
228       XMLString data = m_dtm.getStringValue(node);
229
230       if (m_contentHandler instanceof LexicalHandler JavaDoc)
231       {
232         LexicalHandler JavaDoc lh = ((LexicalHandler JavaDoc) this.m_contentHandler);
233         data.dispatchAsComment(lh);
234       }
235     }
236     break;
237     case DTM.DOCUMENT_FRAGMENT_NODE :
238
239       // ??;
240
break;
241     case DTM.DOCUMENT_NODE :
242       this.m_contentHandler.startDocument();
243       break;
244     case DTM.ELEMENT_NODE :
245       DTM dtm = m_dtm;
246
247       for (int nsn = dtm.getFirstNamespaceNode(node, true); DTM.NULL != nsn;
248            nsn = dtm.getNextNamespaceNode(node, nsn, true))
249       {
250         // String prefix = dtm.getPrefix(nsn);
251
String JavaDoc prefix = dtm.getNodeNameX(nsn);
252
253         this.m_contentHandler.startPrefixMapping(prefix, dtm.getNodeValue(nsn));
254         
255       }
256
257       // System.out.println("m_dh.getNamespaceOfNode(node): "+m_dh.getNamespaceOfNode(node));
258
// System.out.println("m_dh.getLocalNameOfNode(node): "+m_dh.getLocalNameOfNode(node));
259
String JavaDoc ns = dtm.getNamespaceURI(node);
260       if(null == ns)
261         ns = "";
262         
263       // %OPT% !!
264
org.xml.sax.helpers.AttributesImpl JavaDoc attrs =
265                             new org.xml.sax.helpers.AttributesImpl JavaDoc();
266               
267       for (int i = dtm.getFirstAttribute(node);
268            i != DTM.NULL;
269            i = dtm.getNextAttribute(i))
270       {
271         attrs.addAttribute(dtm.getNamespaceURI(i),
272                            dtm.getLocalName(i),
273                            dtm.getNodeName(i),
274                            "CDATA",
275                            dtm.getNodeValue(i));
276       }
277       
278         
279       this.m_contentHandler.startElement(ns,
280                                          m_dtm.getLocalName(node),
281                                          m_dtm.getNodeName(node),
282                                          attrs);
283       break;
284     case DTM.PROCESSING_INSTRUCTION_NODE :
285     {
286       String JavaDoc name = m_dtm.getNodeName(node);
287
288       // String data = pi.getData();
289
if (name.equals("xslt-next-is-raw"))
290       {
291         nextIsRaw = true;
292       }
293       else
294       {
295         this.m_contentHandler.processingInstruction(name,
296                                                     m_dtm.getNodeValue(node));
297       }
298     }
299     break;
300     case DTM.CDATA_SECTION_NODE :
301     {
302       boolean isLexH = (m_contentHandler instanceof LexicalHandler JavaDoc);
303       LexicalHandler JavaDoc lh = isLexH
304                           ? ((LexicalHandler JavaDoc) this.m_contentHandler) : null;
305
306       if (isLexH)
307       {
308         lh.startCDATA();
309       }
310       
311       dispatachChars(node);
312
313       {
314         if (isLexH)
315         {
316           lh.endCDATA();
317         }
318       }
319     }
320     break;
321     case DTM.TEXT_NODE :
322     {
323       if (nextIsRaw)
324       {
325         nextIsRaw = false;
326
327         m_contentHandler.processingInstruction(javax.xml.transform.Result.PI_DISABLE_OUTPUT_ESCAPING, "");
328         dispatachChars(node);
329         m_contentHandler.processingInstruction(javax.xml.transform.Result.PI_ENABLE_OUTPUT_ESCAPING, "");
330       }
331       else
332       {
333         dispatachChars(node);
334       }
335     }
336     break;
337     case DTM.ENTITY_REFERENCE_NODE :
338     {
339       if (m_contentHandler instanceof LexicalHandler JavaDoc)
340       {
341         ((LexicalHandler JavaDoc) this.m_contentHandler).startEntity(
342           m_dtm.getNodeName(node));
343       }
344       else
345       {
346
347         // warning("Can not output entity to a pure SAX ContentHandler");
348
}
349     }
350     break;
351     default :
352     }
353   }
354
355   /**
356    * End processing of given node
357    *
358    *
359    * @param node Node we just finished processing
360    *
361    * @throws org.xml.sax.SAXException
362    */

363   protected void endNode(int node) throws org.xml.sax.SAXException JavaDoc
364   {
365
366     switch (m_dtm.getNodeType(node))
367     {
368     case DTM.DOCUMENT_NODE :
369       this.m_contentHandler.endDocument();
370       break;
371     case DTM.ELEMENT_NODE :
372       String JavaDoc ns = m_dtm.getNamespaceURI(node);
373       if(null == ns)
374         ns = "";
375       this.m_contentHandler.endElement(ns,
376                                          m_dtm.getLocalName(node),
377                                          m_dtm.getNodeName(node));
378
379       for (int nsn = m_dtm.getFirstNamespaceNode(node, true); DTM.NULL != nsn;
380            nsn = m_dtm.getNextNamespaceNode(node, nsn, true))
381       {
382         // String prefix = m_dtm.getPrefix(nsn);
383
String JavaDoc prefix = m_dtm.getNodeNameX(nsn);
384
385         this.m_contentHandler.endPrefixMapping(prefix);
386       }
387       break;
388     case DTM.CDATA_SECTION_NODE :
389       break;
390     case DTM.ENTITY_REFERENCE_NODE :
391     {
392       if (m_contentHandler instanceof LexicalHandler JavaDoc)
393       {
394         LexicalHandler JavaDoc lh = ((LexicalHandler JavaDoc) this.m_contentHandler);
395
396         lh.endEntity(m_dtm.getNodeName(node));
397       }
398     }
399     break;
400     default :
401     }
402   }
403 } //TreeWalker
404

405
Popular Tags