KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xml > internal > serializer > ToHTMLSAXHandler


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: ToHTMLSAXHandler.java,v 1.8 2004/02/17 04:18:19 minchau Exp $
18  */

19
20 package com.sun.org.apache.xml.internal.serializer;
21
22 import java.io.IOException JavaDoc;
23 import java.io.OutputStream JavaDoc;
24 import java.io.Writer JavaDoc;
25 import java.util.Properties JavaDoc;
26
27 import javax.xml.transform.Result JavaDoc;
28
29 import org.w3c.dom.Node JavaDoc;
30 import org.xml.sax.Attributes JavaDoc;
31 import org.xml.sax.ContentHandler JavaDoc;
32 import org.xml.sax.Locator JavaDoc;
33 import org.xml.sax.SAXException JavaDoc;
34 import org.xml.sax.ext.LexicalHandler JavaDoc;
35
36 /**
37  * This class accepts SAX-like calls, then sends true SAX calls to a
38  * wrapped SAX handler. There is optimization done knowing that the ultimate
39  * output is HTML.
40  * @author Santiago Pericas-Geertsen
41  * @author G. Todd Miller
42  */

43 public class ToHTMLSAXHandler extends ToSAXHandler
44 {
45
46     /**
47      * Keeps track of whether output escaping is currently enabled
48      */

49     protected boolean m_escapeSetting = false;
50
51     /**
52      * Returns null.
53      * @return null
54      * @see com.sun.org.apache.xml.internal.serializer.Serializer#getOutputFormat()
55      */

56     public Properties JavaDoc getOutputFormat()
57     {
58         return null;
59     }
60
61     /**
62      * Reurns null
63      * @return null
64      * @see com.sun.org.apache.xml.internal.serializer.Serializer#getOutputStream()
65      */

66     public OutputStream JavaDoc getOutputStream()
67     {
68         return null;
69     }
70
71     /**
72      * Returns null
73      * @return null
74      * @see com.sun.org.apache.xml.internal.serializer.Serializer#getWriter()
75      */

76     public Writer JavaDoc getWriter()
77     {
78         return null;
79     }
80
81     /**
82      * Does nothing.
83      *
84      */

85     public void indent(int n) throws SAXException JavaDoc
86     {
87     }
88
89     /**
90      * Does nothing.
91      * @see com.sun.org.apache.xml.internal.serializer.DOMSerializer#serialize(Node)
92      */

93     public void serialize(Node JavaDoc node) throws IOException JavaDoc
94     {
95         return;
96     }
97
98     /**
99      * Turns special character escaping on/off.
100      *
101      *
102      * @param excape true if escaping is to be set on.
103      *
104      * @see com.sun.org.apache.xml.internal.serializer.SerializationHandler#setEscaping(boolean)
105      */

106     public boolean setEscaping(boolean escape) throws SAXException JavaDoc
107     {
108         boolean oldEscapeSetting = m_escapeSetting;
109         m_escapeSetting = escape;
110
111         if (escape) {
112             processingInstruction(Result.PI_ENABLE_OUTPUT_ESCAPING, "");
113         } else {
114             processingInstruction(Result.PI_DISABLE_OUTPUT_ESCAPING, "");
115         }
116
117         return oldEscapeSetting;
118     }
119
120     /**
121      * Does nothing
122      * @param indent the number of spaces to indent per indentation level
123      * (ignored)
124      * @see com.sun.org.apache.xml.internal.serializer.SerializationHandler#setIndent(boolean)
125      */

126     public void setIndent(boolean indent)
127     {
128     }
129
130     /**
131      * Does nothing.
132      * @param format this parameter is not used
133      * @see com.sun.org.apache.xml.internal.serializer.Serializer#setOutputFormat(Properties)
134      */

135     public void setOutputFormat(Properties JavaDoc format)
136     {
137     }
138
139     /**
140      * Does nothing.
141      * @param output this parameter is ignored
142      * @see com.sun.org.apache.xml.internal.serializer.Serializer#setOutputStream(OutputStream)
143      */

144     public void setOutputStream(OutputStream JavaDoc output)
145     {
146     }
147
148
149     /**
150      * Does nothing.
151      * @param writer this parameter is ignored.
152      * @see com.sun.org.apache.xml.internal.serializer.Serializer#setWriter(Writer)
153      */

154     public void setWriter(Writer JavaDoc writer)
155     {
156     }
157
158     /**
159      * @see org.xml.sax.ext.DeclHandler#attributeDecl(String, String, String, String, String)
160      */

161     /**
162      * Does nothing.
163      *
164      * @param eName this parameter is ignored
165      * @param aName this parameter is ignored
166      * @param type this parameter is ignored
167      * @param valueDefault this parameter is ignored
168      * @param value this parameter is ignored
169      * @see org.xml.sax.ext.DeclHandler#attributeDecl(String, String, String,String,String)
170      */

171     public void attributeDecl(
172         String JavaDoc eName,
173         String JavaDoc aName,
174         String JavaDoc type,
175         String JavaDoc valueDefault,
176         String JavaDoc value)
177         throws SAXException JavaDoc
178     {
179     }
180
181
182     /**
183      * Does nothing.
184      * @see org.xml.sax.ext.DeclHandler#elementDecl(String, String)
185      */

186     public void elementDecl(String JavaDoc name, String JavaDoc model) throws SAXException JavaDoc
187     {
188         return;
189     }
190
191     /**
192      * @see org.xml.sax.ext.DeclHandler#externalEntityDecl(String, String, String)
193      */

194     public void externalEntityDecl(String JavaDoc arg0, String JavaDoc arg1, String JavaDoc arg2)
195         throws SAXException JavaDoc
196     {
197     }
198
199     /**
200      * Does nothing.
201      *
202      * @see org.xml.sax.DTDHandler#unparsedEntityDecl
203      */

204     public void internalEntityDecl(String JavaDoc name, String JavaDoc value)
205         throws SAXException JavaDoc
206     {
207     }
208
209     /**
210      * Receive notification of the end of an element.
211      *
212      * <p>The SAX parser will invoke this method at the end of every
213      * element in the XML document; there will be a corresponding
214      * startElement() event for every endElement() event (even when the
215      * element is empty).</p>
216      *
217      * <p>If the element name has a namespace prefix, the prefix will
218      * still be attached to the name.</p>
219      *
220      *
221      * @param namespaceURI The Namespace URI, or the empty string if the
222      * element has no Namespace URI or if Namespace
223      * processing is not being performed.
224      * @param localName The local name (without prefix), or the
225      * empty string if Namespace processing is not being
226      * performed.
227      * @param name The qualified name (with prefix), or the
228      * empty string if qualified names are not available.
229      * @param name The element type name
230      * @throws org.xml.sax.SAXException Any SAX exception, possibly
231      * wrapping another exception.
232      * @see org.xml.sax.ContentHandler#endElement(String, String, String)
233      */

234     public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName)
235         throws SAXException JavaDoc
236     {
237         flushPending();
238         m_saxHandler.endElement(uri, localName, qName);
239         
240         // time to fire off endElement event
241
if (m_tracer != null)
242             super.fireEndElem(qName);
243     }
244
245     /**
246      * Does nothing.
247      */

248     public void endPrefixMapping(String JavaDoc prefix) throws SAXException JavaDoc
249     {
250     }
251
252     /**
253      * Does nothing.
254      * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
255      */

256     public void ignorableWhitespace(char[] ch, int start, int length)
257         throws SAXException JavaDoc
258     {
259     }
260     
261     /**
262      * Receive notification of a processing instruction.
263      *
264      * <p>The Parser will invoke this method once for each processing
265      * instruction found: note that processing instructions may occur
266      * before or after the main document element.</p>
267      *
268      * <p>A SAX parser should never report an XML declaration (XML 1.0,
269      * section 2.8) or a text declaration (XML 1.0, section 4.3.1)
270      * using this method.</p>
271      *
272      * @param target The processing instruction target.
273      * @param data The processing instruction data, or null if
274      * none was supplied.
275      * @throws org.xml.sax.SAXException Any SAX exception, possibly
276      * wrapping another exception.
277      *
278      * @throws org.xml.sax.SAXException
279      * @see org.xml.sax.ContentHandler#processingInstruction(String, String)
280      */

281     public void processingInstruction(String JavaDoc arg0, String JavaDoc arg1)
282         throws SAXException JavaDoc
283     {
284         flushPending();
285         m_saxHandler.processingInstruction(arg0,arg1);
286
287         // time to fire off processing instruction event
288

289         if (m_tracer != null)
290             super.fireEscapingEvent(arg0,arg1);
291     }
292
293     /**
294      * Does nothing.
295      * @see org.xml.sax.ContentHandler#setDocumentLocator(Locator)
296      */

297     public void setDocumentLocator(Locator JavaDoc arg0)
298     {
299         // do nothing
300
}
301
302     /**
303      * Does nothing.
304      * @see org.xml.sax.ContentHandler#skippedEntity(String)
305      */

306     public void skippedEntity(String JavaDoc arg0) throws SAXException JavaDoc
307     {
308     }
309
310     /**
311      * Receive notification of the beginning of an element, although this is a
312      * SAX method additional namespace or attribute information can occur before
313      * or after this call, that is associated with this element.
314      *
315      *
316      * @param namespaceURI The Namespace URI, or the empty string if the
317      * element has no Namespace URI or if Namespace
318      * processing is not being performed.
319      * @param localName The local name (without prefix), or the
320      * empty string if Namespace processing is not being
321      * performed.
322      * @param qName The elements name.
323      * @param atts The attributes attached to the element, if any.
324      * @throws org.xml.sax.SAXException Any SAX exception, possibly
325      * wrapping another exception.
326      * @see org.xml.sax.ContentHandler#startElement
327      * @see org.xml.sax.ContentHandler#endElement
328      * @see org.xml.sax.AttributeList
329      *
330      * @throws org.xml.sax.SAXException
331      *
332      * @see org.xml.sax.ContentHandler#startElement(String, String, String, Attributes)
333      */

334     public void startElement(
335         String JavaDoc namespaceURI,
336         String JavaDoc localName,
337         String JavaDoc qName,
338         Attributes JavaDoc atts)
339         throws SAXException JavaDoc
340     {
341         flushPending();
342         super.startElement(namespaceURI, localName, qName, atts);
343         m_saxHandler.startElement(namespaceURI, localName, qName, atts);
344         m_elemContext.m_startTagOpen = false;
345     }
346
347     /**
348      * Receive notification of a comment anywhere in the document. This callback
349      * will be used for comments inside or outside the document element.
350      * @param ch An array holding the characters in the comment.
351      * @param start The starting position in the array.
352      * @param length The number of characters to use from the array.
353      * @throws org.xml.sax.SAXException The application may raise an exception.
354      *
355      * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int)
356      */

357     public void comment(char[] ch, int start, int length) throws SAXException JavaDoc
358     {
359         flushPending();
360         m_lexHandler.comment(ch, start, length);
361
362         // time to fire off comment event
363
if (m_tracer != null)
364             super.fireCommentEvent(ch, start, length);
365         return;
366     }
367
368     /**
369      * Does nothing.
370      * @see org.xml.sax.ext.LexicalHandler#endCDATA()
371      */

372     public void endCDATA() throws SAXException JavaDoc
373     {
374         return;
375     }
376
377     /**
378      * Does nothing.
379      * @see org.xml.sax.ext.LexicalHandler#endDTD()
380      */

381     public void endDTD() throws SAXException JavaDoc
382     {
383     }
384
385     /**
386      * Does nothing.
387      * @see org.xml.sax.ext.LexicalHandler#startCDATA()
388      */

389     public void startCDATA() throws SAXException JavaDoc
390     {
391     }
392
393     /**
394      * Does nothing.
395      * @see org.xml.sax.ext.LexicalHandler#startEntity(String)
396      */

397     public void startEntity(String JavaDoc arg0) throws SAXException JavaDoc
398     {
399     }
400
401     /**
402      * Receive notification of the end of a document.
403      *
404      * <p>The SAX parser will invoke this method only once, and it will
405      * be the last method invoked during the parse. The parser shall
406      * not invoke this method until it has either abandoned parsing
407      * (because of an unrecoverable error) or reached the end of
408      * input.</p>
409      *
410      * @throws org.xml.sax.SAXException Any SAX exception, possibly
411      * wrapping another exception.
412      *
413      * @throws org.xml.sax.SAXException
414      *
415      *
416      */

417     public void endDocument() throws SAXException JavaDoc
418     {
419         flushPending();
420
421         // Close output document
422
m_saxHandler.endDocument();
423
424         if (m_tracer != null)
425             super.fireEndDoc();
426     }
427
428     /**
429      * This method is called when all the data needed for a call to the
430      * SAX handler's startElement() method has been gathered.
431      */

432     protected void closeStartTag() throws SAXException JavaDoc
433     {
434
435         m_elemContext.m_startTagOpen = false;
436
437         // Now is time to send the startElement event
438
m_saxHandler.startElement(
439             EMPTYSTRING,
440             m_elemContext.m_elementName,
441             m_elemContext.m_elementName,
442             m_attributes);
443         m_attributes.clear();
444
445     }
446
447     /**
448      * Do nothing.
449      * @see com.sun.org.apache.xml.internal.serializer.SerializationHandler#close()
450      */

451     public void close()
452     {
453         return;
454     }
455
456     /**
457      * Receive notification of character data.
458      *
459      * @param chars The string of characters to process.
460      *
461      * @throws org.xml.sax.SAXException
462      *
463      * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#characters(String)
464      */

465     public void characters(final String JavaDoc chars) throws SAXException JavaDoc
466     {
467         final int length = chars.length();
468         if (length > m_charsBuff.length)
469         {
470             m_charsBuff = new char[length * 2 + 1];
471         }
472         chars.getChars(0, length, m_charsBuff, 0);
473         this.characters(m_charsBuff, 0, length);
474     }
475
476
477     /**
478      * A constructor
479      * @param handler the wrapped SAX content handler
480      * @param encoding the encoding of the output HTML document
481      */

482     public ToHTMLSAXHandler(ContentHandler JavaDoc handler, String JavaDoc encoding)
483     {
484         super(handler,encoding);
485     }
486     /**
487      * A constructor.
488      * @param handler the wrapped SAX content handler
489      * @param lex the wrapped lexical handler
490      * @param encoding the encoding of the output HTML document
491      */

492     public ToHTMLSAXHandler(
493         ContentHandler JavaDoc handler,
494         LexicalHandler JavaDoc lex,
495         String JavaDoc encoding)
496     {
497         super(handler,lex,encoding);
498     }
499
500     /**
501      * An element starts, but attributes are not fully known yet.
502      *
503      * @param elementNamespaceURI the URI of the namespace of the element
504      * (optional)
505      * @param elementLocalName the element name, but without prefix
506      * (optional)
507      * @param elementName the element name, with prefix, if any (required)
508      *
509      * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#startElement(String)
510      */

511     public void startElement(
512         String JavaDoc elementNamespaceURI,
513         String JavaDoc elementLocalName,
514         String JavaDoc elementName) throws SAXException JavaDoc
515     {
516
517         super.startElement(elementNamespaceURI, elementLocalName, elementName);
518
519         flushPending();
520
521         // Handle document type declaration (for first element only)
522
if (m_lexHandler != null)
523         {
524             String JavaDoc doctypeSystem = getDoctypeSystem();
525             String JavaDoc doctypePublic = getDoctypePublic();
526             if ((doctypeSystem != null) || (doctypePublic != null))
527                 m_lexHandler.startDTD(
528                     elementName,
529                     doctypePublic,
530                     doctypeSystem);
531             m_lexHandler = null;
532         }
533         m_elemContext = m_elemContext.push(elementNamespaceURI, elementLocalName, elementName);
534     }
535     /**
536      * An element starts, but attributes are not fully known yet.
537      *
538      * @param elementName the element name, with prefix, if any
539      *
540      * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#startElement(String)
541      */

542     public void startElement(String JavaDoc elementName) throws SAXException JavaDoc
543     {
544         this.startElement(null,null, elementName);
545     }
546     
547     /**
548      * Receive notification of the end of an element.
549      * @param elementName The element type name
550      * @throws org.xml.sax.SAXException Any SAX exception, possibly
551      * wrapping another exception.
552      *
553      * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#endElement(String)
554      */

555     public void endElement(String JavaDoc elementName) throws SAXException JavaDoc
556     {
557         flushPending();
558         m_saxHandler.endElement(EMPTYSTRING, elementName, elementName);
559
560         // time to fire off endElement event
561
if (m_tracer != null)
562             super.fireEndElem(elementName);
563     }
564
565     /**
566      * Receive notification of character data.
567      *
568      * <p>The Parser will call this method to report each chunk of
569      * character data. SAX parsers may return all contiguous character
570      * data in a single chunk, or they may split it into several
571      * chunks; however, all of the characters in any single event
572      * must come from the same external entity, so that the Locator
573      * provides useful information.</p>
574      *
575      * <p>The application must not attempt to read from the array
576      * outside of the specified range.</p>
577      *
578      * <p>Note that some parsers will report whitespace using the
579      * ignorableWhitespace() method rather than this one (validating
580      * parsers must do so).</p>
581      *
582      * @param ch The characters from the XML document.
583      * @param off The start position in the array.
584      * @param len The number of characters to read from the array.
585      * @throws org.xml.sax.SAXException Any SAX exception, possibly
586      * wrapping another exception.
587      * @see #ignorableWhitespace
588      * @see org.xml.sax.Locator
589      *
590      * @throws org.xml.sax.SAXException
591      *
592      * @see org.xml.sax.ContentHandler#characters(char[], int, int)
593      */

594     public void characters(char[] ch, int off, int len) throws SAXException JavaDoc
595     {
596
597         flushPending();
598         m_saxHandler.characters(ch, off, len);
599
600         // time to fire off characters event
601
if (m_tracer != null)
602             super.fireCharEvent(ch, off, len);
603     }
604
605     /**
606      * This method flushes any pending events, which can be startDocument()
607      * closing the opening tag of an element, or closing an open CDATA section.
608      */

609     public void flushPending() throws SAXException JavaDoc
610     {
611         if (m_needToCallStartDocument)
612         {
613             startDocumentInternal();
614             m_needToCallStartDocument = false;
615         }
616         // Close any open element
617
if (m_elemContext.m_startTagOpen)
618         {
619             closeStartTag();
620             m_elemContext.m_startTagOpen = false;
621         }
622     }
623     /**
624      * Handle a prefix/uri mapping, which is associated with a startElement()
625      * that is soon to follow. Need to close any open start tag to make
626      * sure than any name space attributes due to this event are associated wih
627      * the up comming element, not the current one.
628      * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#startPrefixMapping
629      *
630      * @param prefix The Namespace prefix being declared.
631      * @param uri The Namespace URI the prefix is mapped to.
632      * @param shouldFlush true if any open tags need to be closed first, this
633      * will impact which element the mapping applies to (open parent, or its up
634      * comming child)
635      * @return returns true if the call made a change to the current
636      * namespace information, false if it did not change anything, e.g. if the
637      * prefix/namespace mapping was already in scope from before.
638      *
639      * @throws org.xml.sax.SAXException The client may throw
640      * an exception during processing.
641      */

642     public boolean startPrefixMapping(
643         String JavaDoc prefix,
644         String JavaDoc uri,
645         boolean shouldFlush)
646         throws SAXException JavaDoc
647     {
648         // no namespace support for HTML
649
if (shouldFlush)
650             flushPending();
651         m_saxHandler.startPrefixMapping(prefix,uri);
652         return false;
653     }
654
655     /**
656      * Begin the scope of a prefix-URI Namespace mapping
657      * just before another element is about to start.
658      * This call will close any open tags so that the prefix mapping
659      * will not apply to the current element, but the up comming child.
660      *
661      * @see org.xml.sax.ContentHandler#startPrefixMapping
662      *
663      * @param prefix The Namespace prefix being declared.
664      * @param uri The Namespace URI the prefix is mapped to.
665      *
666      * @throws org.xml.sax.SAXException The client may throw
667      * an exception during processing.
668      *
669      */

670     public void startPrefixMapping(String JavaDoc prefix, String JavaDoc uri)
671         throws org.xml.sax.SAXException JavaDoc
672     {
673         startPrefixMapping(prefix,uri,true);
674     }
675
676     /**
677      * This method is used when a prefix/uri namespace mapping
678      * is indicated after the element was started with a
679      * startElement() and before and endElement().
680      * startPrefixMapping(prefix,uri) would be used before the
681      * startElement() call.
682      * @param prefix the prefix associated with the given URI.
683      * @param uri the URI of the namespace
684      *
685      * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#namespaceAfterStartElement(String, String)
686      */

687     public void namespaceAfterStartElement(
688         final String JavaDoc prefix,
689         final String JavaDoc uri)
690         throws SAXException JavaDoc
691     {
692         // hack for XSLTC with finding URI for default namespace
693
if (m_elemContext.m_elementURI == null)
694         {
695             String JavaDoc prefix1 = getPrefixPart(m_elemContext.m_elementName);
696             if (prefix1 == null && EMPTYSTRING.equals(prefix))
697             {
698                 // the elements URI is not known yet, and it
699
// doesn't have a prefix, and we are currently
700
// setting the uri for prefix "", so we have
701
// the uri for the element... lets remember it
702
m_elemContext.m_elementURI = uri;
703             }
704         }
705         startPrefixMapping(prefix,uri,false);
706     }
707     
708     /**
709      * Try's to reset the super class and reset this class for
710      * re-use, so that you don't need to create a new serializer
711      * (mostly for performance reasons).
712      *
713      * @return true if the class was successfuly reset.
714      * @see com.sun.org.apache.xml.internal.serializer.Serializer#reset()
715      */

716     public boolean reset()
717     {
718         boolean wasReset = false;
719         if (super.reset())
720         {
721             resetToHTMLSAXHandler();
722             wasReset = true;
723         }
724         return wasReset;
725     }
726     
727     /**
728      * Reset all of the fields owned by ToHTMLSAXHandler class
729      *
730      */

731     private void resetToHTMLSAXHandler()
732     {
733         this.m_escapeSetting = false;
734     }
735 }
736
Popular Tags