1 /*
   2  * Copyright (c) 2015, 2017 Oracle and/or its affiliates. All rights reserved.
   3  */
   4 /*
   5  * Licensed to the Apache Software Foundation (ASF) under one or more
   6  * contributor license agreements.  See the NOTICE file distributed with
   7  * this work for additional information regarding copyright ownership.
   8  * The ASF licenses this file to You under the Apache License, Version 2.0
   9  * (the "License"); you may not use this file except in compliance with
  10  * the License.  You may obtain a copy of the License at
  11  *
  12  *      http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 
  21 
  22 package com.sun.org.apache.xml.internal.serialize;
  23 
  24 
  25 import com.sun.org.apache.xerces.internal.util.EncodingMap;
  26 import java.io.UnsupportedEncodingException;
  27 import java.util.Locale;
  28 import java.util.Map;
  29 import java.util.concurrent.ConcurrentHashMap;
  30 
  31 
  32 /**
  33  * Provides information about encodings. Depends on the Java runtime
  34  * to provides writers for the different encodings, but can be used
  35  * to override encoding names and provide the last printable character
  36  * for each encoding.
  37  *
  38  * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a>
  39  *
  40  * @deprecated As of JDK 9, Xerces 2.9.0, Xerces DOM L3 Serializer implementation
  41  * is replaced by that of Xalan. Main class
  42  * {@link com.sun.org.apache.xml.internal.serialize.DOMSerializerImpl} is replaced
  43  * by {@link com.sun.org.apache.xml.internal.serializer.dom3.LSSerializerImpl}.
  44  */
  45 @Deprecated
  46 class Encodings
  47 {
  48 
  49 
  50     /**
  51      * The last printable character for unknown encodings.
  52      */
  53     static final int DEFAULT_LAST_PRINTABLE = 0x7F;
  54 
  55     // last printable character for Unicode-compatible encodings
  56     static final int LAST_PRINTABLE_UNICODE = 0xffff;
  57     // unicode-compliant encodings; can express plane 0
  58     static final String[] UNICODE_ENCODINGS = {
  59         "Unicode", "UnicodeBig", "UnicodeLittle", "GB2312", "UTF8", "UTF-16",
  60     };
  61     // default (Java) encoding if none supplied:
  62     static final String DEFAULT_ENCODING = "UTF8";
  63 
  64     // note that the size of this Map
  65     // is bounded by the number of encodings recognized by EncodingMap;
  66     // therefore it poses no static mutability risk.
  67     private static final Map<String, EncodingInfo> _encodings = new ConcurrentHashMap();
  68 
  69     /**
  70      * @param encoding a MIME charset name, or null.
  71      */
  72     static EncodingInfo getEncodingInfo(String encoding, boolean allowJavaNames) throws UnsupportedEncodingException {
  73         EncodingInfo eInfo = null;
  74         if (encoding == null) {
  75             if((eInfo = _encodings.get(DEFAULT_ENCODING)) != null)
  76                 return eInfo;
  77             eInfo = new EncodingInfo(EncodingMap.getJava2IANAMapping(DEFAULT_ENCODING), DEFAULT_ENCODING, LAST_PRINTABLE_UNICODE);
  78             _encodings.put(DEFAULT_ENCODING, eInfo);
  79             return eInfo;
  80         }
  81         // need to convert it to upper case:
  82         encoding = encoding.toUpperCase(Locale.ENGLISH);
  83         String jName = EncodingMap.getIANA2JavaMapping(encoding);
  84         if(jName == null) {
  85             // see if the encoding passed in is a Java encoding name.
  86             if(allowJavaNames ) {
  87                 EncodingInfo.testJavaEncodingName(encoding);
  88                 if((eInfo = _encodings.get(encoding)) != null)
  89                     return eInfo;
  90                 // is it known to be unicode-compliant?
  91                 int i=0;
  92                 for(; i<UNICODE_ENCODINGS.length; i++) {
  93                     if(UNICODE_ENCODINGS[i].equalsIgnoreCase(encoding)) {
  94                         eInfo = new EncodingInfo(EncodingMap.getJava2IANAMapping(encoding), encoding, LAST_PRINTABLE_UNICODE);
  95                         break;
  96                     }
  97                 }
  98                 if(i == UNICODE_ENCODINGS.length) {
  99                     eInfo = new EncodingInfo(EncodingMap.getJava2IANAMapping(encoding), encoding, DEFAULT_LAST_PRINTABLE);
 100                 }
 101                 _encodings.put(encoding, eInfo);
 102                 return eInfo;
 103             } else {
 104                 throw new UnsupportedEncodingException(encoding);
 105             }
 106         }
 107         if ((eInfo = _encodings.get(jName)) != null)
 108             return eInfo;
 109         // have to create one...
 110         // is it known to be unicode-compliant?
 111         int i=0;
 112         for(; i<UNICODE_ENCODINGS.length; i++) {
 113             if(UNICODE_ENCODINGS[i].equalsIgnoreCase(jName)) {
 114                 eInfo = new EncodingInfo(encoding, jName, LAST_PRINTABLE_UNICODE);
 115                 break;
 116             }
 117         }
 118         if(i == UNICODE_ENCODINGS.length) {
 119             eInfo = new EncodingInfo(encoding, jName, DEFAULT_LAST_PRINTABLE);
 120         }
 121         _encodings.put(jName, eInfo);
 122         return eInfo;
 123     }
 124 
 125     static final String JIS_DANGER_CHARS
 126     = "\\\u007e\u007f\u00a2\u00a3\u00a5\u00ac"
 127     +"\u2014\u2015\u2016\u2026\u203e\u203e\u2225\u222f\u301c"
 128     +"\uff3c\uff5e\uffe0\uffe1\uffe2\uffe3";
 129 
 130 }