1 /*
2 * reserved comment block
3 * DO NOT REMOVE OR ALTER!
4 */
5 /*
6 * Copyright 2001-2004 The Apache Software Foundation.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20 /*
21 * $Id: SerializerBase.java,v 1.5 2006/04/14 12:09:19 sunithareddy Exp $
22 */
23 package com.sun.org.apache.xml.internal.serializer;
24
25 import java.io.IOException;
26 import java.util.Vector;
27
28 import javax.xml.transform.SourceLocator;
29 import javax.xml.transform.Transformer;
30
31 import com.sun.org.apache.xml.internal.serializer.utils.MsgKey;
32 import com.sun.org.apache.xml.internal.serializer.utils.Utils;
33 import org.xml.sax.Attributes;
34 import org.xml.sax.ContentHandler;
35 import org.xml.sax.Locator;
36 import org.xml.sax.SAXException;
37 import org.xml.sax.SAXParseException;
38 import org.xml.sax.ext.Locator2;
39
40
41 /**
42 * This class acts as a base class for the XML "serializers"
43 * and the stream serializers.
44 * It contains a number of common fields and methods.
45 *
46 * @xsl.usage internal
47 */
91 protected boolean m_cdataTagOpen = false;
92
93 /**
94 * All the attributes of the current element, collected from
95 * startPrefixMapping() calls, or addAddtribute() calls, or
96 * from the SAX attributes in a startElement() call.
97 */
98 protected AttributesImplSerializer m_attributes = new AttributesImplSerializer();
99
100 /**
101 * Tells if we're in an EntityRef event.
102 */
103 protected boolean m_inEntityRef = false;
104
105 /** This flag is set while receiving events from the external DTD */
106 protected boolean m_inExternalDTD = false;
107
108 /**
109 * The System ID for the doc type.
110 */
111 private String m_doctypeSystem;
112
113 /**
114 * The public ID for the doc type.
115 */
116 private String m_doctypePublic;
117
118 /**
119 * Flag to tell that we need to add the doctype decl, which we can't do
120 * until the first element is encountered.
121 */
122 boolean m_needToOutputDocTypeDecl = true;
123
124 /**
125 * The character encoding. Must match the encoding used for the
126 * printWriter.
127 */
128 private String m_encoding = null;
129
130 /**
131 * Tells if we should write the XML declaration.
132 */
133 private boolean m_shouldNotWriteXMLHeader = false;
134
135 /**
136 * The standalone value for the doctype.
137 */
138 private String m_standalone;
139
140 /**
141 * True if standalone was specified.
142 */
143 protected boolean m_standaloneWasSpecified = false;
144
145 /**
146 * Determine if the output is a standalone.
147 */
148 protected boolean m_isStandalone = false;
149
150 /**
151 * Flag to tell if indenting (pretty-printing) is on.
152 */
153 protected boolean m_doIndent = false;
154 /**
155 * Amount to indent.
156 */
157 protected int m_indentAmount = 0;
158
159 /**
160 * Tells the XML version, for writing out to the XML decl.
161 */
162 private String m_version = null;
163
164 /**
165 * The mediatype. Not used right now.
166 */
167 private String m_mediatype;
168
169 /**
170 * The transformer that was around when this output handler was created (if
171 * any).
172 */
173 private Transformer m_transformer;
174
175 /**
176 * Pairs of local names and corresponding URIs of CDATA sections. This list
177 * comes from the cdata-section-elements attribute. Every second one is a
178 * local name, and every other second one is the URI for the local name.
179 */
180 protected Vector m_cdataSectionElements = null;
181
182 /**
183 * Namespace support, that keeps track of currently defined
184 * prefix/uri mappings. As processed elements come and go, so do
185 * the associated mappings for that element.
186 */
187 protected NamespaceMappings m_prefixMap;
188
189 /**
190 * Handle for firing generate events. This interface may be implemented
191 * by the referenced transformer object.
192 */
193 protected SerializerTrace m_tracer;
194
195 protected SourceLocator m_sourceLocator;
196
197
198 /**
199 * The writer to send output to. This field is only used in the ToStream
200 * serializers, but exists here just so that the fireStartDoc() and
201 * other fire... methods can flush this writer when tracing.
202 */
521 {
522 // do nothing (base behavior)
523 }
524
525 /**
526 * Initialize global variables
527 */
528 protected void initCDATA()
529 {
530 // CDATA stack
531 // _cdataStack = new Stack();
532 // _cdataStack.push(new Integer(-1)); // push dummy value
533 }
534
535 /**
536 * Returns the character encoding to be used in the output document.
537 * @return the character encoding to be used in the output document.
538 */
539 public String getEncoding()
540 {
541 return m_encoding;
542 }
543
544 /**
545 * Sets the character encoding coming from the xsl:output encoding stylesheet attribute.
546 * @param m_encoding the character encoding
547 */
548 public void setEncoding(String m_encoding)
549 {
550 this.m_encoding = m_encoding;
551 }
552
553 /**
554 * Sets the value coming from the xsl:output omit-xml-declaration stylesheet attribute
555 * @param b true if the XML declaration is to be omitted from the output
556 * document.
557 */
558 public void setOmitXMLDeclaration(boolean b)
559 {
560 this.m_shouldNotWriteXMLHeader = b;
561 }
562
563
564 /**
565 * @return true if the XML declaration is to be omitted from the output
566 * document.
567 */
568 public boolean getOmitXMLDeclaration()
569 {
570 return m_shouldNotWriteXMLHeader;
571 }
572
573 /**
574 * Returns the previously set value of the value to be used as the public
575 * identifier in the document type declaration (DTD).
576 *
577 *@return the public identifier to be used in the DOCTYPE declaration in the
578 * output document.
579 */
580 public String getDoctypePublic()
581 {
582 return m_doctypePublic;
583 }
584
585 /** Set the value coming from the xsl:output doctype-public stylesheet attribute.
586 * @param doctypePublic the public identifier to be used in the DOCTYPE
587 * declaration in the output document.
588 */
589 public void setDoctypePublic(String doctypePublic)
590 {
591 this.m_doctypePublic = doctypePublic;
592 }
593
594
595 /**
596 * Returns the previously set value of the value to be used
597 * as the system identifier in the document type declaration (DTD).
598 * @return the system identifier to be used in the DOCTYPE declaration in
599 * the output document.
600 *
601 */
602 public String getDoctypeSystem()
603 {
604 return m_doctypeSystem;
605 }
606
607 /** Set the value coming from the xsl:output doctype-system stylesheet attribute.
608 * @param doctypeSystem the system identifier to be used in the DOCTYPE
609 * declaration in the output document.
610 */
611 public void setDoctypeSystem(String doctypeSystem)
612 {
613 this.m_doctypeSystem = doctypeSystem;
614 }
615
616 /** Set the value coming from the xsl:output doctype-public and doctype-system stylesheet properties
617 * @param doctypeSystem the system identifier to be used in the DOCTYPE
618 * declaration in the output document.
619 * @param doctypePublic the public identifier to be used in the DOCTYPE
620 * declaration in the output document.
621 */
622 public void setDoctype(String doctypeSystem, String doctypePublic)
623 {
624 this.m_doctypeSystem = doctypeSystem;
625 this.m_doctypePublic = doctypePublic;
626 }
627
628 /**
629 * Sets the value coming from the xsl:output standalone stylesheet attribute.
630 * @param standalone a value of "yes" indicates that the
631 * <code>standalone</code> delaration is to be included in the output
632 * document. This method remembers if the value was explicitly set using
633 * this method, verses if the value is the default value.
634 */
635 public void setStandalone(String standalone)
636 {
637 if (standalone != null)
638 {
639 m_standaloneWasSpecified = true;
640 setStandaloneInternal(standalone);
641 }
642 }
643 /**
644 * Sets the XSL standalone attribute, but does not remember if this is a
645 * default or explicite setting.
646 * @param standalone "yes" | "no"
647 */
648 protected void setStandaloneInternal(String standalone)
649 {
650 if ("yes".equals(standalone))
651 m_standalone = "yes";
652 else
653 m_standalone = "no";
654
655 }
656
657 /**
658 * Gets the XSL standalone attribute
659 * @return a value of "yes" if the <code>standalone</code> delaration is to
660 * be included in the output document.
661 * @see XSLOutputAttributes#getStandalone()
662 */
683 {
684 return m_mediatype;
685 }
686
687 /**
688 * Gets the version of the output format.
689 * @return the version of the output format.
690 */
691 public String getVersion()
692 {
693 return m_version;
694 }
695
696 /**
697 * Sets the value coming from the xsl:output version attribute.
698 * @param version the version of the output format.
699 * @see SerializationHandler#setVersion(String)
700 */
701 public void setVersion(String version)
702 {
703 m_version = version;
704 }
705
706 /**
707 * Sets the value coming from the xsl:output media-type stylesheet attribute.
708 * @param mediaType the non-null media-type or MIME type associated with the
709 * output document.
710 * @see javax.xml.transform.OutputKeys#MEDIA_TYPE
711 * @see SerializationHandler#setMediaType(String)
712 */
713 public void setMediaType(String mediaType)
714 {
715 m_mediatype = mediaType;
716 }
717
718 /**
719 * @return the number of spaces to indent for each indentation level.
720 */
721 public int getIndentAmount()
722 {
723 return m_indentAmount;
724 }
725
726 /**
727 * Sets the indentation amount.
728 * @param m_indentAmount The m_indentAmount to set
729 */
730 public void setIndentAmount(int m_indentAmount)
731 {
732 this.m_indentAmount = m_indentAmount;
733 }
734
735 /**
736 * Sets the value coming from the xsl:output indent stylesheet
737 * attribute.
738 * @param doIndent true if the output document should be indented to
739 * visually indicate its structure.
740 * @see XSLOutputAttributes#setIndent(boolean)
741 */
742 public void setIndent(boolean doIndent)
743 {
744 m_doIndent = doIndent;
745 }
746
747 /**
748 * Sets the isStandalone property
749 * @param isStandalone true if the ORACLE_IS_STANDALONE is set to yes
750 * @see OutputPropertiesFactory ORACLE_IS_STANDALONE
751 */
752 public void setIsStandalone(boolean isStandalone)
753 {
754 m_isStandalone = isStandalone;
755 }
756
757 /**
758 * This method is used when a prefix/uri namespace mapping
759 * is indicated after the element was started with a
760 * startElement() and before and endElement().
761 * startPrefixMapping(prefix,uri) would be used before the
762 * startElement() call.
763 * @param uri the URI of the namespace
764 * @param prefix the prefix associated with the given URI.
770 {
771 // default behavior is to do nothing
772 }
773
774 /**
775 * Return a {@link DOMSerializer} interface into this serializer. If the
776 * serializer does not support the {@link DOMSerializer} interface, it should
777 * return null.
778 *
779 * @return A {@link DOMSerializer} interface into this serializer, or null
780 * if the serializer is not DOM capable
781 * @throws IOException An I/O exception occured
782 * @see Serializer#asDOMSerializer()
783 */
784 public DOMSerializer asDOMSerializer() throws IOException
785 {
786 return this;
787 }
788
789 /**
790 * Push a boolean state based on if the name of the current element
791 * is found in the list of qnames. A state is only pushed if
792 * there were some cdata-section-names were specified.
793 * <p>
794 * Hidden parameters are the vector of qualified elements specified in
795 * cdata-section-names attribute, and the m_cdataSectionStates stack
796 * onto which whether the current element is in the list is pushed (true or
797 * false). Other hidden parameters are the current elements namespaceURI,
798 * localName and qName
799 */
800 protected boolean isCdataSection()
801 {
802
803 boolean b = false;
804
805 if (null != m_cdataSectionElements)
806 {
807 if (m_elemContext.m_elementLocalName == null)
808 m_elemContext.m_elementLocalName =
809 getLocalName(m_elemContext.m_elementName);
810 if (m_elemContext.m_elementURI == null)
811 {
812 String prefix = getPrefixPart(m_elemContext.m_elementName);
813 if (prefix != null)
814 m_elemContext.m_elementURI =
815 m_prefixMap.lookupNamespace(prefix);
816
817 }
818
819 if ((null != m_elemContext.m_elementURI)
820 && m_elemContext.m_elementURI.length() == 0)
821 m_elemContext.m_elementURI = null;
822
823 int nElems = m_cdataSectionElements.size();
824
825 // loop through 2 at a time, as these are pairs of URI and localName
826 for (int i = 0; i < nElems; i += 2)
827 {
828 String uri = (String) m_cdataSectionElements.elementAt(i);
829 String loc = (String) m_cdataSectionElements.elementAt(i + 1);
830 if (loc.equals(m_elemContext.m_elementLocalName)
831 && subPartMatch(m_elemContext.m_elementURI, uri))
832 {
833 b = true;
834
835 break;
836 }
837 }
838 }
839 return b;
840 }
841
842 /**
843 * Tell if two strings are equal, without worry if the first string is null.
844 *
845 * @param p String reference, which may be null.
846 * @param t String reference, which may be null.
847 *
848 * @return true if strings are equal.
849 */
850 private static final boolean subPartMatch(String p, String t)
851 {
852 return (p == t) || ((null != p) && (p.equals(t)));
853 }
854
855 /**
856 * Returns the local name of a qualified name.
857 * If the name has no prefix,
858 * then it works as the identity (SAX2).
859 *
860 * @param qname a qualified name
861 * @return returns the prefix of the qualified name,
862 * or null if there is no prefix.
1295 *
1296 * @param mappings NamespaceMappings
1297 */
1298 public void setNamespaceMappings(NamespaceMappings mappings) {
1299 m_prefixMap = mappings;
1300 }
1301
1302 public boolean reset()
1303 {
1304 resetSerializerBase();
1305 return true;
1306 }
1307
1308 /**
1309 * Reset all of the fields owned by SerializerBase
1310 *
1311 */
1312 private void resetSerializerBase()
1313 {
1314 this.m_attributes.clear();
1315 this.m_cdataSectionElements = null;
1316 this.m_elemContext = new ElemContext();
1317 this.m_doctypePublic = null;
1318 this.m_doctypeSystem = null;
1319 this.m_doIndent = false;
1320 this.m_encoding = null;
1321 this.m_indentAmount = 0;
1322 this.m_inEntityRef = false;
1323 this.m_inExternalDTD = false;
1324 this.m_mediatype = null;
1325 this.m_needToCallStartDocument = true;
1326 this.m_needToOutputDocTypeDecl = false;
1327 if (this.m_prefixMap != null)
1328 this.m_prefixMap.reset();
1329 this.m_shouldNotWriteXMLHeader = false;
1330 this.m_sourceLocator = null;
1331 this.m_standalone = null;
1332 this.m_standaloneWasSpecified = false;
1333 this.m_tracer = null;
1334 this.m_transformer = null;
1335 this.m_version = null;
1336 // don't set writer to null, so that it might be re-used
1337 //this.m_writer = null;
1338 }
1339
1340 /**
1382 */
1383 public void unparsedEntityDecl(
1384 String arg0,
1385 String arg1,
1386 String arg2,
1387 String arg3)
1388 throws SAXException {
1389 // This method just provides a definition to satisfy the interface
1390 // A particular sub-class of SerializerBase provides the implementation (if desired)
1391 }
1392
1393 /**
1394 * If set to false the serializer does not expand DTD entities,
1395 * but leaves them as is, the default value is true.
1396 */
1397 public void setDTDEntityExpansion(boolean expand) {
1398 // This method just provides a definition to satisfy the interface
1399 // A particular sub-class of SerializerBase provides the implementation (if desired)
1400 }
1401
1402 }
|
1 /*
2 * reserved comment block
3 * DO NOT REMOVE OR ALTER!
4 */
5 /*
6 * Licensed to the Apache Software Foundation (ASF) under one
7 * or more contributor license agreements. See the NOTICE file
8 * distributed with this work for additional information
9 * regarding copyright ownership. The ASF licenses this file
10 * to you under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22 /*
23 * $Id: SerializerBase.java,v 1.5 2006/04/14 12:09:19 sunithareddy Exp $
24 */
25 package com.sun.org.apache.xml.internal.serializer;
26
27 import java.io.IOException;
28 import java.util.HashMap;
29 import java.util.Set;
30 import java.util.ArrayList;
31
32 import javax.xml.transform.OutputKeys;
33 import javax.xml.transform.SourceLocator;
34 import javax.xml.transform.Transformer;
35
36 import com.sun.org.apache.xml.internal.serializer.utils.MsgKey;
37 import com.sun.org.apache.xml.internal.serializer.utils.Utils;
38 import org.xml.sax.Attributes;
39 import org.xml.sax.ContentHandler;
40 import org.xml.sax.Locator;
41 import org.xml.sax.SAXException;
42 import org.xml.sax.SAXParseException;
43 import org.xml.sax.ext.Locator2;
44
45
46 /**
47 * This class acts as a base class for the XML "serializers"
48 * and the stream serializers.
49 * It contains a number of common fields and methods.
50 *
51 * @xsl.usage internal
52 */
96 protected boolean m_cdataTagOpen = false;
97
98 /**
99 * All the attributes of the current element, collected from
100 * startPrefixMapping() calls, or addAddtribute() calls, or
101 * from the SAX attributes in a startElement() call.
102 */
103 protected AttributesImplSerializer m_attributes = new AttributesImplSerializer();
104
105 /**
106 * Tells if we're in an EntityRef event.
107 */
108 protected boolean m_inEntityRef = false;
109
110 /** This flag is set while receiving events from the external DTD */
111 protected boolean m_inExternalDTD = false;
112
113 /**
114 * The System ID for the doc type.
115 */
116 protected String m_doctypeSystem;
117
118 /**
119 * The public ID for the doc type.
120 */
121 protected String m_doctypePublic;
122
123 /**
124 * Flag to tell that we need to add the doctype decl, which we can't do
125 * until the first element is encountered.
126 */
127 boolean m_needToOutputDocTypeDecl = true;
128
129 /**
130 * Tells if we should write the XML declaration.
131 */
132 protected boolean m_shouldNotWriteXMLHeader = false;
133
134 /**
135 * The standalone value for the doctype.
136 */
137 private String m_standalone;
138
139 /**
140 * True if standalone was specified.
141 */
142 protected boolean m_standaloneWasSpecified = false;
143
144 /**
145 * Determine if the output is a standalone.
146 */
147 protected boolean m_isStandalone = false;
148
149 /**
150 * Flag to tell if indenting (pretty-printing) is on.
151 */
152 protected boolean m_doIndent = false;
153 /**
154 * Amount to indent.
155 */
156 protected int m_indentAmount = 0;
157
158 /**
159 * Tells the XML version, for writing out to the XML decl.
160 */
161 protected String m_version = null;
162
163 /**
164 * The mediatype. Not used right now.
165 */
166 protected String m_mediatype;
167
168 /**
169 * The transformer that was around when this output handler was created (if
170 * any).
171 */
172 private Transformer m_transformer;
173
174 /**
175 * Namespace support, that keeps track of currently defined
176 * prefix/uri mappings. As processed elements come and go, so do
177 * the associated mappings for that element.
178 */
179 protected NamespaceMappings m_prefixMap;
180
181 /**
182 * Handle for firing generate events. This interface may be implemented
183 * by the referenced transformer object.
184 */
185 protected SerializerTrace m_tracer;
186
187 protected SourceLocator m_sourceLocator;
188
189
190 /**
191 * The writer to send output to. This field is only used in the ToStream
192 * serializers, but exists here just so that the fireStartDoc() and
193 * other fire... methods can flush this writer when tracing.
194 */
513 {
514 // do nothing (base behavior)
515 }
516
517 /**
518 * Initialize global variables
519 */
520 protected void initCDATA()
521 {
522 // CDATA stack
523 // _cdataStack = new Stack();
524 // _cdataStack.push(new Integer(-1)); // push dummy value
525 }
526
527 /**
528 * Returns the character encoding to be used in the output document.
529 * @return the character encoding to be used in the output document.
530 */
531 public String getEncoding()
532 {
533 return getOutputProperty(OutputKeys.ENCODING);
534 }
535
536 /**
537 * Sets the character encoding coming from the xsl:output encoding stylesheet attribute.
538 * @param m_encoding the character encoding
539 */
540 public void setEncoding(String encoding)
541 {
542 setOutputProperty(OutputKeys.ENCODING,encoding);
543 }
544
545 /**
546 * Sets the value coming from the xsl:output omit-xml-declaration stylesheet attribute
547 * @param b true if the XML declaration is to be omitted from the output
548 * document.
549 */
550 public void setOmitXMLDeclaration(boolean b)
551 {
552 String val = b ? "yes":"no";
553 setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,val);
554 }
555
556
557 /**
558 * @return true if the XML declaration is to be omitted from the output
559 * document.
560 */
561 public boolean getOmitXMLDeclaration()
562 {
563 return m_shouldNotWriteXMLHeader;
564 }
565
566 /**
567 * Returns the previously set value of the value to be used as the public
568 * identifier in the document type declaration (DTD).
569 *
570 *@return the public identifier to be used in the DOCTYPE declaration in the
571 * output document.
572 */
573 public String getDoctypePublic()
574 {
575 return m_doctypePublic;
576 }
577
578 /** Set the value coming from the xsl:output doctype-public stylesheet attribute.
579 * @param doctypePublic the public identifier to be used in the DOCTYPE
580 * declaration in the output document.
581 */
582 public void setDoctypePublic(String doctypePublic)
583 {
584 setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doctypePublic);
585 }
586
587
588 /**
589 * Returns the previously set value of the value to be used
590 * as the system identifier in the document type declaration (DTD).
591 * @return the system identifier to be used in the DOCTYPE declaration in
592 * the output document.
593 *
594 */
595 public String getDoctypeSystem()
596 {
597 return m_doctypeSystem;
598 }
599
600 /** Set the value coming from the xsl:output doctype-system stylesheet attribute.
601 * @param doctypeSystem the system identifier to be used in the DOCTYPE
602 * declaration in the output document.
603 */
604 public void setDoctypeSystem(String doctypeSystem)
605 {
606 setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doctypeSystem);
607 }
608
609 /** Set the value coming from the xsl:output doctype-public and doctype-system stylesheet properties
610 * @param doctypeSystem the system identifier to be used in the DOCTYPE
611 * declaration in the output document.
612 * @param doctypePublic the public identifier to be used in the DOCTYPE
613 * declaration in the output document.
614 */
615 public void setDoctype(String doctypeSystem, String doctypePublic)
616 {
617 setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doctypeSystem);
618 setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doctypePublic);
619 }
620
621 /**
622 * Sets the value coming from the xsl:output standalone stylesheet attribute.
623 * @param standalone a value of "yes" indicates that the
624 * <code>standalone</code> delaration is to be included in the output
625 * document. This method remembers if the value was explicitly set using
626 * this method, verses if the value is the default value.
627 */
628 public void setStandalone(String standalone)
629 {
630 setOutputProperty(OutputKeys.STANDALONE, standalone);
631 }
632
633 /**
634 * Sets the XSL standalone attribute, but does not remember if this is a
635 * default or explicite setting.
636 * @param standalone "yes" | "no"
637 */
638 protected void setStandaloneInternal(String standalone)
639 {
640 if ("yes".equals(standalone))
641 m_standalone = "yes";
642 else
643 m_standalone = "no";
644
645 }
646
647 /**
648 * Gets the XSL standalone attribute
649 * @return a value of "yes" if the <code>standalone</code> delaration is to
650 * be included in the output document.
651 * @see XSLOutputAttributes#getStandalone()
652 */
673 {
674 return m_mediatype;
675 }
676
677 /**
678 * Gets the version of the output format.
679 * @return the version of the output format.
680 */
681 public String getVersion()
682 {
683 return m_version;
684 }
685
686 /**
687 * Sets the value coming from the xsl:output version attribute.
688 * @param version the version of the output format.
689 * @see SerializationHandler#setVersion(String)
690 */
691 public void setVersion(String version)
692 {
693 setOutputProperty(OutputKeys.VERSION, version);
694 }
695
696 /**
697 * Sets the value coming from the xsl:output media-type stylesheet attribute.
698 * @param mediaType the non-null media-type or MIME type associated with the
699 * output document.
700 * @see javax.xml.transform.OutputKeys#MEDIA_TYPE
701 * @see SerializationHandler#setMediaType(String)
702 */
703 public void setMediaType(String mediaType)
704 {
705 setOutputProperty(OutputKeys.MEDIA_TYPE,mediaType);
706 }
707
708 /**
709 * @return the number of spaces to indent for each indentation level.
710 */
711 public int getIndentAmount()
712 {
713 return m_indentAmount;
714 }
715
716 /**
717 * Sets the indentation amount.
718 * @param m_indentAmount The m_indentAmount to set
719 */
720 public void setIndentAmount(int m_indentAmount)
721 {
722 this.m_indentAmount = m_indentAmount;
723 }
724
725 /**
726 * Sets the value coming from the xsl:output indent stylesheet
727 * attribute.
728 * @param doIndent true if the output document should be indented to
729 * visually indicate its structure.
730 * @see XSLOutputAttributes#setIndent(boolean)
731 */
732 public void setIndent(boolean doIndent)
733 {
734 String val = doIndent ? "yes":"no";
735 setOutputProperty(OutputKeys.INDENT,val);
736 }
737
738 /**
739 * Sets the isStandalone property
740 * @param isStandalone true if the ORACLE_IS_STANDALONE is set to yes
741 * @see OutputPropertiesFactory ORACLE_IS_STANDALONE
742 */
743 public void setIsStandalone(boolean isStandalone)
744 {
745 m_isStandalone = isStandalone;
746 }
747
748 /**
749 * This method is used when a prefix/uri namespace mapping
750 * is indicated after the element was started with a
751 * startElement() and before and endElement().
752 * startPrefixMapping(prefix,uri) would be used before the
753 * startElement() call.
754 * @param uri the URI of the namespace
755 * @param prefix the prefix associated with the given URI.
761 {
762 // default behavior is to do nothing
763 }
764
765 /**
766 * Return a {@link DOMSerializer} interface into this serializer. If the
767 * serializer does not support the {@link DOMSerializer} interface, it should
768 * return null.
769 *
770 * @return A {@link DOMSerializer} interface into this serializer, or null
771 * if the serializer is not DOM capable
772 * @throws IOException An I/O exception occured
773 * @see Serializer#asDOMSerializer()
774 */
775 public DOMSerializer asDOMSerializer() throws IOException
776 {
777 return this;
778 }
779
780 /**
781 * Tell if two strings are equal, without worry if the first string is null.
782 *
783 * @param p String reference, which may be null.
784 * @param t String reference, which may be null.
785 *
786 * @return true if strings are equal.
787 */
788 private static final boolean subPartMatch(String p, String t)
789 {
790 return (p == t) || ((null != p) && (p.equals(t)));
791 }
792
793 /**
794 * Returns the local name of a qualified name.
795 * If the name has no prefix,
796 * then it works as the identity (SAX2).
797 *
798 * @param qname a qualified name
799 * @return returns the prefix of the qualified name,
800 * or null if there is no prefix.
1233 *
1234 * @param mappings NamespaceMappings
1235 */
1236 public void setNamespaceMappings(NamespaceMappings mappings) {
1237 m_prefixMap = mappings;
1238 }
1239
1240 public boolean reset()
1241 {
1242 resetSerializerBase();
1243 return true;
1244 }
1245
1246 /**
1247 * Reset all of the fields owned by SerializerBase
1248 *
1249 */
1250 private void resetSerializerBase()
1251 {
1252 this.m_attributes.clear();
1253 this.m_StringOfCDATASections = null;
1254 this.m_elemContext = new ElemContext();
1255 this.m_doctypePublic = null;
1256 this.m_doctypeSystem = null;
1257 this.m_doIndent = false;
1258 this.m_indentAmount = 0;
1259 this.m_inEntityRef = false;
1260 this.m_inExternalDTD = false;
1261 this.m_mediatype = null;
1262 this.m_needToCallStartDocument = true;
1263 this.m_needToOutputDocTypeDecl = false;
1264 if (this.m_prefixMap != null)
1265 this.m_prefixMap.reset();
1266 this.m_shouldNotWriteXMLHeader = false;
1267 this.m_sourceLocator = null;
1268 this.m_standalone = null;
1269 this.m_standaloneWasSpecified = false;
1270 this.m_tracer = null;
1271 this.m_transformer = null;
1272 this.m_version = null;
1273 // don't set writer to null, so that it might be re-used
1274 //this.m_writer = null;
1275 }
1276
1277 /**
1319 */
1320 public void unparsedEntityDecl(
1321 String arg0,
1322 String arg1,
1323 String arg2,
1324 String arg3)
1325 throws SAXException {
1326 // This method just provides a definition to satisfy the interface
1327 // A particular sub-class of SerializerBase provides the implementation (if desired)
1328 }
1329
1330 /**
1331 * If set to false the serializer does not expand DTD entities,
1332 * but leaves them as is, the default value is true.
1333 */
1334 public void setDTDEntityExpansion(boolean expand) {
1335 // This method just provides a definition to satisfy the interface
1336 // A particular sub-class of SerializerBase provides the implementation (if desired)
1337 }
1338
1339
1340 /**
1341 * The CDATA section names stored in a whitespace separateed list with
1342 * each element being a word of the form "{uri}localName" This list
1343 * comes from the cdata-section-elements attribute.
1344 *
1345 * This field replaces m_cdataSectionElements Vector.
1346 */
1347 protected String m_StringOfCDATASections = null;
1348
1349 boolean m_docIsEmpty = true;
1350 void initCdataElems(String s)
1351 {
1352 if (s != null)
1353 {
1354 int max = s.length();
1355
1356 // true if we are in the middle of a pair of curly braces that delimit a URI
1357 boolean inCurly = false;
1358
1359 // true if we found a URI but haven't yet processed the local name
1360 boolean foundURI = false;
1361
1362 StringBuilder buf = new StringBuilder();
1363 String uri = null;
1364 String localName = null;
1365
1366 // parse through string, breaking on whitespaces. I do this instead
1367 // of a tokenizer so I can track whitespace inside of curly brackets,
1368 // which theoretically shouldn't happen if they contain legal URLs.
1369 for (int i = 0; i < max; i++)
1370 {
1371 char c = s.charAt(i);
1372
1373 if (Character.isWhitespace(c))
1374 {
1375 if (!inCurly)
1376 {
1377 if (buf.length() > 0)
1378 {
1379 localName = buf.toString();
1380 if (!foundURI)
1381 uri = "";
1382 addCDATAElement(uri,localName);
1383 buf.setLength(0);
1384 foundURI = false;
1385 }
1386 continue;
1387 }
1388 else
1389 buf.append(c); // add whitespace to the URI
1390 }
1391 else if ('{' == c) // starting a URI
1392 inCurly = true;
1393 else if ('}' == c)
1394 {
1395 // we just ended a URI
1396 foundURI = true;
1397 uri = buf.toString();
1398 buf.setLength(0);
1399 inCurly = false;
1400 }
1401 else
1402 {
1403 // append non-whitespace, non-curly to current URI or localName being gathered.
1404 buf.append(c);
1405 }
1406
1407 }
1408
1409 if (buf.length() > 0)
1410 {
1411 // We have one last localName to process.
1412 localName = buf.toString();
1413 if (!foundURI)
1414 uri = "";
1415 addCDATAElement(uri,localName);
1416 }
1417 }
1418 }
1419
1420 protected java.util.HashMap<String, HashMap<String, String>> m_CdataElems = null;
1421 private void addCDATAElement(String uri, String localName)
1422 {
1423 if (m_CdataElems == null) {
1424 m_CdataElems = new java.util.HashMap<>();
1425 }
1426
1427 HashMap<String,String> h = m_CdataElems.get(localName);
1428 if (h == null) {
1429 h = new HashMap<>();
1430 m_CdataElems.put(localName,h);
1431 }
1432 h.put(uri,uri);
1433
1434 }
1435
1436
1437 /**
1438 * Return true if nothing has been sent to this result tree yet.
1439 * <p>
1440 * This is not a public API.
1441 *
1442 * @xsl.usage internal
1443 */
1444 public boolean documentIsEmpty() {
1445 // If we haven't called startDocument() yet, then this document is empty
1446 return m_docIsEmpty && (m_elemContext.m_currentElemDepth == 0);
1447 }
1448
1449 /**
1450 * Return true if the current element in m_elemContext
1451 * is a CDATA section.
1452 * CDATA sections are specified in the <xsl:output> attribute
1453 * cdata-section-names or in the JAXP equivalent property.
1454 * In any case the format of the value of such a property is:
1455 * <pre>
1456 * "{uri1}localName1 {uri2}localName2 . . . "
1457 * </pre>
1458 *
1459 * <p>
1460 * This method is not a public API, but is only used internally by the serializer.
1461 */
1462 protected boolean isCdataSection() {
1463 boolean b = false;
1464
1465 if (null != m_StringOfCDATASections) {
1466 if (m_elemContext.m_elementLocalName == null) {
1467 String localName = getLocalName(m_elemContext.m_elementName);
1468 m_elemContext.m_elementLocalName = localName;
1469 }
1470
1471 if ( m_elemContext.m_elementURI == null) {
1472
1473 m_elemContext.m_elementURI = getElementURI();
1474 }
1475 else if ( m_elemContext.m_elementURI.length() == 0) {
1476 if ( m_elemContext.m_elementName == null) {
1477 m_elemContext.m_elementName = m_elemContext.m_elementLocalName;
1478 // leave URI as "", meaning in no namespace
1479 }
1480 else if (m_elemContext.m_elementLocalName.length() < m_elemContext.m_elementName.length()){
1481 // We were told the URI was "", yet the name has a prefix since the name is longer than the localname.
1482 // So we will fix that incorrect information here.
1483 m_elemContext.m_elementURI = getElementURI();
1484 }
1485 }
1486
1487 HashMap<String, String> h = null;
1488 if (m_CdataElems != null) {
1489 h = m_CdataElems.get(m_elemContext.m_elementLocalName);
1490 }
1491 if (h != null) {
1492 Object obj = h.get(m_elemContext.m_elementURI);
1493 if (obj != null)
1494 b = true;
1495 }
1496
1497 }
1498 return b;
1499 }
1500
1501 /**
1502 * Before this call m_elementContext.m_elementURI is null,
1503 * which means it is not yet known. After this call it
1504 * is non-null, but possibly "" meaning that it is in the
1505 * default namespace.
1506 *
1507 * @return The URI of the element, never null, but possibly "".
1508 */
1509 private String getElementURI() {
1510 String uri = null;
1511 // At this point in processing we have received all the
1512 // namespace mappings
1513 // As we still don't know the elements namespace,
1514 // we now figure it out.
1515
1516 String prefix = getPrefixPart(m_elemContext.m_elementName);
1517
1518 if (prefix == null) {
1519 // no prefix so lookup the URI of the default namespace
1520 uri = m_prefixMap.lookupNamespace("");
1521 } else {
1522 uri = m_prefixMap.lookupNamespace(prefix);
1523 }
1524 if (uri == null) {
1525 // We didn't find the namespace for the
1526 // prefix ... ouch, that shouldn't happen.
1527 // This is a hack, we really don't know
1528 // the namespace
1529 uri = EMPTYSTRING;
1530 }
1531
1532 return uri;
1533 }
1534
1535
1536 /**
1537 * Get the value of an output property,
1538 * the explicit value, if any, otherwise the
1539 * default value, if any, otherwise null.
1540 */
1541 public String getOutputProperty(String name) {
1542 String val = getOutputPropertyNonDefault(name);
1543 // If no explicit value, try to get the default value
1544 if (val == null)
1545 val = getOutputPropertyDefault(name);
1546 return val;
1547
1548 }
1549 /**
1550 * Get the value of an output property,
1551 * not the default value. If there is a default
1552 * value, but no non-default value this method
1553 * will return null.
1554 * <p>
1555 *
1556 */
1557 public String getOutputPropertyNonDefault(String name) {
1558 return getProp(name,false);
1559 }
1560
1561 /**
1562 * Get the default value of an xsl:output property,
1563 * which would be null only if no default value exists
1564 * for the property.
1565 */
1566 public String getOutputPropertyDefault(String name) {
1567 return getProp(name, true);
1568 }
1569
1570 /**
1571 * Set the value for the output property, typically from
1572 * an xsl:output element, but this does not change what
1573 * the default value is.
1574 */
1575 public void setOutputProperty(String name, String val) {
1576 setProp(name,val,false);
1577 }
1578
1579 /**
1580 * Set the default value for an output property, but this does
1581 * not impact any explicitly set value.
1582 */
1583 public void setOutputPropertyDefault(String name, String val) {
1584 setProp(name,val,true);
1585
1586 }
1587
1588 /**
1589 * A mapping of keys to explicitly set values, for example if
1590 * and <xsl:output/> has an "encoding" attribute, this
1591 * map will have what that attribute maps to.
1592 */
1593 private HashMap<String, String> m_OutputProps;
1594 /**
1595 * A mapping of keys to default values, for example if
1596 * the default value of the encoding is "UTF-8" then this
1597 * map will have that "encoding" maps to "UTF-8".
1598 */
1599 private HashMap<String, String> m_OutputPropsDefault;
1600
1601 Set<String> getOutputPropDefaultKeys() {
1602 return m_OutputPropsDefault.keySet();
1603 }
1604 Set<String> getOutputPropKeys() {
1605 return m_OutputProps.keySet();
1606 }
1607
1608 private String getProp(String name, boolean defaultVal) {
1609 if (m_OutputProps == null) {
1610 m_OutputProps = new HashMap<>();
1611 m_OutputPropsDefault = new HashMap<>();
1612 }
1613
1614 String val;
1615 if (defaultVal)
1616 val = m_OutputPropsDefault.get(name);
1617 else
1618 val = m_OutputProps.get(name);
1619
1620 return val;
1621 }
1622 /**
1623 *
1624 * @param name The name of the property, e.g. "{http://myprop}indent-tabs" or "indent".
1625 * @param val The value of the property, e.g. "4"
1626 * @param defaultVal true if this is a default value being set for the property as
1627 * opposed to a user define on, set say explicitly in the stylesheet or via JAXP
1628 */
1629 void setProp(String name, String val, boolean defaultVal) {
1630 if (m_OutputProps == null) {
1631 m_OutputProps = new HashMap<>();
1632 m_OutputPropsDefault = new HashMap<>();
1633 }
1634
1635 if (defaultVal)
1636 m_OutputPropsDefault.put(name,val);
1637 else {
1638 if (OutputKeys.CDATA_SECTION_ELEMENTS.equals(name) && val != null) {
1639 initCdataElems(val);
1640 String oldVal = m_OutputProps.get(name);
1641 String newVal;
1642 if (oldVal == null)
1643 newVal = oldVal + ' ' + val;
1644 else
1645 newVal = val;
1646 m_OutputProps.put(name,newVal);
1647 }
1648 else {
1649 m_OutputProps.put(name,val);
1650 }
1651 }
1652 }
1653
1654 /**
1655 * Get the first char of the local name
1656 * @param name Either a local name, or a local name
1657 * preceeded by a uri enclosed in curly braces.
1658 */
1659 static char getFirstCharLocName(String name) {
1660 final char first;
1661 int i = name.indexOf('}');
1662 if (i < 0)
1663 first = name.charAt(0);
1664 else
1665 first = name.charAt(i+1);
1666 return first;
1667 }
1668 }
|