alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (XMLStreamWriterImpl.java)

This example Java source code file (XMLStreamWriterImpl.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

ampersand, charset, close_start_tag, doublequot, element, element_starttag_open, open_start_tag, state_element, state_xml_decl, string, unsupportedencodingexception, xmlstreamexception, xmlstreamwriterimpl, xmlwriter

The XMLStreamWriterImpl.java Java example source code

/*
 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.internal.util.xml.impl;

import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
import jdk.internal.util.xml.XMLStreamException;
import jdk.internal.util.xml.XMLStreamWriter;

/**
 * Implementation of a reduced version of XMLStreamWriter
 *
 * @author Joe Wang
 */
public class XMLStreamWriterImpl implements XMLStreamWriter {
    //Document state

    static final int STATE_XML_DECL = 1;
    static final int STATE_PROLOG = 2;
    static final int STATE_DTD_DECL = 3;
    static final int STATE_ELEMENT = 4;
    //Element state
    static final int ELEMENT_STARTTAG_OPEN = 10;
    static final int ELEMENT_STARTTAG_CLOSE = 11;
    static final int ELEMENT_ENDTAG_OPEN = 12;
    static final int ELEMENT_ENDTAG_CLOSE = 13;
    public static final char CLOSE_START_TAG = '>';
    public static final char OPEN_START_TAG = '<';
    public static final String OPEN_END_TAG = "</";
    public static final char CLOSE_END_TAG = '>';
    public static final String START_CDATA = "<![CDATA[";
    public static final String END_CDATA = "]]>";
    public static final String CLOSE_EMPTY_ELEMENT = "/>";
    public static final String ENCODING_PREFIX = "&#x";
    public static final char SPACE = ' ';
    public static final char AMPERSAND = '&';
    public static final char DOUBLEQUOT = '"';
    public static final char SEMICOLON = ';';
    //current state
    private int _state = 0;
    private Element _currentEle;
    private XMLWriter _writer;
    private String _encoding;
    /**
     * This flag can be used to turn escaping off for content. It does
     * not apply to attribute content.
     */
    boolean _escapeCharacters = true;
    //pretty print by default
    private boolean _doIndent = true;
    //The system line separator for writing out line breaks.
    private char[] _lineSep =
            System.getProperty("line.separator").toCharArray();

    public XMLStreamWriterImpl(OutputStream os) throws XMLStreamException {
        this(os, XMLStreamWriter.DEFAULT_ENCODING);
    }

    public XMLStreamWriterImpl(OutputStream os, String encoding)
        throws XMLStreamException
    {
        Charset cs = null;
        if (encoding == null) {
            _encoding = XMLStreamWriter.DEFAULT_ENCODING;
        } else {
            try {
                cs = getCharset(encoding);
            } catch (UnsupportedEncodingException e) {
                throw new XMLStreamException(e);
            }

            this._encoding = encoding;
        }

        _writer = new XMLWriter(os, encoding, cs);
    }

    /**
     * Write the XML Declaration. Defaults the XML version to 1.0, and the
     * encoding to utf-8.
     *
     * @throws XMLStreamException
     */
    public void writeStartDocument() throws XMLStreamException {
        writeStartDocument(_encoding, XMLStreamWriter.DEFAULT_XML_VERSION);
    }

    /**
     * Write the XML Declaration. Defaults the encoding to utf-8
     *
     * @param version version of the xml document
     * @throws XMLStreamException
     */
    public void writeStartDocument(String version) throws XMLStreamException {
        writeStartDocument(_encoding, version, null);
    }

    /**
     * Write the XML Declaration. Note that the encoding parameter does not set
     * the actual encoding of the underlying output. That must be set when the
     * instance of the XMLStreamWriter is created
     *
     * @param encoding encoding of the xml declaration
     * @param version version of the xml document
     * @throws XMLStreamException If given encoding does not match encoding of the
     * underlying stream
     */
    public void writeStartDocument(String encoding, String version) throws XMLStreamException {
        writeStartDocument(encoding, version, null);
    }

    /**
     * Write the XML Declaration. Note that the encoding parameter does not set
     * the actual encoding of the underlying output. That must be set when the
     * instance of the XMLStreamWriter is created
     *
     * @param encoding encoding of the xml declaration
     * @param version version of the xml document
     * @param standalone indicate if the xml document is standalone
     * @throws XMLStreamException If given encoding does not match encoding of the
     * underlying stream
     */
    public void writeStartDocument(String encoding, String version, String standalone)
        throws XMLStreamException
    {
        if (_state > 0) {
            throw new XMLStreamException("XML declaration must be as the first line in the XML document.");
        }
        _state = STATE_XML_DECL;
        String enc = encoding;
        if (enc == null) {
            enc = _encoding;
        } else {
            //check if the encoding is supported
            try {
                getCharset(encoding);
            } catch (UnsupportedEncodingException e) {
                throw new XMLStreamException(e);
            }
        }

        if (version == null) {
            version = XMLStreamWriter.DEFAULT_XML_VERSION;
        }

        _writer.write("<?xml version=\"");
        _writer.write(version);
        _writer.write(DOUBLEQUOT);

        if (enc != null) {
            _writer.write(" encoding=\"");
            _writer.write(enc);
            _writer.write(DOUBLEQUOT);
        }

        if (standalone != null) {
            _writer.write(" standalone=\"");
            _writer.write(standalone);
            _writer.write(DOUBLEQUOT);
        }
        _writer.write("?>");
        writeLineSeparator();
    }

    /**
     * Write a DTD section.  This string represents the entire doctypedecl production
     * from the XML 1.0 specification.
     *
     * @param dtd the DTD to be written
     * @throws XMLStreamException
     */
    public void writeDTD(String dtd) throws XMLStreamException {
        if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
            closeStartTag();
        }
        _writer.write(dtd);
        writeLineSeparator();
    }

    /**
     * Writes a start tag to the output.
     * @param localName local name of the tag, may not be null
     * @throws XMLStreamException
     */
    public void writeStartElement(String localName) throws XMLStreamException {
        if (localName == null || localName.length() == 0) {
            throw new XMLStreamException("Local Name cannot be null or empty");
        }

        _state = STATE_ELEMENT;
        if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
            closeStartTag();
        }

        _currentEle = new Element(_currentEle, localName, false);
        openStartTag();

        _writer.write(localName);
    }

    /**
     * Writes an empty element tag to the output
     * @param localName local name of the tag, may not be null
     * @throws XMLStreamException
     */
    public void writeEmptyElement(String localName) throws XMLStreamException {
        if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
            closeStartTag();
        }

        _currentEle = new Element(_currentEle, localName, true);

        openStartTag();
        _writer.write(localName);
    }

    /**
     * Writes an attribute to the output stream without a prefix.
     * @param localName the local name of the attribute
     * @param value the value of the attribute
     * @throws IllegalStateException if the current state does not allow Attribute writing
     * @throws XMLStreamException
     */
    public void writeAttribute(String localName, String value) throws XMLStreamException {
        if (_currentEle.getState() != ELEMENT_STARTTAG_OPEN) {
            throw new XMLStreamException(
                    "Attribute not associated with any element");
        }

        _writer.write(SPACE);
        _writer.write(localName);
        _writer.write("=\"");
        writeXMLContent(
                value,
                true, // true = escapeChars
                true);  // true = escapeDoubleQuotes
        _writer.write(DOUBLEQUOT);
    }

    public void writeEndDocument() throws XMLStreamException {
        if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
            closeStartTag();
        }

        /**
         * close unclosed elements if any
         */
        while (_currentEle != null) {

            if (!_currentEle.isEmpty()) {
                _writer.write(OPEN_END_TAG);
                _writer.write(_currentEle.getLocalName());
                _writer.write(CLOSE_END_TAG);
            }

            _currentEle = _currentEle.getParent();
        }
    }

    public void writeEndElement() throws XMLStreamException {
        if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
            closeStartTag();
        }

        if (_currentEle == null) {
            throw new XMLStreamException("No element was found to write");
        }

        if (_currentEle.isEmpty()) {
            return;
        }

        _writer.write(OPEN_END_TAG);
        _writer.write(_currentEle.getLocalName());
        _writer.write(CLOSE_END_TAG);
        writeLineSeparator();

        _currentEle = _currentEle.getParent();
    }

    public void writeCData(String cdata) throws XMLStreamException {
        if (cdata == null) {
            throw new XMLStreamException("cdata cannot be null");
        }

        if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
            closeStartTag();
        }

        _writer.write(START_CDATA);
        _writer.write(cdata);
        _writer.write(END_CDATA);
    }

    public void writeCharacters(String data) throws XMLStreamException {
        if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
            closeStartTag();
        }

        writeXMLContent(data);
    }

    public void writeCharacters(char[] data, int start, int len)
            throws XMLStreamException {
        if (_currentEle != null && _currentEle.getState() == ELEMENT_STARTTAG_OPEN) {
            closeStartTag();
        }

        writeXMLContent(data, start, len, _escapeCharacters);
    }

    /**
     * Close this XMLStreamWriter by closing underlying writer.
     */
    public void close() throws XMLStreamException {
        if (_writer != null) {
            _writer.close();
        }
        _writer = null;
        _currentEle = null;
        _state = 0;
    }

    /**
     * Flush this XMLStreamWriter by flushing underlying writer.
     */
    public void flush() throws XMLStreamException {
        if (_writer != null) {
            _writer.flush();
        }
    }

    /**
     * Set the flag to indicate if the writer should add line separator
     * @param doIndent
     */
    public void setDoIndent(boolean doIndent) {
        _doIndent = doIndent;
    }

    /**
     * Writes XML content to underlying writer. Escapes characters unless
     * escaping character feature is turned off.
     */
    private void writeXMLContent(char[] content, int start, int length, boolean escapeChars)
        throws XMLStreamException
    {
        if (!escapeChars) {
            _writer.write(content, start, length);
            return;
        }

        // Index of the next char to be written
        int startWritePos = start;

        final int end = start + length;

        for (int index = start; index < end; index++) {
            char ch = content[index];

            if (!_writer.canEncode(ch)) {
                _writer.write(content, startWritePos, index - startWritePos);

                // Escape this char as underlying encoder cannot handle it
                _writer.write(ENCODING_PREFIX);
                _writer.write(Integer.toHexString(ch));
                _writer.write(SEMICOLON);
                startWritePos = index + 1;
                continue;
            }

            switch (ch) {
                case OPEN_START_TAG:
                    _writer.write(content, startWritePos, index - startWritePos);
                    _writer.write("<");
                    startWritePos = index + 1;

                    break;

                case AMPERSAND:
                    _writer.write(content, startWritePos, index - startWritePos);
                    _writer.write("&");
                    startWritePos = index + 1;

                    break;

                case CLOSE_START_TAG:
                    _writer.write(content, startWritePos, index - startWritePos);
                    _writer.write(">");
                    startWritePos = index + 1;

                    break;
            }
        }

        // Write any pending data
        _writer.write(content, startWritePos, end - startWritePos);
    }

    private void writeXMLContent(String content) throws XMLStreamException {
        if ((content != null) && (content.length() > 0)) {
            writeXMLContent(content,
                    _escapeCharacters, // boolean = escapeChars
                    false);             // false = escapeDoubleQuotes
        }
    }

    /**
     * Writes XML content to underlying writer. Escapes characters unless
     * escaping character feature is turned off.
     */
    private void writeXMLContent(
            String content,
            boolean escapeChars,
            boolean escapeDoubleQuotes)
        throws XMLStreamException
    {

        if (!escapeChars) {
            _writer.write(content);

            return;
        }

        // Index of the next char to be written
        int startWritePos = 0;

        final int end = content.length();

        for (int index = 0; index < end; index++) {
            char ch = content.charAt(index);

            if (!_writer.canEncode(ch)) {
                _writer.write(content, startWritePos, index - startWritePos);

                // Escape this char as underlying encoder cannot handle it
                _writer.write(ENCODING_PREFIX);
                _writer.write(Integer.toHexString(ch));
                _writer.write(SEMICOLON);
                startWritePos = index + 1;
                continue;
            }

            switch (ch) {
                case OPEN_START_TAG:
                    _writer.write(content, startWritePos, index - startWritePos);
                    _writer.write("<");
                    startWritePos = index + 1;

                    break;

                case AMPERSAND:
                    _writer.write(content, startWritePos, index - startWritePos);
                    _writer.write("&");
                    startWritePos = index + 1;

                    break;

                case CLOSE_START_TAG:
                    _writer.write(content, startWritePos, index - startWritePos);
                    _writer.write(">");
                    startWritePos = index + 1;

                    break;

                case DOUBLEQUOT:
                    _writer.write(content, startWritePos, index - startWritePos);
                    if (escapeDoubleQuotes) {
                        _writer.write(""");
                    } else {
                        _writer.write(DOUBLEQUOT);
                    }
                    startWritePos = index + 1;

                    break;
            }
        }

        // Write any pending data
        _writer.write(content, startWritePos, end - startWritePos);
    }

    /**
     * marks open of start tag and writes the same into the writer.
     */
    private void openStartTag() throws XMLStreamException {
        _currentEle.setState(ELEMENT_STARTTAG_OPEN);
        _writer.write(OPEN_START_TAG);
    }

    /**
     * marks close of start tag and writes the same into the writer.
     */
    private void closeStartTag() throws XMLStreamException {
        if (_currentEle.isEmpty()) {
            _writer.write(CLOSE_EMPTY_ELEMENT);
        } else {
            _writer.write(CLOSE_START_TAG);

        }

        if (_currentEle.getParent() == null) {
            writeLineSeparator();
        }

        _currentEle.setState(ELEMENT_STARTTAG_CLOSE);

    }

    /**
     * Write a line separator
     * @throws XMLStreamException
     */
    private void writeLineSeparator() throws XMLStreamException {
        if (_doIndent) {
            _writer.write(_lineSep, 0, _lineSep.length);
        }
    }

    /**
     * Returns a charset object for the specified encoding
     * @param encoding
     * @return a charset object
     * @throws UnsupportedEncodingException if the encoding is not supported
     */
    private Charset getCharset(String encoding) throws UnsupportedEncodingException {
        if (encoding.equalsIgnoreCase("UTF-32")) {
            throw new UnsupportedEncodingException("The basic XMLWriter does "
                    + "not support " + encoding);
        }

        Charset cs;
        try {
            cs = Charset.forName(encoding);
        } catch (IllegalCharsetNameException | UnsupportedCharsetException ex) {
            throw new UnsupportedEncodingException(encoding);
        }
        return cs;
    }

    /*
     * Start of Internal classes.
     *
     */
    protected class Element {

        /**
         * the parent element
         */
        protected Element _parent;
        /**
         * The size of the stack.
         */
        protected short _Depth;
        /**
         * indicate if an element is an empty one
         */
        boolean _isEmptyElement = false;
        String _localpart;
        int _state;

        /**
         * Default constructor.
         */
        public Element() {
        }

        /**
         * @param parent the parent of the element
         * @param localpart name of the element
         * @param isEmpty indicate if the element is an empty one
         */
        public Element(Element parent, String localpart, boolean isEmpty) {
            _parent = parent;
            _localpart = localpart;
            _isEmptyElement = isEmpty;
        }

        public Element getParent() {
            return _parent;
        }

        public String getLocalName() {
            return _localpart;
        }

        /**
         * get the state of the element
         */
        public int getState() {
            return _state;
        }

        /**
         * Set the state of the element
         *
         * @param state the state of the element
         */
        public void setState(int state) {
            _state = state;
        }

        public boolean isEmpty() {
            return _isEmptyElement;
        }
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java XMLStreamWriterImpl.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.