1/*
2 * Copyright (c) 2012, 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 jdk.internal.util.xml.impl;
27
28import java.io.BufferedOutputStream;
29import java.io.IOException;
30import java.io.OutputStream;
31import java.io.OutputStreamWriter;
32import java.io.UnsupportedEncodingException;
33import java.io.Writer;
34import java.nio.charset.Charset;
35import java.nio.charset.CharsetEncoder;
36import jdk.internal.util.xml.XMLStreamException;
37
38/**
39 *
40 * @author huizwang
41 */
42public class XMLWriter {
43
44    private Writer _writer;
45    /**
46     * In some cases, this charset encoder is used to determine if a char is
47     * encodable by underlying writer. For example, an 8-bit char from the
48     * extended ASCII set is not encodable by 7-bit ASCII encoder. Unencodable
49     * chars are escaped using XML numeric entities.
50     */
51    private CharsetEncoder _encoder = null;
52
53    public XMLWriter(OutputStream os, String encoding, Charset cs) throws XMLStreamException {
54        _encoder = cs.newEncoder();
55        try {
56            _writer = getWriter(os, encoding, cs);
57        } catch (UnsupportedEncodingException ex) {
58            throw new XMLStreamException(ex);
59        }
60
61    }
62
63    public boolean canEncode(char ch) {
64        if (_encoder == null) {
65            return false;
66        }
67        return (_encoder.canEncode(ch));
68    }
69
70    public void write(String s)
71            throws XMLStreamException {
72        try {
73            _writer.write(s.toCharArray());
74//            _writer.write(s.getBytes(Charset.forName(_encoding)));
75        } catch (IOException e) {
76            throw new XMLStreamException("I/O error", e);
77        }
78    }
79
80    public void write(String str, int off, int len)
81            throws XMLStreamException {
82        try {
83            _writer.write(str, off, len);
84        } catch (IOException e) {
85            throw new XMLStreamException("I/O error", e);
86        }
87
88    }
89
90    public void write(char[] cbuf, int off, int len)
91            throws XMLStreamException {
92        try {
93            _writer.write(cbuf, off, len);
94        } catch (IOException e) {
95            throw new XMLStreamException("I/O error", e);
96        }
97
98    }
99
100    void write(int b)
101            throws XMLStreamException {
102        try {
103            _writer.write(b);
104        } catch (IOException e) {
105            throw new XMLStreamException("I/O error", e);
106        }
107    }
108
109    void flush() throws XMLStreamException {
110        try {
111            _writer.flush();
112        } catch (IOException ex) {
113            throw new XMLStreamException(ex);
114        }
115    }
116
117    void close() throws XMLStreamException {
118        try {
119            _writer.close();
120        } catch (IOException ex) {
121            throw new XMLStreamException(ex);
122        }
123    }
124
125    private void nl() throws XMLStreamException {
126        String lineEnd = System.getProperty("line.separator");
127        try {
128            _writer.write(lineEnd);
129        } catch (IOException e) {
130            throw new XMLStreamException("I/O error", e);
131        }
132    }
133
134    /**
135     * Returns a writer for the specified encoding based on an output stream.
136     *
137     * @param output The output stream
138     * @param encoding The encoding
139     * @return A suitable writer
140     * @throws UnsupportedEncodingException There is no convertor to support
141     * this encoding
142     */
143    private Writer getWriter(OutputStream output, String encoding, Charset cs)
144        throws XMLStreamException, UnsupportedEncodingException
145    {
146        if (cs != null) {
147            return (new OutputStreamWriter(new BufferedOutputStream(output), cs));
148        }
149
150        return new OutputStreamWriter(new BufferedOutputStream(output), encoding);
151    }
152}
153