KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xml > serializer > ToSAXHandler


1 /*
2  * Copyright 2001-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: ToSAXHandler.java,v 1.10 2004/02/17 04:18:18 minchau Exp $
18  */

19 package org.apache.xml.serializer;
20
21 import java.util.Vector JavaDoc;
22
23 import org.xml.sax.Attributes JavaDoc;
24 import org.xml.sax.ContentHandler JavaDoc;
25 import org.xml.sax.ErrorHandler JavaDoc;
26 import org.xml.sax.SAXException JavaDoc;
27 import org.xml.sax.SAXParseException JavaDoc;
28 import org.xml.sax.ext.LexicalHandler JavaDoc;
29
30 /**
31  * @author Santiago Pericas-Geertsen
32  * @author G. Todd Miller
33  */

34 abstract public class ToSAXHandler extends SerializerBase
35 {
36     public ToSAXHandler()
37     {
38     }
39
40     public ToSAXHandler(
41         ContentHandler JavaDoc hdlr,
42         LexicalHandler JavaDoc lex,
43         String JavaDoc encoding)
44     {
45         setContentHandler(hdlr);
46         setLexHandler(lex);
47         setEncoding(encoding);
48     }
49     public ToSAXHandler(ContentHandler JavaDoc handler, String JavaDoc encoding)
50     {
51         setContentHandler(handler);
52         setEncoding(encoding);
53     }
54
55     /**
56      * Underlying SAX handler. Taken from XSLTC
57      */

58     protected ContentHandler JavaDoc m_saxHandler;
59
60     /**
61      * Underlying LexicalHandler. Taken from XSLTC
62      */

63     protected LexicalHandler JavaDoc m_lexHandler;
64
65     /**
66      * A startPrefixMapping() call on a ToSAXHandler will pass that call
67      * on to the wrapped ContentHandler, but should we also mirror these calls
68      * with matching attributes, if so this field is true.
69      * For example if this field is true then a call such as
70      * startPrefixMapping("prefix1","uri1") will also cause the additional
71      * internally generated attribute xmlns:prefix1="uri1" to be effectively added
72      * to the attributes passed to the wrapped ContentHandler.
73      */

74     private boolean m_shouldGenerateNSAttribute = true;
75     
76     /** If this is true, then the content handler wrapped by this
77      * serializer implements the TransformState interface which
78      * will give the content handler access to the state of
79      * the transform. */

80     protected TransformStateSetter m_state = null;
81
82     /**
83      * Pass callback to the SAX Handler
84      */

85     protected void startDocumentInternal() throws SAXException JavaDoc
86     {
87         if (m_needToCallStartDocument)
88         {
89             super.startDocumentInternal();
90
91             m_saxHandler.startDocument();
92             m_needToCallStartDocument = false;
93         }
94     }
95     /**
96      * Do nothing.
97      * @see org.xml.sax.ext.LexicalHandler#startDTD(String, String, String)
98      */

99     public void startDTD(String JavaDoc arg0, String JavaDoc arg1, String JavaDoc arg2)
100         throws SAXException JavaDoc
101     {
102         // do nothing for now
103
}
104
105     /**
106      * Receive notification of character data.
107      *
108      * @param chars The string of characters to process.
109      *
110      * @throws org.xml.sax.SAXException
111      *
112      * @see org.apache.xml.serializer.ExtendedContentHandler#characters(String)
113      */

114     public void characters(String JavaDoc characters) throws SAXException JavaDoc
115     {
116         final int len = characters.length();
117         if (len > m_charsBuff.length)
118         {
119            m_charsBuff = new char[len*2 + 1];
120         }
121         characters.getChars(0,len, m_charsBuff, 0);
122         characters(m_charsBuff, 0, len);
123     }
124
125     /**
126      * Receive notification of a comment.
127      *
128      * @see org.apache.xml.serializer.ExtendedLexicalHandler#comment(String)
129      */

130     public void comment(String JavaDoc comment) throws SAXException JavaDoc
131     {
132
133         // Close any open element before emitting comment
134
if (m_elemContext.m_startTagOpen)
135         {
136             closeStartTag();
137         }
138         else if (m_cdataTagOpen)
139         {
140             closeCDATA();
141         }
142
143         // Ignore if a lexical handler has not been set
144
if (m_lexHandler != null)
145         {
146             final int len = comment.length();
147             if (len > m_charsBuff.length)
148             {
149                m_charsBuff = new char[len*2 + 1];
150             }
151             comment.getChars(0,len, m_charsBuff, 0);
152             m_lexHandler.comment(m_charsBuff, 0, len);
153             // time to fire off comment event
154
if (m_tracer != null)
155                 super.fireCommentEvent(m_charsBuff, 0, len);
156         }
157
158     }
159
160     /**
161      * Do nothing as this is an abstract class. All subclasses will need to
162      * define their behavior if it is different.
163      * @see org.xml.sax.ContentHandler#processingInstruction(String, String)
164      */

165     public void processingInstruction(String JavaDoc target, String JavaDoc data)
166         throws SAXException JavaDoc
167     {
168         // Redefined in SAXXMLOutput
169
}
170
171     protected void closeStartTag() throws SAXException JavaDoc
172     {
173     }
174
175     protected void closeCDATA() throws SAXException JavaDoc
176     {
177         // Redefined in SAXXMLOutput
178
}
179     
180     /**
181      * Receive notification of the beginning of an element, although this is a
182      * SAX method additional namespace or attribute information can occur before
183      * or after this call, that is associated with this element.
184      *
185      *
186      * @param namespaceURI The Namespace URI, or the empty string if the
187      * element has no Namespace URI or if Namespace
188      * processing is not being performed.
189      * @param localName The local name (without prefix), or the
190      * empty string if Namespace processing is not being
191      * performed.
192      * @param name The element type name.
193      * @param atts The attributes attached to the element, if any.
194      * @throws org.xml.sax.SAXException Any SAX exception, possibly
195      * wrapping another exception.
196      * @see org.xml.sax.ContentHandler#startElement
197      * @see org.xml.sax.ContentHandler#endElement
198      * @see org.xml.sax.AttributeList
199      *
200      * @throws org.xml.sax.SAXException
201      *
202      * @see org.xml.sax.ContentHandler#startElement(String,String,String,Attributes)
203      */

204     public void startElement(
205         String JavaDoc arg0,
206         String JavaDoc arg1,
207         String JavaDoc arg2,
208         Attributes JavaDoc arg3)
209         throws SAXException JavaDoc
210     {
211         if (m_state != null) {
212             m_state.resetState(getTransformer());
213         }
214
215         // fire off the start element event
216
if (m_tracer != null)
217             super.fireStartElem(arg2);
218     }
219
220     /**
221      * Sets the LexicalHandler.
222      * @param _lexHandler The LexicalHandler to set
223      */

224     public void setLexHandler(LexicalHandler JavaDoc _lexHandler)
225     {
226         this.m_lexHandler = _lexHandler;
227     }
228
229     /**
230      * Sets the SAX ContentHandler.
231      * @param m_saxHandler The ContentHandler to set
232      */

233     public void setContentHandler(ContentHandler JavaDoc _saxHandler)
234     {
235         this.m_saxHandler = _saxHandler;
236         if (m_lexHandler == null && _saxHandler instanceof LexicalHandler JavaDoc)
237         {
238             // we are not overwriting an existing LexicalHandler, and _saxHandler
239
// is also implements LexicalHandler, so lets use it
240
m_lexHandler = (LexicalHandler JavaDoc) _saxHandler;
241         }
242     }
243
244     /**
245      * Does nothing. The setting of CDATA section elements has an impact on
246      * stream serializers.
247      * @see org.apache.xml.serializer.SerializationHandler#setCdataSectionElements(java.util.Vector)
248      */

249     public void setCdataSectionElements(Vector JavaDoc URI_and_localNames)
250     {
251         // do nothing
252
}
253     
254     /** Set whether or not namespace declarations (e.g.
255      * xmlns:foo) should appear as attributes of
256      * elements
257      * @param doOutputNSAttr whether or not namespace declarations
258      * should appear as attributes
259      */

260     public void setShouldOutputNSAttr(boolean doOutputNSAttr)
261     {
262         m_shouldGenerateNSAttribute = doOutputNSAttr;
263     }
264  
265     /**
266      * Returns true if namespace declarations from calls such as
267      * startPrefixMapping("prefix1","uri1") should
268      * also be mirrored with self generated additional attributes of elements
269      * that declare the namespace, for example the attribute xmlns:prefix1="uri1"
270      */

271     boolean getShouldOutputNSAttr()
272     {
273         return m_shouldGenerateNSAttribute;
274     }
275
276     /**
277      * This method flushes any pending events, which can be startDocument()
278      * closing the opening tag of an element, or closing an open CDATA section.
279      */

280     public void flushPending() throws SAXException JavaDoc
281     {
282     
283             if (m_needToCallStartDocument)
284             {
285                 startDocumentInternal();
286                 m_needToCallStartDocument = false;
287             }
288
289             if (m_elemContext.m_startTagOpen)
290             {
291                 closeStartTag();
292                 m_elemContext.m_startTagOpen = false;
293             }
294             
295             if (m_cdataTagOpen)
296             {
297                 closeCDATA();
298                 m_cdataTagOpen = false;
299             }
300
301     }
302
303     /**
304      * Pass in a reference to a TransformState object, which
305      * can be used during SAX ContentHandler events to obtain
306      * information about he state of the transformation. This
307      * method will be called before each startDocument event.
308      *
309      * @param ts A reference to a TransformState object
310      */

311     public void setTransformState(TransformStateSetter ts) {
312         this.m_state = ts;
313     }
314     
315     /**
316      * Receives notification that an element starts, but attributes are not
317      * fully known yet.
318      *
319      * @param uri the URI of the namespace of the element (optional)
320      * @param localName the element name, but without prefix (optional)
321      * @param qName the element name, with prefix, if any (required)
322      *
323      * @see org.apache.xml.serializer.ExtendedContentHandler#startElement(String, String, String)
324      */

325     public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName)
326         throws SAXException JavaDoc {
327             
328         if (m_state != null) {
329             m_state.resetState(getTransformer());
330         }
331
332         // fire off the start element event
333
if (m_tracer != null)
334             super.fireStartElem(qName);
335     }
336
337     /**
338      * An element starts, but attributes are not fully known yet.
339      *
340      * @param elementName the element name, with prefix (if any).
341
342      * @see org.apache.xml.serializer.ExtendedContentHandler#startElement(String)
343      */

344     public void startElement(String JavaDoc qName) throws SAXException JavaDoc {
345         if (m_state != null) {
346             m_state.resetState(getTransformer());
347         }
348         // fire off the start element event
349
if (m_tracer != null)
350             super.fireStartElem(qName);
351     }
352     
353     /**
354      * This method gets the node's value as a String and uses that String as if
355      * it were an input character notification.
356      * @param node the Node to serialize
357      * @throws org.xml.sax.SAXException
358      */

359     public void characters(org.w3c.dom.Node JavaDoc node)
360         throws org.xml.sax.SAXException JavaDoc
361     {
362         // remember the current node
363
if (m_state != null)
364         {
365             m_state.setCurrentNode(node);
366         }
367         
368         // Get the node's value as a String and use that String as if
369
// it were an input character notification.
370
String JavaDoc data = node.getNodeValue();
371         if (data != null) {
372             this.characters(data);
373         }
374     }
375
376     /**
377      * @see org.xml.sax.ErrorHandler#fatalError(SAXParseException)
378      */

379     public void fatalError(SAXParseException JavaDoc exc) throws SAXException JavaDoc {
380         super.fatalError(exc);
381         
382         m_needToCallStartDocument = false;
383         
384         if (m_saxHandler instanceof ErrorHandler JavaDoc) {
385             ((ErrorHandler JavaDoc)m_saxHandler).fatalError(exc);
386         }
387     }
388
389     /**
390      * @see org.xml.sax.ErrorHandler#error(SAXParseException)
391      */

392     public void error(SAXParseException JavaDoc exc) throws SAXException JavaDoc {
393         super.error(exc);
394         
395         if (m_saxHandler instanceof ErrorHandler JavaDoc)
396             ((ErrorHandler JavaDoc)m_saxHandler).error(exc);
397         
398     }
399
400     /**
401      * @see org.xml.sax.ErrorHandler#warning(SAXParseException)
402      */

403     public void warning(SAXParseException JavaDoc exc) throws SAXException JavaDoc {
404         super.warning(exc);
405         
406         if (m_saxHandler instanceof ErrorHandler JavaDoc)
407             ((ErrorHandler JavaDoc)m_saxHandler).warning(exc);
408     }
409     
410        
411     /**
412      * Try's to reset the super class and reset this class for
413      * re-use, so that you don't need to create a new serializer
414      * (mostly for performance reasons).
415      *
416      * @return true if the class was successfuly reset.
417      * @see org.apache.xml.serializer.Serializer#reset()
418      */

419     public boolean reset()
420     {
421         boolean wasReset = false;
422         if (super.reset())
423         {
424             resetToSAXHandler();
425             wasReset = true;
426         }
427         return wasReset;
428     }
429     
430     /**
431      * Reset all of the fields owned by ToSAXHandler class
432      *
433      */

434     private void resetToSAXHandler()
435     {
436         this.m_lexHandler = null;
437         this.m_saxHandler = null;
438         this.m_state = null;
439         this.m_shouldGenerateNSAttribute = false;
440     }
441
442     /**
443      * Add a unique attribute
444      */

445     public void addUniqueAttribute(String JavaDoc qName, String JavaDoc value, int flags)
446         throws SAXException JavaDoc
447     {
448         addAttribute(qName, value);
449     }
450 }
451
Popular Tags