1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.xml.internal.serialize;
  23 
  24 import java.io.OutputStream;
  25 import java.io.OutputStreamWriter;
  26 import java.io.UnsupportedEncodingException;
  27 import java.io.Writer;
  28 import com.sun.org.apache.xerces.internal.util.EncodingMap;
  29 import java.nio.charset.Charset;
  30 import java.nio.charset.CharsetEncoder;
  31 
  32 /**
  33  * This class represents an encoding.
  34  *
  35  * @deprecated As of JDK 9, Xerces 2.9.0, Xerces DOM L3 Serializer implementation
  36  * is replaced by that of Xalan. Main class
  37  * {@link com.sun.org.apache.xml.internal.serialize.DOMSerializerImpl} is replaced
  38  * by {@link com.sun.org.apache.xml.internal.serializer.dom3.LSSerializerImpl}.
  39  */
  40 public class EncodingInfo {
  41 
  42     // name of encoding as registered with IANA;
  43     // preferably a MIME name, but aliases are fine too.
  44     String ianaName;
  45     String javaName;
  46     int lastPrintable;
  47 
  48     // The CharsetEncoder with which we test unusual characters.
  49     CharsetEncoder fCharsetEncoder = null;
  50 
  51     // Is the charset encoder usable or available.
  52     boolean fHaveTriedCharsetEncoder = false;
  53 
  54     /**
  55      * Creates new <code>EncodingInfo</code> instance.
  56      */
  57     public EncodingInfo(String ianaName, String javaName, int lastPrintable) {
  58         this.ianaName = ianaName;
  59         this.javaName = EncodingMap.getIANA2JavaMapping(ianaName);
  60         this.lastPrintable = lastPrintable;
  61     }
  62 
  63     /**
  64      * Returns a MIME charset name of this encoding.
  65      */
  66     public String getIANAName() {
  67         return this.ianaName;
  68     }
  69 
  70     /**
  71      * Returns a writer for this encoding based on
  72      * an output stream.
  73      *
  74      * @return A suitable writer
  75      * @exception UnsupportedEncodingException There is no convertor
  76      *  to support this encoding
  77      */
  78     public Writer getWriter(OutputStream output)
  79         throws UnsupportedEncodingException {
  80         // this should always be true!
  81         if (javaName != null)
  82             return new OutputStreamWriter(output, javaName);
  83         javaName = EncodingMap.getIANA2JavaMapping(ianaName);
  84         if(javaName == null)
  85             // use UTF-8 as preferred encoding
  86             return new OutputStreamWriter(output, "UTF8");
  87         return new OutputStreamWriter(output, javaName);
  88     }
  89 
  90     /**
  91      * Checks whether the specified character is printable or not in this encoding.
  92      *
  93      * @param ch a code point (0-0x10ffff)
  94      */
  95     public boolean isPrintable(char ch) {
  96         if (ch <= this.lastPrintable) {
  97             return true;
  98         }
  99         return isPrintable0(ch);
 100     }
 101 
 102     /**
 103      * Checks whether the specified character is printable or not in this encoding.
 104      * This method accomplishes this using a java.nio.CharsetEncoder. If NIO isn't
 105      * available it will attempt use a sun.io.CharToByteConverter.
 106      *
 107      * @param ch a code point (0-0x10ffff)
 108      */
 109     private boolean isPrintable0(char ch) {
 110 
 111         // Attempt to get a CharsetEncoder for this encoding.
 112         if (fCharsetEncoder == null && !fHaveTriedCharsetEncoder) {
 113             // try and create the CharsetEncoder
 114             try {
 115                 Charset charset = java.nio.charset.Charset.forName(javaName);
 116                 if (charset.canEncode()) {
 117                     fCharsetEncoder = charset.newEncoder();
 118                 }
 119                 // This charset cannot be used for encoding, don't try it again...
 120                 else {
 121                     fHaveTriedCharsetEncoder = true;
 122                 }
 123             }
 124             catch (Exception e) {
 125                 // don't try it again...
 126                 fHaveTriedCharsetEncoder = true;
 127             }
 128         }
 129         // Attempt to use the CharsetEncoder to determine whether the character is printable.
 130         if (fCharsetEncoder != null) {
 131             try {
 132                 return fCharsetEncoder.canEncode(ch);
 133             }
 134             catch (Exception e) {
 135                 // obviously can't use this charset encoder; possibly a JDK bug
 136                 fCharsetEncoder = null;
 137                 fHaveTriedCharsetEncoder = false;
 138             }
 139         }
 140 
 141         return false;
 142     }
 143 
 144     // is this an encoding name recognized by this JDK?
 145     // if not, will throw UnsupportedEncodingException
 146     public static void testJavaEncodingName(String name)  throws UnsupportedEncodingException {
 147         final byte [] bTest = {(byte)'v', (byte)'a', (byte)'l', (byte)'i', (byte)'d'};
 148         String s = new String(bTest, name);
 149     }
 150 
 151 }