1/* 2 * Copyright (c) 2005, 2016, 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 26package com.sun.xml.internal.stream.writers; 27 28import java.util.Iterator; 29import javax.xml.namespace.NamespaceContext; 30import javax.xml.namespace.QName; 31import javax.xml.stream.XMLEventReader; 32import javax.xml.stream.XMLEventWriter; 33import javax.xml.stream.XMLStreamException; 34import javax.xml.stream.XMLStreamWriter; 35import javax.xml.stream.events.Attribute; 36import javax.xml.stream.events.Characters; 37import javax.xml.stream.events.Comment; 38import javax.xml.stream.events.DTD; 39import javax.xml.stream.events.EntityReference; 40import javax.xml.stream.events.Namespace; 41import javax.xml.stream.events.ProcessingInstruction; 42import javax.xml.stream.events.StartDocument; 43import javax.xml.stream.events.StartElement; 44import javax.xml.stream.events.XMLEvent; 45 46/** 47 * 48 * @author Neeraj Bajaj, Sun Microsystems. 49 * 50 */ 51public class XMLEventWriterImpl implements XMLEventWriter { 52 53 //delegate everything to XMLStreamWriter.. 54 private final XMLStreamWriterBase fStreamWriter; 55 private static final boolean DEBUG = false; 56 57 /** 58 * 59 * @param streamWriter 60 */ 61 public XMLEventWriterImpl(XMLStreamWriter streamWriter) { 62 fStreamWriter = (XMLStreamWriterBase) streamWriter; 63 } 64 65 /** 66 * 67 * @param xMLEventReader 68 * @throws XMLStreamException 69 */ 70 public void add(XMLEventReader xMLEventReader) throws XMLStreamException { 71 if (xMLEventReader == null) { 72 throw new XMLStreamException("Event reader shouldn't be null"); 73 } 74 while (xMLEventReader.hasNext()) { 75 add(xMLEventReader.nextEvent()); 76 } 77 } 78 79 /** 80 * 81 * @param xMLEvent 82 * @throws XMLStreamException 83 */ 84 public void add(XMLEvent xMLEvent) throws XMLStreamException { 85 int type = xMLEvent.getEventType(); 86 switch (type) { 87 case XMLEvent.DTD: { 88 DTD dtd = (DTD) xMLEvent; 89 if (DEBUG) { 90 System.out.println("Adding DTD = " + dtd.toString()); 91 } 92 fStreamWriter.writeDTD(dtd.getDocumentTypeDeclaration()); 93 break; 94 } 95 case XMLEvent.START_DOCUMENT: { 96 StartDocument startDocument = (StartDocument) xMLEvent; 97 if (DEBUG) { 98 System.out.println("Adding StartDocument = " + startDocument.toString()); 99 } 100 try { 101 fStreamWriter.writeStartDocument(startDocument.getCharacterEncodingScheme(), 102 startDocument.getVersion(), 103 startDocument.isStandalone(), startDocument.standaloneSet()); 104 } catch (XMLStreamException e) { 105 fStreamWriter.writeStartDocument(startDocument.getVersion()); 106 } 107 break; 108 } 109 case XMLEvent.START_ELEMENT: { 110 StartElement startElement = xMLEvent.asStartElement(); 111 if (DEBUG) { 112 System.out.println("Adding startelement = " + startElement.toString()); 113 } 114 QName qname = startElement.getName(); 115 fStreamWriter.writeStartElement(qname.getPrefix(), qname.getLocalPart(), 116 qname.getNamespaceURI()); 117 118 /* 119 getNamespaces() Returns an Iterator of namespaces declared on this element. 120 This Iterator does not contain previously declared namespaces unless they 121 appear on the current START_ELEMENT. Therefore this list may contain redeclared 122 namespaces and duplicate namespace declarations. Use the getNamespaceContext() 123 method to get the current context of namespace declarations. We should be 124 using getNamespaces() to write namespace declarations for this START_ELEMENT 125 */ 126 Iterator<? extends Namespace> iterator = startElement.getNamespaces(); 127 while (iterator.hasNext()) { 128 Namespace namespace = iterator.next(); 129 fStreamWriter.writeNamespace(namespace.getPrefix(), namespace.getNamespaceURI()); 130 } 131 //REVISIT: What about writing attributes ? 132 Iterator<? extends Attribute> attributes = startElement.getAttributes(); 133 while (attributes.hasNext()) { 134 Attribute attribute = attributes.next(); 135 QName aqname = attribute.getName(); 136 fStreamWriter.writeAttribute(aqname.getPrefix(), aqname.getNamespaceURI(), 137 aqname.getLocalPart(), attribute.getValue()); 138 } 139 break; 140 } 141 case XMLEvent.NAMESPACE: { 142 Namespace namespace = (Namespace) xMLEvent; 143 if (DEBUG) { 144 System.out.println("Adding namespace = " + namespace.toString()); 145 } 146 fStreamWriter.writeNamespace(namespace.getPrefix(), namespace.getNamespaceURI()); 147 break; 148 } 149 case XMLEvent.COMMENT: { 150 Comment comment = (Comment) xMLEvent; 151 if (DEBUG) { 152 System.out.println("Adding comment = " + comment.toString()); 153 } 154 fStreamWriter.writeComment(comment.getText()); 155 break; 156 } 157 case XMLEvent.PROCESSING_INSTRUCTION: { 158 ProcessingInstruction processingInstruction = (ProcessingInstruction) xMLEvent; 159 if (DEBUG) { 160 System.out.println("Adding processing instruction = " + processingInstruction.toString()); 161 } 162 fStreamWriter.writeProcessingInstruction(processingInstruction.getTarget(), 163 processingInstruction.getData()); 164 break; 165 } 166 case XMLEvent.CHARACTERS: { 167 Characters characters = xMLEvent.asCharacters(); 168 if (DEBUG) { 169 System.out.println("Adding characters = " + characters.toString()); 170 } 171 //check if the CHARACTERS are CDATA 172 if (characters.isCData()) { 173 fStreamWriter.writeCData(characters.getData()); 174 } else { 175 fStreamWriter.writeCharacters(characters.getData()); 176 } 177 break; 178 } 179 case XMLEvent.ENTITY_REFERENCE: { 180 EntityReference entityReference = (EntityReference) xMLEvent; 181 if (DEBUG) { 182 System.out.println("Adding Entity Reference = " + entityReference.toString()); 183 } 184 fStreamWriter.writeEntityRef(entityReference.getName()); 185 break; 186 } 187 case XMLEvent.ATTRIBUTE: { 188 Attribute attribute = (Attribute) xMLEvent; 189 if (DEBUG) { 190 System.out.println("Adding Attribute = " + attribute.toString()); 191 } 192 QName qname = attribute.getName(); 193 fStreamWriter.writeAttribute(qname.getPrefix(), qname.getNamespaceURI(), 194 qname.getLocalPart(), attribute.getValue()); 195 break; 196 } 197 case XMLEvent.CDATA: { 198 //there is no separate CDATA datatype but CDATA event can be reported 199 //by using vendor specific CDATA property. 200 Characters characters = (Characters) xMLEvent; 201 if (DEBUG) { 202 System.out.println("Adding characters = " + characters.toString()); 203 } 204 if (characters.isCData()) { 205 fStreamWriter.writeCData(characters.getData()); 206 } 207 break; 208 } 209 //xxx: Why there isn't any event called Notation. 210 //case XMLEvent.NOTATION_DECLARATION:{ 211 //} 212 213 case XMLEvent.END_ELEMENT: { 214 fStreamWriter.writeEndElement(); 215 break; 216 } 217 case XMLEvent.END_DOCUMENT: { 218 fStreamWriter.writeEndDocument(); 219 break; 220 } 221 //throw new XMLStreamException("Unknown Event type = " + type); 222 }; 223 224 } 225 226 /** 227 * 228 * @throws XMLStreamException 229 */ 230 public void close() throws XMLStreamException { 231 fStreamWriter.close(); 232 } 233 234 /** 235 * 236 * @throws XMLStreamException will inturn call flush on the stream to which 237 * data is being written. 238 */ 239 public void flush() throws XMLStreamException { 240 fStreamWriter.flush(); 241 } 242 243 /** 244 * 245 * @return 246 */ 247 public NamespaceContext getNamespaceContext() { 248 return fStreamWriter.getNamespaceContext(); 249 } 250 251 /** 252 * 253 * @param namespaceURI Namespace URI 254 * @throws XMLStreamException 255 * @return prefix associated with the URI. 256 */ 257 public String getPrefix(String namespaceURI) throws XMLStreamException { 258 return fStreamWriter.getPrefix(namespaceURI); 259 } 260 261 /** 262 * 263 * @param uri Namespace URI 264 * @throws XMLStreamException 265 */ 266 public void setDefaultNamespace(String uri) throws XMLStreamException { 267 fStreamWriter.setDefaultNamespace(uri); 268 } 269 270 /** 271 * 272 * @param namespaceContext Namespace Context 273 * @throws XMLStreamException 274 */ 275 public void setNamespaceContext(NamespaceContext namespaceContext) 276 throws XMLStreamException { 277 fStreamWriter.setNamespaceContext(namespaceContext); 278 } 279 280 /** 281 * 282 * @param prefix namespace prefix associated with the uri. 283 * @param uri Namespace URI 284 * @throws XMLStreamException 285 */ 286 public void setPrefix(String prefix, String uri) throws XMLStreamException { 287 fStreamWriter.setPrefix(prefix, uri); 288 } 289 290}//XMLEventWriterImpl 291