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 private void writeStartDocument() throws SAXException { 200 try { 201 if (docLocator == null) { 202 writer.writeStartDocument(); 203 } else { 204 try { 205 writer.writeStartDocument(((Locator2) docLocator).getXMLVersion()); 206 } catch (ClassCastException e) { 207 writer.writeStartDocument(); 208 } 209 } 210 211 } catch (XMLStreamException e) { 212 throw new SAXException(e); 213 } 214 needToCallStartDocument = false; 215 } 216 }