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