KickJava   Java API By Example, From Geeks To Geeks.

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


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

19 package com.sun.org.apache.xml.internal.serializer;
20
21 import java.io.IOException JavaDoc;
22 import java.io.OutputStream JavaDoc;
23 import java.io.Writer JavaDoc;
24 import java.util.Properties JavaDoc;
25 import java.util.Vector JavaDoc;
26
27 import javax.xml.transform.SourceLocator JavaDoc;
28 import javax.xml.transform.Transformer JavaDoc;
29
30 import org.w3c.dom.Node JavaDoc;
31 import org.xml.sax.Attributes JavaDoc;
32 import org.xml.sax.ContentHandler JavaDoc;
33 import org.xml.sax.Locator JavaDoc;
34 import org.xml.sax.SAXException JavaDoc;
35
36
37 /**
38  *This class wraps another SerializationHandler. The wrapped object will either
39  * handler XML or HTML, which is not known until a little later when the first XML
40  * tag is seen. If the first tag is <html> then the wrapped object is an HTML
41  * handler, otherwise it is an XML handler.
42  *
43  * This class effectively caches the first few calls to it then passes them
44  * on to the wrapped handler (once it exists). After that subsequent calls a
45  * simply passed directly to the wrapped handler.
46  *
47  * The user of this class doesn't know if the output is ultimatley XML or HTML.
48  */

49 public class ToUnknownStream extends SerializerBase
50 {
51
52     /**
53      * The wrapped handler, initially XML but possibly switched to HTML
54      */

55     private SerializationHandler m_handler;
56
57     /**
58      * A String with no characters
59      */

60     private static final String JavaDoc EMPTYSTRING = "";
61
62     /**
63      * true if the underlying handler (XML or HTML) is fully initialized
64      */

65     private boolean m_wrapped_handler_not_initialized = false;
66
67
68     /**
69      * the prefix of the very first tag in the document
70      */

71     private String JavaDoc m_firstElementPrefix;
72     /**
73      * the element name (including any prefix) of the very first tag in the document
74      */

75     private String JavaDoc m_firstElementName;
76
77     /**
78      * the namespace URI associated with the first element
79      */

80     private String JavaDoc m_firstElementURI;
81     
82     /**
83      * the local name (no prefix) associated with the first element
84      */

85     private String JavaDoc m_firstElementLocalName = null;
86
87     /**
88      * true if the first tag has been emitted to the wrapped handler
89      */

90     private boolean m_firstTagNotEmitted = true;
91
92     /**
93      * A collection of namespace URI's (only for first element).
94      * _namespacePrefix has the matching prefix for these URI's
95      */

96     private Vector JavaDoc m_namespaceURI = null;
97     /**
98      * A collection of namespace Prefix (only for first element)
99      * _namespaceURI has the matching URIs for these prefix'
100      */

101     private Vector JavaDoc m_namespacePrefix = null;
102
103     /**
104      * true if startDocument() was called before the underlying handler
105      * was initialized
106      */

107     private boolean m_needToCallStartDocument = false;
108     /**
109      * true if setVersion() was called before the underlying handler
110      * was initialized
111      */

112     private boolean m_setVersion_called = false;
113     /**
114      * true if setDoctypeSystem() was called before the underlying handler
115      * was initialized
116      */

117     private boolean m_setDoctypeSystem_called = false;
118     /**
119      * true if setDoctypePublic() was called before the underlying handler
120      * was initialized
121      */

122     private boolean m_setDoctypePublic_called = false;
123     /**
124      * true if setMediaType() was called before the underlying handler
125      * was initialized
126      */

127     private boolean m_setMediaType_called = false;
128
129     /**
130      * Default constructor.
131      * Initially this object wraps an XML Stream object, so _handler is never null.
132      * That may change later to an HTML Stream object.
133      */

134     public ToUnknownStream()
135     {
136         m_handler = new ToXMLStream();
137     }
138
139     /**
140      * @see com.sun.org.apache.xml.internal.serializer.Serializer#asContentHandler()
141      * @return the wrapped XML or HTML handler
142      */

143     public ContentHandler JavaDoc asContentHandler() throws IOException JavaDoc
144     {
145         /* don't return the real handler ( m_handler ) because
146          * that would expose the real handler to the outside.
147          * Keep m_handler private so it can be internally swapped
148          * to an HTML handler.
149          */

150         return this;
151     }
152
153     /**
154      * @see com.sun.org.apache.xml.internal.serializer.SerializationHandler#close()
155      */

156     public void close()
157     {
158         m_handler.close();
159     }
160
161     /**
162      * @see com.sun.org.apache.xml.internal.serializer.Serializer#getOutputFormat()
163      * @return the properties of the underlying handler
164      */

165     public Properties JavaDoc getOutputFormat()
166     {
167         return m_handler.getOutputFormat();
168     }
169
170     /**
171      * @see com.sun.org.apache.xml.internal.serializer.Serializer#getOutputStream()
172      * @return the OutputStream of the underlying XML or HTML handler
173      */

174     public OutputStream JavaDoc getOutputStream()
175     {
176         return m_handler.getOutputStream();
177     }
178
179     /**
180      * @see com.sun.org.apache.xml.internal.serializer.Serializer#getWriter()
181      * @return the Writer of the underlying XML or HTML handler
182      */

183     public Writer JavaDoc getWriter()
184     {
185         return m_handler.getWriter();
186     }
187
188     /**
189      * passes the call on to the underlying HTML or XML handler
190      * @see com.sun.org.apache.xml.internal.serializer.Serializer#reset()
191      * @return ???
192      */

193     public boolean reset()
194     {
195         return m_handler.reset();
196     }
197
198     /**
199      * Converts the DOM node to output
200      * @param node the DOM node to transform to output
201      * @see com.sun.org.apache.xml.internal.serializer.DOMSerializer#serialize(Node)
202      *
203      */

204     public void serialize(Node JavaDoc node) throws IOException JavaDoc
205     {
206         if (m_firstTagNotEmitted)
207         {
208             flush();
209         }
210         m_handler.serialize(node);
211     }
212
213     /**
214      * @see com.sun.org.apache.xml.internal.serializer.SerializationHandler#setEscaping(boolean)
215      */

216     public boolean setEscaping(boolean escape) throws SAXException JavaDoc
217     {
218         return m_handler.setEscaping(escape);
219     }
220
221     /**
222      * Set the properties of the handler
223      * @param format the output properties to set
224      * @see com.sun.org.apache.xml.internal.serializer.Serializer#setOutputFormat(Properties)
225      */

226     public void setOutputFormat(Properties JavaDoc format)
227     {
228         m_handler.setOutputFormat(format);
229     }
230
231     /**
232      * Sets the output stream to write to
233      * @param output the OutputStream to write to
234      * @see com.sun.org.apache.xml.internal.serializer.Serializer#setOutputStream(OutputStream)
235      */

236     public void setOutputStream(OutputStream JavaDoc output)
237     {
238         m_handler.setOutputStream(output);
239     }
240
241     /**
242      * Sets the writer to write to
243      * @param writer the writer to write to
244      * @see com.sun.org.apache.xml.internal.serializer.Serializer#setWriter(Writer)
245      */

246     public void setWriter(Writer JavaDoc writer)
247     {
248         m_handler.setWriter(writer);
249     }
250
251     /**
252      * Adds an attribute to the currenly open tag
253      * @param uri the URI of a namespace
254      * @param localName the attribute name, without prefix
255      * @param rawName the attribute name, with prefix (if any)
256      * @param type the type of the attribute, typically "CDATA"
257      * @param value the value of the parameter
258      * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#addAttribute(String, String, String, String, String)
259      */

260     public void addAttribute(
261         String JavaDoc uri,
262         String JavaDoc localName,
263         String JavaDoc rawName,
264         String JavaDoc type,
265         String JavaDoc value)
266         throws SAXException JavaDoc
267     {
268         if (m_firstTagNotEmitted)
269         {
270             flush();
271         }
272         m_handler.addAttribute(uri, localName, rawName, type, value);
273     }
274     /**
275      * Adds an attribute to the currenly open tag
276      * @param name the attribute name, with prefix (if any)
277      * @param value the value of the parameter
278      * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#addAttribute(String, String)
279      */

280     public void addAttribute(String JavaDoc rawName, String JavaDoc value)
281     {
282         if (m_firstTagNotEmitted)
283         {
284             flush();
285         }
286         m_handler.addAttribute(rawName, value);
287  
288     }
289
290     /**
291      * Adds a unique attribute to the currenly open tag
292      */

293     public void addUniqueAttribute(String JavaDoc rawName, String JavaDoc value, int flags)
294         throws SAXException JavaDoc
295     {
296         if (m_firstTagNotEmitted)
297         {
298             flush();
299         }
300         m_handler.addUniqueAttribute(rawName, value, flags);
301  
302     }
303
304     /**
305      * Converts the String to a character array and calls the SAX method
306      * characters(char[],int,int);
307      *
308      * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#characters(String)
309      */

310     public void characters(String JavaDoc chars) throws SAXException JavaDoc
311     {
312         final int length = chars.length();
313         if (length > m_charsBuff.length)
314         {
315             m_charsBuff = new char[length*2 + 1];
316         }
317         chars.getChars(0, length, m_charsBuff, 0);
318         this.characters(m_charsBuff, 0, length);
319     }
320
321     /**
322      * Pass the call on to the underlying handler
323      * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#endElement(String)
324      */

325     public void endElement(String JavaDoc elementName) throws SAXException JavaDoc
326     {
327         if (m_firstTagNotEmitted)
328         {
329             flush();
330         }
331         m_handler.endElement(elementName);
332     }
333
334
335     /**
336      * @see org.xml.sax.ContentHandler#startPrefixMapping(String, String)
337      * @param prefix The prefix that maps to the URI
338      * @param uri The URI for the namespace
339      */

340     public void startPrefixMapping(String JavaDoc prefix, String JavaDoc uri) throws SAXException JavaDoc
341     {
342         this.startPrefixMapping(prefix,uri, true);
343     }
344
345     /**
346      * This method is used when a prefix/uri namespace mapping
347      * is indicated after the element was started with a
348      * startElement() and before and endElement().
349      * startPrefixMapping(prefix,uri) would be used before the
350      * startElement() call.
351      * @param uri the URI of the namespace
352      * @param prefix the prefix associated with the given URI.
353      *
354      * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#namespaceAfterStartElement(String, String)
355      */

356     public void namespaceAfterStartElement(String JavaDoc prefix, String JavaDoc uri)
357         throws SAXException JavaDoc
358     {
359         // hack for XSLTC with finding URI for default namespace
360
if (m_firstTagNotEmitted && m_firstElementURI == null && m_firstElementName != null)
361         {
362             String JavaDoc prefix1 = getPrefixPart(m_firstElementName);
363             if (prefix1 == null && EMPTYSTRING.equals(prefix))
364             {
365                 // the elements URI is not known yet, and it
366
// doesn't have a prefix, and we are currently
367
// setting the uri for prefix "", so we have
368
// the uri for the element... lets remember it
369
m_firstElementURI = uri;
370             }
371         }
372         startPrefixMapping(prefix,uri, false);
373     }
374     
375     public boolean startPrefixMapping(String JavaDoc prefix, String JavaDoc uri, boolean shouldFlush)
376         throws SAXException JavaDoc
377     {
378         boolean pushed = false;
379         if (m_firstTagNotEmitted)
380         {
381             if (m_firstElementName != null && shouldFlush)
382             {
383                 /* we've already seen a startElement, and this is a prefix mapping
384                  * for the up coming element, so flush the old element
385                  * then send this event on its way.
386                  */

387                 flush();
388                 pushed = m_handler.startPrefixMapping(prefix, uri, shouldFlush);
389             }
390             else
391             {
392                 if (m_namespacePrefix == null)
393                 {
394                     m_namespacePrefix = new Vector JavaDoc();
395                     m_namespaceURI = new Vector JavaDoc();
396                 }
397                 m_namespacePrefix.addElement(prefix);
398                 m_namespaceURI.addElement(uri);
399             
400                 if (m_firstElementURI == null)
401                 {
402                     if (prefix.equals(m_firstElementPrefix))
403                         m_firstElementURI = uri;
404                 }
405             }
406
407         }
408         else
409         {
410            pushed = m_handler.startPrefixMapping(prefix, uri, shouldFlush);
411         }
412         return pushed;
413     }
414
415     /**
416       * This method cannot be cached because default is different in
417       * HTML and XML (we need more than a boolean).
418       */

419
420     public void setVersion(String JavaDoc version)
421     {
422         m_handler.setVersion(version);
423
424         // Cache call to setVersion()
425
// super.setVersion(version);
426
m_setVersion_called = true;
427     }
428
429     /**
430      * @see org.xml.sax.ContentHandler#startDocument()
431      */

432     public void startDocument() throws SAXException JavaDoc
433     {
434         m_needToCallStartDocument = true;
435     }
436
437  
438     
439     public void startElement(String JavaDoc qName) throws SAXException JavaDoc
440     {
441         this.startElement(null, null, qName, null);
442     }
443     
444     public void startElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName) throws SAXException JavaDoc
445     {
446         this.startElement(namespaceURI, localName, qName, null);
447     }
448
449     public void startElement(
450         String JavaDoc namespaceURI,
451         String JavaDoc localName,
452         String JavaDoc elementName,
453         Attributes JavaDoc atts) throws SAXException JavaDoc
454     {
455         /* we are notified of the start of an element */
456         if (m_firstTagNotEmitted)
457         {
458             /* we have not yet sent the first element on its way */
459             if (m_firstElementName != null)
460             {
461                 /* this is not the first element, but a later one.
462                  * But we have the old element pending, so flush it out,
463                  * then send this one on its way.
464                  */

465                 flush();
466                 m_handler.startElement(namespaceURI, localName, elementName, atts);
467             }
468             else
469             {
470                 /* this is the very first element that we have seen,
471                  * so save it for flushing later. We may yet get to know its
472                  * URI due to added attributes.
473                  */

474                  
475                 m_wrapped_handler_not_initialized = true;
476                 m_firstElementName = elementName;
477                 
478                 // null if not known
479
m_firstElementPrefix = getPrefixPartUnknown(elementName);
480                 
481                 // null if not known
482
m_firstElementURI = namespaceURI;
483                 
484                 // null if not known
485
m_firstElementLocalName = localName;
486
487                 if (m_tracer != null)
488                     firePseudoElement(elementName);
489                     
490                 /* we don't want to call our own addAttributes, which
491                  * merely delegates to the wrapped handler, but we want to
492                  * add these attributes to m_attributes. So me must call super.
493                  * addAttributes() In this case m_attributes is only used for the
494                  * first element, after that this class totally delegates to the
495                  * wrapped handler which is either XML or HTML.
496                  */

497                 if (atts != null)
498                     super.addAttributes(atts);
499                 
500                 // if there are attributes, then lets make the flush()
501
// call the startElement on the handler and send the
502
// attributes on their way.
503
if (atts != null)
504                     flush();
505                 
506             }
507         }
508         else
509         {
510             // this is not the first element, but a later one, so just
511
// send it on its way.
512
m_handler.startElement(namespaceURI, localName, elementName, atts);
513         }
514     }
515
516     /**
517      * Pass the call on to the underlying handler
518      * @see com.sun.org.apache.xml.internal.serializer.ExtendedLexicalHandler#comment(String)
519      */

520     public void comment(String JavaDoc comment) throws SAXException JavaDoc
521     {
522         if (m_firstTagNotEmitted && m_firstElementName != null)
523         {
524             emitFirstTag();
525         }
526         else if (m_needToCallStartDocument)
527         {
528             m_handler.startDocument();
529             m_needToCallStartDocument = false;
530         }
531
532         m_handler.comment(comment);
533     }
534
535     /**
536      * Pass the call on to the underlying handler
537      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#getDoctypePublic()
538      */

539     public String JavaDoc getDoctypePublic()
540     {
541
542         return m_handler.getDoctypePublic();
543     }
544
545     /**
546      * Pass the call on to the underlying handler
547      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#getDoctypeSystem()
548      */

549     public String JavaDoc getDoctypeSystem()
550     {
551         return m_handler.getDoctypeSystem();
552     }
553
554     /**
555      * Pass the call on to the underlying handler
556      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#getEncoding()
557      */

558     public String JavaDoc getEncoding()
559     {
560         return m_handler.getEncoding();
561     }
562
563     /**
564      * Pass the call on to the underlying handler
565      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#getIndent()
566      */

567     public boolean getIndent()
568     {
569         return m_handler.getIndent();
570     }
571
572     /**
573      * Pass the call on to the underlying handler
574      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#getIndentAmount()
575      */

576     public int getIndentAmount()
577     {
578         return m_handler.getIndentAmount();
579     }
580
581     /**
582      * Pass the call on to the underlying handler
583      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#getMediaType()
584      */

585     public String JavaDoc getMediaType()
586     {
587         return m_handler.getMediaType();
588     }
589
590     /**
591      * Pass the call on to the underlying handler
592      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#getOmitXMLDeclaration()
593      */

594     public boolean getOmitXMLDeclaration()
595     {
596         return m_handler.getOmitXMLDeclaration();
597     }
598
599     /**
600      * Pass the call on to the underlying handler
601      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#getStandalone()
602      */

603     public String JavaDoc getStandalone()
604     {
605         return m_handler.getStandalone();
606     }
607
608     /**
609      * Pass the call on to the underlying handler
610      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#getVersion()
611      */

612     public String JavaDoc getVersion()
613     {
614         return m_handler.getVersion();
615     }
616
617     /**
618      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#setDoctype(String, String)
619      */

620     public void setDoctype(String JavaDoc system, String JavaDoc pub)
621     {
622         m_handler.setDoctypePublic(pub);
623         m_handler.setDoctypeSystem(system);
624     }
625
626     /**
627      * Set the doctype in the underlying XML handler. Remember that this method
628      * was called, just in case we need to transfer this doctype to an HTML handler
629      * @param doctype the public doctype to set
630      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#setDoctypePublic(String)
631      */

632     public void setDoctypePublic(String JavaDoc doctype)
633     {
634         m_handler.setDoctypePublic(doctype);
635         m_setDoctypePublic_called = true;
636     }
637
638     /**
639      * Set the doctype in the underlying XML handler. Remember that this method
640      * was called, just in case we need to transfer this doctype to an HTML handler
641      * @param doctype the system doctype to set
642      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#setDoctypeSystem(String)
643      */

644     public void setDoctypeSystem(String JavaDoc doctype)
645     {
646         m_handler.setDoctypeSystem(doctype);
647         m_setDoctypeSystem_called = true;
648     }
649
650     /**
651      * Pass the call on to the underlying handler
652      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#setEncoding(String)
653      */

654     public void setEncoding(String JavaDoc encoding)
655     {
656         m_handler.setEncoding(encoding);
657     }
658
659     /**
660      * Pass the call on to the underlying handler
661      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#setIndent(boolean)
662      */

663     public void setIndent(boolean indent)
664     {
665         m_handler.setIndent(indent);
666     }
667
668     /**
669      * Pass the call on to the underlying handler
670      */

671     public void setIndentAmount(int value)
672     {
673         m_handler.setIndentAmount(value);
674     }
675
676     /**
677      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#setMediaType(String)
678      */

679     public void setMediaType(String JavaDoc mediaType)
680     {
681         m_handler.setMediaType(mediaType);
682         m_setMediaType_called = true;
683     }
684
685     /**
686      * Pass the call on to the underlying handler
687      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#setOmitXMLDeclaration(boolean)
688      */

689     public void setOmitXMLDeclaration(boolean b)
690     {
691         m_handler.setOmitXMLDeclaration(b);
692     }
693
694     /**
695      * Pass the call on to the underlying handler
696      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#setStandalone(String)
697      */

698     public void setStandalone(String JavaDoc standalone)
699     {
700         m_handler.setStandalone(standalone);
701     }
702
703     /**
704      * @see com.sun.org.apache.xml.internal.serializer.XSLOutputAttributes#setVersion(String)
705      */

706
707     /**
708      * Pass the call on to the underlying handler
709      * @see org.xml.sax.ext.DeclHandler#attributeDecl(String, String, String, String, String)
710      */

711     public void attributeDecl(
712         String JavaDoc arg0,
713         String JavaDoc arg1,
714         String JavaDoc arg2,
715         String JavaDoc arg3,
716         String JavaDoc arg4)
717         throws SAXException JavaDoc
718     {
719         m_handler.attributeDecl(arg0, arg1, arg2, arg3, arg4);
720     }
721
722     /**
723      * Pass the call on to the underlying handler
724      * @see org.xml.sax.ext.DeclHandler#elementDecl(String, String)
725      */

726     public void elementDecl(String JavaDoc arg0, String JavaDoc arg1) throws SAXException JavaDoc
727     {
728         if (m_firstTagNotEmitted)
729         {
730             emitFirstTag();
731         }
732         m_handler.elementDecl(arg0, arg1);
733     }
734
735     /**
736      * Pass the call on to the underlying handler
737      * @see org.xml.sax.ext.DeclHandler#externalEntityDecl(String, String, String)
738      */

739     public void externalEntityDecl(
740         String JavaDoc name,
741         String JavaDoc publicId,
742         String JavaDoc systemId)
743         throws SAXException JavaDoc
744     {
745         if (m_firstTagNotEmitted)
746         {
747             flush();
748         }
749         m_handler.externalEntityDecl(name, publicId, systemId);
750     }
751
752     /**
753      * Pass the call on to the underlying handler
754      * @see org.xml.sax.ext.DeclHandler#internalEntityDecl(String, String)
755      */

756     public void internalEntityDecl(String JavaDoc arg0, String JavaDoc arg1)
757         throws SAXException JavaDoc
758     {
759         if (m_firstTagNotEmitted)
760         {
761             flush();
762         }
763         m_handler.internalEntityDecl(arg0, arg1);
764     }
765
766     /**
767      * Pass the call on to the underlying handler
768      * @see org.xml.sax.ContentHandler#characters(char[], int, int)
769      */

770     public void characters(char[] characters, int offset, int length)
771         throws SAXException JavaDoc
772     {
773         if (m_firstTagNotEmitted)
774         {
775             flush();
776         }
777
778         m_handler.characters(characters, offset, length);
779
780     }
781
782     /**
783      * Pass the call on to the underlying handler
784      * @see org.xml.sax.ContentHandler#endDocument()
785      */

786     public void endDocument() throws SAXException JavaDoc
787     {
788         if (m_firstTagNotEmitted)
789         {
790             flush();
791         }
792
793         m_handler.endDocument();
794         
795     
796     }
797
798     /**
799      * Pass the call on to the underlying handler
800      * @see org.xml.sax.ContentHandler#endElement(String, String, String)
801      */

802     public void endElement(String JavaDoc namespaceURI, String JavaDoc localName, String JavaDoc qName)
803         throws SAXException JavaDoc
804     {
805         if (m_firstTagNotEmitted)
806         {
807             flush();
808             if (namespaceURI == null && m_firstElementURI != null)
809                 namespaceURI = m_firstElementURI;
810
811
812             if (localName == null && m_firstElementLocalName != null)
813                 localName = m_firstElementLocalName;
814         }
815         
816         m_handler.endElement(namespaceURI, localName, qName);
817     }
818
819     /**
820      * Pass the call on to the underlying handler
821      * @see org.xml.sax.ContentHandler#endPrefixMapping(String)
822      */

823     public void endPrefixMapping(String JavaDoc prefix) throws SAXException JavaDoc
824     {
825         m_handler.endPrefixMapping(prefix);
826     }
827
828     /**
829      * Pass the call on to the underlying handler
830      * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
831      */

832     public void ignorableWhitespace(char[] ch, int start, int length)
833         throws SAXException JavaDoc
834     {
835         if (m_firstTagNotEmitted)
836         {
837             flush();
838         }
839         m_handler.ignorableWhitespace(ch, start, length);
840     }
841
842     /**
843      * Pass the call on to the underlying handler
844      * @see org.xml.sax.ContentHandler#processingInstruction(String, String)
845      */

846     public void processingInstruction(String JavaDoc target, String JavaDoc data)
847         throws SAXException JavaDoc
848     {
849         if (m_firstTagNotEmitted)
850         {
851             flush();
852         }
853
854         m_handler.processingInstruction(target, data);
855     }
856
857     /**
858      * Pass the call on to the underlying handler
859      * @see org.xml.sax.ContentHandler#setDocumentLocator(Locator)
860      */

861     public void setDocumentLocator(Locator JavaDoc locator)
862     {
863         m_handler.setDocumentLocator(locator);
864     }
865
866     /**
867      * Pass the call on to the underlying handler
868      * @see org.xml.sax.ContentHandler#skippedEntity(String)
869      */

870     public void skippedEntity(String JavaDoc name) throws SAXException JavaDoc
871     {
872         m_handler.skippedEntity(name);
873     }
874
875
876
877     /**
878      * Pass the call on to the underlying handler
879      * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int)
880      */

881     public void comment(char[] ch, int start, int length) throws SAXException JavaDoc
882     {
883         if (m_firstTagNotEmitted)
884         {
885             flush();
886         }
887
888         m_handler.comment(ch, start, length);
889     }
890
891     /**
892      * Pass the call on to the underlying handler
893      * @see org.xml.sax.ext.LexicalHandler#endCDATA()
894      */

895     public void endCDATA() throws SAXException JavaDoc
896     {
897
898         m_handler.endCDATA();
899     }
900
901     /**
902      * Pass the call on to the underlying handler
903      * @see org.xml.sax.ext.LexicalHandler#endDTD()
904      */

905     public void endDTD() throws SAXException JavaDoc
906     {
907
908         m_handler.endDTD();
909     }
910
911     /**
912      * Pass the call on to the underlying handler
913      * @see org.xml.sax.ext.LexicalHandler#endEntity(String)
914      */

915     public void endEntity(String JavaDoc name) throws SAXException JavaDoc
916     {
917         if (m_firstTagNotEmitted)
918         {
919             emitFirstTag();
920         }
921         m_handler.endEntity(name);
922     }
923
924     /**
925      * Pass the call on to the underlying handler
926      * @see org.xml.sax.ext.LexicalHandler#startCDATA()
927      */

928     public void startCDATA() throws SAXException JavaDoc
929     {
930         m_handler.startCDATA();
931     }
932
933     /**
934      * Pass the call on to the underlying handler
935      * @see org.xml.sax.ext.LexicalHandler#startDTD(String, String, String)
936      */

937     public void startDTD(String JavaDoc name, String JavaDoc publicId, String JavaDoc systemId)
938         throws SAXException JavaDoc
939     {
940         m_handler.startDTD(name, publicId, systemId);
941     }
942
943     /**
944      * Pass the call on to the underlying handler
945      * @see org.xml.sax.ext.LexicalHandler#startEntity(String)
946      */

947     public void startEntity(String JavaDoc name) throws SAXException JavaDoc
948     {
949         m_handler.startEntity(name);
950     }
951
952     /**
953      * Initialize the wrapped output stream (XML or HTML).
954      * If the stream handler should be HTML, then replace the XML handler with
955      * an HTML handler. After than send the starting method calls that were cached
956      * to the wrapped handler.
957      *
958      */

959     private void initStreamOutput() throws SAXException JavaDoc
960     {
961
962         // Try to rule out if this is an not to be an HTML document based on prefix
963
boolean firstElementIsHTML = isFirstElemHTML();
964
965         if (firstElementIsHTML)
966         {
967             // create an HTML output handler, and initialize it
968

969             // keep a reference to the old handler, ... it will soon be gone
970
SerializationHandler oldHandler = m_handler;
971
972             /* We have to make sure we get an output properties with the proper
973              * defaults for the HTML method. The easiest way to do this is to
974              * have the OutputProperties class do it.
975              */

976
977             Properties JavaDoc htmlProperties =
978                 OutputPropertiesFactory.getDefaultMethodProperties(Method.HTML);
979             Serializer serializer =
980                 SerializerFactory.getSerializer(htmlProperties);
981
982             // The factory should be returning a ToStream
983
// Don't know what to do if it doesn't
984
// i.e. the user has over-ridden the content-handler property
985
// for html
986
m_handler = (SerializationHandler) serializer;
987             //m_handler = new ToHTMLStream();
988

989             Writer JavaDoc writer = oldHandler.getWriter();
990
991             if (null != writer)
992                 m_handler.setWriter(writer);
993             else
994             {
995                 OutputStream JavaDoc os = oldHandler.getOutputStream();
996
997                 if (null != os)
998                     m_handler.setOutputStream(os);
999             }
1000
1001            // need to copy things from the old handler to the new one here
1002

1003            // if (_setVersion_called)
1004
// {
1005
m_handler.setVersion(oldHandler.getVersion());
1006            // }
1007
// if (_setDoctypeSystem_called)
1008
// {
1009
m_handler.setDoctypeSystem(oldHandler.getDoctypeSystem());
1010            // }
1011
// if (_setDoctypePublic_called)
1012
// {
1013
m_handler.setDoctypePublic(oldHandler.getDoctypePublic());
1014            // }
1015
// if (_setMediaType_called)
1016
// {
1017
m_handler.setMediaType(oldHandler.getMediaType());
1018            // }
1019

1020            m_handler.setTransformer(oldHandler.getTransformer());
1021        }
1022
1023        /* Now that we have a real wrapped handler (XML or HTML) lets
1024         * pass any cached calls to it
1025         */

1026        // Call startDocument() if necessary
1027
if (m_needToCallStartDocument)
1028        {
1029            m_handler.startDocument();
1030            m_needToCallStartDocument = false;
1031        }
1032
1033        // the wrapped handler is now fully initialized
1034
m_wrapped_handler_not_initialized = false;
1035    }
1036
1037    private void emitFirstTag() throws SAXException JavaDoc
1038    {
1039        if (m_firstElementName != null)
1040        {
1041            if (m_wrapped_handler_not_initialized)
1042            {
1043                initStreamOutput();
1044                m_wrapped_handler_not_initialized = false;
1045            }
1046            // Output first tag
1047
m_handler.startElement(m_firstElementURI, null, m_firstElementName, m_attributes);
1048            // don't need the collected attributes of the first element anymore.
1049
m_attributes = null;
1050
1051            // Output namespaces of first tag
1052
if (m_namespacePrefix != null)
1053            {
1054                final int n = m_namespacePrefix.size();
1055                for (int i = 0; i < n; i++)
1056                {
1057                    final String JavaDoc prefix =
1058                        (String JavaDoc) m_namespacePrefix.elementAt(i);
1059                    final String JavaDoc uri = (String JavaDoc) m_namespaceURI.elementAt(i);
1060                    m_handler.startPrefixMapping(prefix, uri, false);
1061                }
1062                m_namespacePrefix = null;
1063                m_namespaceURI = null;
1064            }
1065            m_firstTagNotEmitted = false;
1066        }
1067    }
1068
1069    /**
1070     * Utility function for calls to local-name().
1071     *
1072     * Don't want to override static function on SerializerBase
1073     * So added Unknown suffix to method name.
1074     */

1075    private String JavaDoc getLocalNameUnknown(String JavaDoc value)
1076    {
1077        int idx = value.lastIndexOf(':');
1078        if (idx >= 0)
1079            value = value.substring(idx + 1);
1080        idx = value.lastIndexOf('@');
1081        if (idx >= 0)
1082            value = value.substring(idx + 1);
1083        return (value);
1084    }
1085
1086    /**
1087         * Utility function to return prefix
1088         *
1089         * Don't want to override static function on SerializerBase
1090         * So added Unknown suffix to method name.
1091         */

1092    private String JavaDoc getPrefixPartUnknown(String JavaDoc qname)
1093    {
1094        final int index = qname.indexOf(':');
1095        return (index > 0) ? qname.substring(0, index) : EMPTYSTRING;
1096    }
1097
1098    /**
1099     * Determine if the firts element in the document is <html> or <HTML>
1100     * This uses the cached first element name, first element prefix and the
1101     * cached namespaces from previous method calls
1102     *
1103     * @return true if the first element is an opening <html> tag
1104     */

1105    private boolean isFirstElemHTML()
1106    {
1107        boolean isHTML;
1108
1109        // is the first tag html, not considering the prefix ?
1110
isHTML =
1111            getLocalNameUnknown(m_firstElementName).equalsIgnoreCase("html");
1112
1113        // Try to rule out if this is not to be an HTML document based on URI
1114
if (isHTML
1115            && m_firstElementURI != null
1116            && !EMPTYSTRING.equals(m_firstElementURI))
1117        {
1118            // the <html> element has a non-trivial namespace
1119
isHTML = false;
1120        }
1121        // Try to rule out if this is an not to be an HTML document based on prefix
1122
if (isHTML && m_namespacePrefix != null)
1123        {
1124            /* the first element has a name of "html", but lets check the prefix.
1125             * If the prefix points to a namespace with a URL that is not ""
1126             * then the doecument doesn't start with an <html> tag, and isn't html
1127             */

1128            final int max = m_namespacePrefix.size();
1129            for (int i = 0; i < max; i++)
1130            {
1131                final String JavaDoc prefix = (String JavaDoc) m_namespacePrefix.elementAt(i);
1132                final String JavaDoc uri = (String JavaDoc) m_namespaceURI.elementAt(i);
1133
1134                if (m_firstElementPrefix != null
1135                    && m_firstElementPrefix.equals(prefix)
1136                    && !EMPTYSTRING.equals(uri))
1137                {
1138                    // The first element has a prefix, so it can't be <html>
1139
isHTML = false;
1140                    break;
1141                }
1142            }
1143
1144        }
1145        return isHTML;
1146    }
1147    /**
1148     * @see com.sun.org.apache.xml.internal.serializer.Serializer#asDOMSerializer()
1149     */

1150    public DOMSerializer asDOMSerializer() throws IOException JavaDoc
1151    {
1152        return m_handler.asDOMSerializer();
1153    }
1154
1155    /**
1156     * @param URI_and_localNames Vector a list of pairs of URI/localName
1157     * specified in the cdata-section-elements attribute
1158     * @see com.sun.org.apache.xml.internal.serializer.SerializationHandler#setCdataSectionElements(java.util.Vector)
1159     */

1160    public void setCdataSectionElements(Vector JavaDoc URI_and_localNames)
1161    {
1162        m_handler.setCdataSectionElements(URI_and_localNames);
1163    }
1164    /**
1165     * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#addAttributes(org.xml.sax.Attributes)
1166     */

1167    public void addAttributes(Attributes JavaDoc atts) throws SAXException JavaDoc
1168    {
1169        m_handler.addAttributes(atts);
1170    }
1171
1172    /**
1173     * Get the current namespace mappings.
1174     * Simply returns the mappings of the wrapped handler.
1175     * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#getNamespaceMappings()
1176     */

1177    public NamespaceMappings getNamespaceMappings()
1178    {
1179        NamespaceMappings mappings = null;
1180        if (m_handler != null)
1181        {
1182            mappings = m_handler.getNamespaceMappings();
1183        }
1184        return mappings;
1185    }
1186    /**
1187     * @see com.sun.org.apache.xml.internal.serializer.SerializationHandler#flushPending()
1188     */

1189    public void flushPending() throws SAXException JavaDoc
1190    {
1191 
1192        flush();
1193      
1194        m_handler.flushPending();
1195    }
1196    
1197    private void flush()
1198    {
1199        try
1200        {
1201        if (m_firstTagNotEmitted)
1202        {
1203            emitFirstTag();
1204        }
1205        if (m_needToCallStartDocument)
1206        {
1207            m_handler.startDocument();
1208            m_needToCallStartDocument = false;
1209        }
1210        }
1211        catch(SAXException JavaDoc e)
1212        {
1213            throw new RuntimeException JavaDoc(e.toString());
1214        }
1215          
1216    
1217    }
1218
1219    /**
1220     * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#getPrefix
1221     */

1222    public String JavaDoc getPrefix(String JavaDoc namespaceURI)
1223    {
1224        return m_handler.getPrefix(namespaceURI);
1225    }
1226    /**
1227     * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#entityReference(java.lang.String)
1228     */

1229    public void entityReference(String JavaDoc entityName) throws SAXException JavaDoc
1230    {
1231        m_handler.entityReference(entityName);
1232    }
1233
1234    /**
1235     * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#getNamespaceURI(java.lang.String, boolean)
1236     */

1237    public String JavaDoc getNamespaceURI(String JavaDoc qname, boolean isElement)
1238    {
1239        return m_handler.getNamespaceURI(qname, isElement);
1240    }
1241
1242    public String JavaDoc getNamespaceURIFromPrefix(String JavaDoc prefix)
1243    {
1244        return m_handler.getNamespaceURIFromPrefix(prefix);
1245    }
1246
1247    public void setTransformer(Transformer JavaDoc t)
1248    {
1249        m_handler.setTransformer(t);
1250        if ((t instanceof SerializerTrace) &&
1251            (((SerializerTrace) t).hasTraceListeners())) {
1252           m_tracer = (SerializerTrace) t;
1253        } else {
1254           m_tracer = null;
1255        }
1256    }
1257    public Transformer JavaDoc getTransformer()
1258    {
1259        return m_handler.getTransformer();
1260    }
1261
1262    /**
1263     * @see com.sun.org.apache.xml.internal.serializer.SerializationHandler#setContentHandler(org.xml.sax.ContentHandler)
1264     */

1265    public void setContentHandler(ContentHandler JavaDoc ch)
1266    {
1267        m_handler.setContentHandler(ch);
1268    }
1269    /**
1270     * This method is used to set the source locator, which might be used to
1271     * generated an error message.
1272     * @param locator the source locator
1273     *
1274     * @see com.sun.org.apache.xml.internal.serializer.ExtendedContentHandler#setSourceLocator(javax.xml.transform.SourceLocator)
1275     */

1276    public void setSourceLocator(SourceLocator JavaDoc locator)
1277    {
1278        m_handler.setSourceLocator(locator);
1279    }
1280
1281    protected void firePseudoElement(String JavaDoc elementName)
1282    {
1283        
1284        if (m_tracer != null) {
1285            StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1286                
1287            sb.append('<');
1288            sb.append(elementName);
1289            
1290            // convert the StringBuffer to a char array and
1291
// emit the trace event that these characters "might"
1292
// be written
1293
char ch[] = sb.toString().toCharArray();
1294            m_tracer.fireGenerateEvent(
1295                SerializerTrace.EVENTTYPE_OUTPUT_PSEUDO_CHARACTERS,
1296                ch,
1297                0,
1298                ch.length);
1299        }
1300    }
1301}
1302
Popular Tags