View Javadoc
1   /*
2    * Redistribution and use of this software and associated documentation ("Software"), with or
3    * without modification, are permitted provided that the following conditions are met:
4    *
5    * 1. Redistributions of source code must retain copyright statements and notices. Redistributions
6    * must also contain a copy of this document.
7    *
8    * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
9    * conditions and the following disclaimer in the documentation and/or other materials provided with
10   * the distribution.
11   *
12   * 3. The name "Exolab" must not be used to endorse or promote products derived from this Software
13   * without prior written permission of Intalio, Inc. For written permission, please contact
14   * info@exolab.org.
15   *
16   * 4. Products derived from this Software may not be called "Exolab" nor may "Exolab" appear in
17   * their names without prior written permission of Intalio, Inc. Exolab is a registered trademark of
18   * Intalio, Inc.
19   *
20   * 5. Due credit should be given to the Exolab Project (http://www.exolab.org/).
21   *
22   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR
23   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
24   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTALIO, INC. OR ITS
25   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
29   * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30   *
31   * Copyright 1999 (C) Intalio, Inc. All Rights Reserved.
32   *
33   * This file was adapted From XSL:P
34   *
35   * $Id$
36   */
37  package org.exolab.castor.xml.util;
38  
39  import org.exolab.castor.xml.EventProducer;
40  import org.w3c.dom.Document;
41  import org.w3c.dom.Element;
42  import org.w3c.dom.Node;
43  import org.w3c.dom.ProcessingInstruction;
44  import org.w3c.dom.Text;
45  import org.xml.sax.AttributeList;
46  import org.xml.sax.DocumentHandler;
47  
48  /**
49   * A class for converting a DOM document to SAX events
50   * 
51   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
52   * @version $Revision$ $Date: 2003-03-03 00:05:44 -0700 (Mon, 03 Mar 2003) $
53   **/
54  public class DOMEventProducer implements EventProducer {
55  
56  
57    private DocumentHandler _handler = null;
58  
59    private Node _node = null;
60  
61    /**
62     * Creates a new DOMEventProducer
63     **/
64    public DOMEventProducer() {
65      super();
66    } // -- DOMEventProducer
67  
68    /**
69     * Creates a new DOMEventProducer for the given Node
70     * 
71     * @param node the node to create the DOMEventProducer for.
72     **/
73    public DOMEventProducer(Node node) {
74      super();
75      this._node = node;
76    } // -- DOMEventProducer
77  
78  
79    /**
80     * Sets the DocumentHandler to use when firing events
81     **/
82    public void setDocumentHandler(DocumentHandler handler) {
83      this._handler = handler;
84    } // -- setDocumentHandler
85  
86    /**
87     * Sets the node which is to be converted into SAX events
88     * 
89     * @param node the node which is to be converted into SAX events
90     **/
91    public void setNode(Node node) {
92      this._node = node;
93    } // -- setNode
94  
95    /**
96     * Starts producing the events for the Node which is to be converted into SAX events
97     **/
98    public void start() throws org.xml.sax.SAXException {
99      if ((_node == null) || (_handler == null))
100       return;
101 
102     process(_node, _handler);
103 
104   } // -- start
105 
106   /**
107    * Walks the given DOM Document and converts it into it's corresponding SAX events
108    * 
109    * @param document the Node to process into SAX events
110    * @param handler the DocumentHandler to send events to
111    **/
112   public static void process(Document document, DocumentHandler handler)
113 
114       throws org.xml.sax.SAXException
115 
116   {
117 
118     if (document == null)
119       return;
120 
121     if (handler == null)
122       return;
123 
124 
125 
126     handler.startDocument();
127 
128     processChildren(document, handler);
129 
130     handler.endDocument();
131 
132 
133 
134   } // -- process(Document, DocumentHandler)
135 
136 
137 
138   /**
139    * 
140    * Breaks down the given node into it's corresponding SAX events
141    * 
142    * @param node the Node to process into SAX events
143    * 
144    * @param handler the DocumentHandler to send events to
145    * 
146    **/
147 
148   public static void process(Node node, DocumentHandler handler)
149 
150       throws org.xml.sax.SAXException
151 
152   {
153 
154 
155 
156     if ((node == null) || (handler == null))
157       return;
158 
159 
160 
161     switch (node.getNodeType()) {
162 
163       case Node.DOCUMENT_NODE:
164 
165         process((Document) node, handler);
166 
167         break;
168 
169       case Node.DOCUMENT_FRAGMENT_NODE:
170 
171         processChildren(node, handler);
172 
173         break;
174 
175       case Node.ELEMENT_NODE:
176 
177         process((Element) node, handler);
178 
179         break;
180 
181       case Node.CDATA_SECTION_NODE:
182 
183       case Node.TEXT_NODE:
184 
185         process((Text) node, handler);
186 
187         break;
188 
189       case Node.PROCESSING_INSTRUCTION_NODE:
190 
191         process((ProcessingInstruction) node, handler);
192 
193         break;
194 
195       case Node.COMMENT_NODE:
196 
197 
198 
199       default:
200 
201         break;
202 
203     }
204 
205 
206 
207   } // -- process(Node, DocumentHandler)
208 
209 
210 
211   // -------------------/
212 
213   // - Private Methods -/
214 
215   // -------------------/
216 
217 
218 
219   /**
220    * 
221    * Breaks down the given node into it's corresponding SAX events
222    * 
223    * @param handler the DocumentHandler to send events to
224    * 
225    **/
226 
227   private static void process(Element element, DocumentHandler handler)
228 
229       throws org.xml.sax.SAXException
230 
231   {
232 
233 
234 
235     String name = element.getNodeName();
236 
237     AttributeList atts = new AttributeListWrapper(element.getAttributes());
238 
239     handler.startElement(name, atts);
240 
241     processChildren(element, handler);
242 
243     handler.endElement(name);
244 
245   } // -- process(Element, DocumentHandler);
246 
247 
248 
249   /**
250    * 
251    * Breaks down the given node into it's corresponding SAX events
252    * 
253    * @param handler the DocumentHandler to send events to
254    * 
255    **/
256 
257   private static void process(Text text, DocumentHandler handler)
258 
259       throws org.xml.sax.SAXException
260 
261   {
262 
263     String data = text.getData();
264 
265     if ((data != null) && (data.length() > 0)) {
266 
267       char[] chars = data.toCharArray();
268 
269       handler.characters(chars, 0, chars.length);
270 
271     }
272 
273   } // -- process(Text, DocumentHandler)
274 
275 
276 
277   /**
278    * 
279    * Breaks down the given ProcessingInstruction into it's corresponding
280    * 
281    * SAX event
282    * 
283    * @param pi the processing instruction to process
284    * 
285    * @param handler the DocumentHandler to send events to
286    * 
287    **/
288 
289   private static void process
290 
291   (ProcessingInstruction pi, DocumentHandler handler)
292 
293       throws org.xml.sax.SAXException
294 
295   {
296 
297     handler.processingInstruction(pi.getTarget(), pi.getData());
298 
299 
300 
301   } // -- process(ProcessingInstruction, DocumentHandler);
302 
303 
304 
305   /**
306    * 
307    * Processes the children of the given Node
308    * 
309    * @param node the Node to process the children of
310    * 
311    * @param handler the DocumentHandler to send events to
312    * 
313    **/
314 
315   private static void processChildren
316 
317   (Node node, DocumentHandler handler)
318 
319       throws org.xml.sax.SAXException
320 
321   {
322 
323     Node child = node.getFirstChild();
324 
325     while (child != null) {
326 
327       process(child, handler);
328 
329       child = child.getNextSibling();
330 
331     }
332 
333 
334 
335   } // -- processChildren
336 
337 
338 
339 } // -- DOMEventProducer
340