001    /*
002     * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons-sandbox//xmlio/src/java/org/apache/commons/xmlio/out/XMLOutputStreamWriter.java,v 1.1 2004/10/08 11:56:20 ozeigermann Exp $
003     * $Revision: 155476 $
004     * $Date: 2005-02-26 13:31:24 +0000 (Sat, 26 Feb 2005) $
005     *
006     * ====================================================================
007     *
008     * Copyright 2004 The Apache Software Foundation 
009     *
010     * Licensed under the Apache License, Version 2.0 (the "License");
011     * you may not use this file except in compliance with the License.
012     * You may obtain a copy of the License at
013     *
014     *     http://www.apache.org/licenses/LICENSE-2.0
015     *
016     * Unless required by applicable law or agreed to in writing, software
017     * distributed under the License is distributed on an "AS IS" BASIS,
018     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
019     * See the License for the specific language governing permissions and
020     * limitations under the License.
021     *
022     */
023    
024    package org.apache.commons.xmlio.out;
025    
026    import java.io.*;
027    
028    /**
029     * Adds XML export functionality to the underlying output stream. Formatting and
030     * encoding is done as straight forward as possible. <br>
031     * Everything you know better than this class must be done by you, e.g. you will
032     * have to tell <code>XMLOutputStreamWriter</code> where you wish to have
033     * newlines.In effect, no unexpected so called
034     * <em>intelligent</em> behavior is to be feared. Another effect is high speed.
035     * <br>
036     * <br>
037     * <em>Caution</em>: Do not forget to call {@link #flush} at the end of your
038     * exporting process as otherwise no data might be written.
039     *
040     * <em>Warning</em>: When using two byte encoding (e.g. UTF-16) underlying
041     * OutputStream can
042     * not savely be brought to string. Do <em>not</em> use
043     * {@link ByteArrayOutputStream} with two byte encoding, as XML declaration
044     * will be in single byte encoding (according to XML spec) and the rest will be
045     * in double byte totally confusing ByteArrayOutputStream encoding to string.
046     * <b>If you want to have string output use {@link XMLWriter} filtering 
047     * {@link StringWriter} or for convenience {@link XMLStringWriter}.</b>
048     *
049     */
050    public class XMLOutputStreamWriter extends XMLWriter {
051        /** Name of UTF-8 encoding  */
052        public static String ENCODING_UTF_8 = "UTF-8";
053        /** Name of UTF-16 encoding */
054        public static String ENCODING_UTF_16 = "UTF-16";
055        /** Name of ISO-8859-1 encoding */
056        public static String ENCODING_ISO_8859_1 = "ISO-8859-1";
057    
058        /** Name of standard encoding */
059        public static String ENCODING_STANDARD = ENCODING_UTF_8;
060        /** Alias for ISO-8859-1 encoding */
061        public static String ENCODING_ISO_LATIN1 = ENCODING_ISO_8859_1;
062    
063        protected OutputStream os;
064        protected String encodingName;
065    
066        /** Creates a new output stream writer for XML export.
067         * @param os the underlying output stream the XML is exported to
068         * @param encodingName name of the encoding used to write XML as well as
069         * for the XML declataration (e.g. UTF-8, ISO-8859-1, ...)
070         */
071        public XMLOutputStreamWriter(OutputStream os, String encodingName) throws UnsupportedEncodingException {
072            super(new OutputStreamWriter(os, encodingName));
073            this.encodingName = encodingName;
074            this.os = os;
075        }
076    
077        /** Creates a new output stream writer for XML export. Standard encoding
078         * will be used as found in {@link #ENCODING_STANDARD}, which usually is
079         * UTF-8.
080         * @param os the underlying output stream the XML is exported to
081         * @see #XMLOutputStreamWriter(OutputStream, String)
082         */
083        public XMLOutputStreamWriter(OutputStream os) throws UnsupportedEncodingException {
084            this(os, ENCODING_STANDARD);
085        }
086    
087        /** Gets the name of the encoding as it would be inserted into the
088         * XML declaration. {@link OutputStreamWriter#getEncoding} may return something less verbose.
089         * @see OutputStreamWriter#getEncoding
090         */
091        public String getEncodingName() {
092            return encodingName;
093        }
094    
095        /** Writes XML delcaration using version 1.0 and encoding specified in
096         * constructor.
097         * <em>Caution</em>: As XML declaration must be in plain text (no UNICODE)
098         * it will not be passed to writer, but directly to stream!
099         */
100        public void writeXMLDeclaration() throws IOException {
101            String xmlDecl = "<?xml version=\"1.0\" encoding=\"" + getEncodingName() + "\"?>\n";
102            byte[] xmlDeclBytes = xmlDecl.getBytes("US-ASCII");
103    
104            // flush to ensure correct sequence
105            flush();
106            os.write(xmlDeclBytes);
107        }
108    
109    }