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