1 /*
   2  * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.org.apache.xalan.internal.xsltc.trax;
  27 
  28 
  29 import javax.xml.stream.XMLStreamException;
  30 import javax.xml.stream.XMLStreamWriter;
  31 import org.xml.sax.Attributes;
  32 import org.xml.sax.SAXException;
  33 import org.xml.sax.ext.Locator2;
  34 
  35 /**
  36  * @author Sunitha Reddy
  37  */
  38 public class SAX2StAXStreamWriter extends SAX2StAXBaseWriter {
  39 
  40     private XMLStreamWriter writer;
  41 
  42     private boolean needToCallStartDocument = false;
  43 
  44     public SAX2StAXStreamWriter() {
  45 
  46     }
  47 
  48     public SAX2StAXStreamWriter(XMLStreamWriter writer) {
  49         this.writer = writer;
  50     }
  51 
  52     public XMLStreamWriter getStreamWriter() {
  53         return writer;
  54     }
  55 
  56     public void setStreamWriter(XMLStreamWriter writer) {
  57         this.writer = writer;
  58     }
  59 
  60     public void startDocument() throws SAXException {
  61         super.startDocument();
  62         // Encoding and version info will be available only after startElement
  63         // is called for first time. So, defer START_DOCUMENT event of StAX till
  64         // that point of time.
  65         needToCallStartDocument = true;
  66     }
  67 
  68     public void endDocument() throws SAXException {
  69         try {
  70             writer.writeEndDocument();
  71         } catch (XMLStreamException e) {
  72             throw new SAXException(e);
  73         }
  74 
  75         super.endDocument();
  76     }
  77 
  78     public void startElement(String uri, String localName, String qName,
  79             Attributes attributes) throws SAXException {
  80 
  81         if (needToCallStartDocument) {
  82             writeStartDocument();
  83         }
  84 
  85         try {
  86 
  87             String[] qname = {null, null};
  88             parseQName(qName, qname);
  89             //Do not call writeStartElement with prefix and namespaceURI, as it writes out
  90             //namespace declaration.
  91             //writer.writeStartElement(qname[0], qname[1], uri);
  92             writer.writeStartElement(qName);
  93 
  94             // write attributes and namespaces as attributes
  95             for (int i = 0, s = attributes.getLength(); i < s; i++) {
  96 
  97                 parseQName(attributes.getQName(i), qname);
  98 
  99                 String attrPrefix = qname[0];
 100                 String attrLocal = qname[1];
 101 
 102                 String attrQName = attributes.getQName(i);
 103                 String attrValue = attributes.getValue(i);
 104                 String attrURI = attributes.getURI(i);
 105 
 106                 if ("xmlns".equals(attrPrefix) || "xmlns".equals(attrQName)) {
 107                     // namespace declaration disguised as an attribute.
 108                     // write it as an namespace
 109                     if (attrLocal.length() == 0) {
 110                         writer.setDefaultNamespace(attrValue);
 111                     } else {
 112                         writer.setPrefix(attrLocal, attrValue);
 113                     }
 114 
 115                     writer.writeNamespace(attrLocal, attrValue);
 116 
 117                 } else if (attrPrefix.length() > 0) {
 118                     writer.writeAttribute(attrPrefix, attrURI, attrLocal,
 119                             attrValue);
 120                 } else {
 121                     writer.writeAttribute(attrQName, attrValue);
 122                 }
 123             }
 124 
 125         } catch (XMLStreamException e) {
 126             throw new SAXException(e);
 127         } finally {
 128             super.startElement(uri, localName, qName, attributes);
 129         }
 130     }
 131 
 132     public void endElement(String uri, String localName, String qName)
 133             throws SAXException {
 134         try {
 135             writer.writeEndElement();
 136         } catch (XMLStreamException e) {
 137             throw new SAXException(e);
 138         } finally {
 139             super.endElement(uri, localName, qName);
 140         }
 141     }
 142 
 143     public void comment(char[] ch, int start, int length) throws SAXException {
 144         if (needToCallStartDocument) {
 145             writeStartDocument();
 146         }
 147         super.comment(ch, start, length);
 148         try {
 149             writer.writeComment(new String(ch, start, length));
 150         } catch (XMLStreamException e) {
 151             throw new SAXException(e);
 152         }
 153     }
 154 
 155     public void characters(char[] ch, int start, int length)
 156             throws SAXException {
 157         super.characters(ch, start, length);
 158         try {
 159             if (!isCDATA) {
 160                 writer.writeCharacters(ch, start, length);
 161             }
 162         } catch (XMLStreamException e) {
 163             throw new SAXException(e);
 164         }
 165     }
 166 
 167     public void endCDATA() throws SAXException {
 168         try {
 169             writer.writeCData(CDATABuffer.toString());
 170         } catch (XMLStreamException e) {
 171             throw new SAXException(e);
 172         }
 173 
 174         super.endCDATA();
 175     }
 176 
 177     public void ignorableWhitespace(char[] ch, int start, int length)
 178             throws SAXException {
 179 
 180         super.ignorableWhitespace(ch, start, length);
 181         try {
 182             writer.writeCharacters(ch, start, length);
 183         } catch (XMLStreamException e) {
 184             throw new SAXException(e);
 185         }
 186     }
 187 
 188     public void processingInstruction(String target, String data)
 189             throws SAXException {
 190 
 191         super.processingInstruction(target, data);
 192         try {
 193             writer.writeProcessingInstruction(target, data);
 194         } catch (XMLStreamException e) {
 195             throw new SAXException(e);
 196         }
 197     }
 198 
 199     void writeStartDocument() throws SAXException {
 200         super.writeStartDocument();
 201         try {
 202             writer.writeStartDocument(xmlVersion);
 203         } catch (XMLStreamException e) {
 204             throw new SAXException(e);
 205         }
 206         needToCallStartDocument = false;
 207     }
 208 }