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  * @LastModified: Oct 2017
  46  */
  47 @Deprecated
  48 class Encodings
  49 {
  50 
  51 
  52     /**
  53      * The last printable character for unknown encodings.
  54      */
  55     static final int DEFAULT_LAST_PRINTABLE = 0x7F;
  56 
  57     // last printable character for Unicode-compatible encodings
  58     static final int LAST_PRINTABLE_UNICODE = 0xffff;
  59     // unicode-compliant encodings; can express plane 0
  60     static final String[] UNICODE_ENCODINGS = {
  61         "Unicode", "UnicodeBig", "UnicodeLittle", "GB2312", "UTF8", "UTF-16",
  62     };
  63     // default (Java) encoding if none supplied:
  64     static final String DEFAULT_ENCODING = "UTF8";
  65 
  66     // note that the size of this Map
  67     // is bounded by the number of encodings recognized by EncodingMap;
  68     // therefore it poses no static mutability risk.
  69     private static final Map<String, EncodingInfo> _encodings = new ConcurrentHashMap<>();
  70 
  71     /**
  72      * @param encoding a MIME charset name, or null.
  73      */
  74     static EncodingInfo getEncodingInfo(String encoding, boolean allowJavaNames) throws UnsupportedEncodingException {
  75         EncodingInfo eInfo = null;
  76         if (encoding == null) {
  77             if((eInfo = _encodings.get(DEFAULT_ENCODING)) != null)
  78                 return eInfo;
  79             eInfo = new EncodingInfo(EncodingMap.getJava2IANAMapping(DEFAULT_ENCODING), DEFAULT_ENCODING, LAST_PRINTABLE_UNICODE);
  80             _encodings.put(DEFAULT_ENCODING, eInfo);
  81             return eInfo;
  82         }
  83         // need to convert it to upper case:
  84         encoding = encoding.toUpperCase(Locale.ENGLISH);
  85         String jName = EncodingMap.getIANA2JavaMapping(encoding);
  86         if(jName == null) {
  87             // see if the encoding passed in is a Java encoding name.
  88             if(allowJavaNames ) {
  89                 EncodingInfo.testJavaEncodingName(encoding);
  90                 if((eInfo = _encodings.get(encoding)) != null)
  91                     return eInfo;
  92                 // is it known to be unicode-compliant?
  93                 int i=0;
  94                 for(; i<UNICODE_ENCODINGS.length; i++) {
  95                     if(UNICODE_ENCODINGS[i].equalsIgnoreCase(encoding)) {
  96                         eInfo = new EncodingInfo(EncodingMap.getJava2IANAMapping(encoding), encoding, LAST_PRINTABLE_UNICODE);
  97                         break;
  98                     }
  99                 }
 100                 if(i == UNICODE_ENCODINGS.length) {
 101                     eInfo = new EncodingInfo(EncodingMap.getJava2IANAMapping(encoding), encoding, DEFAULT_LAST_PRINTABLE);
 102                 }
 103                 _encodings.put(encoding, eInfo);
 104                 return eInfo;
 105             } else {
 106                 throw new UnsupportedEncodingException(encoding);
 107             }
 108         }
 109         if ((eInfo = _encodings.get(jName)) != null)
 110             return eInfo;
 111         // have to create one...
 112         // is it known to be unicode-compliant?
 113         int i=0;
 114         for(; i<UNICODE_ENCODINGS.length; i++) {
 115             if(UNICODE_ENCODINGS[i].equalsIgnoreCase(jName)) {
 116                 eInfo = new EncodingInfo(encoding, jName, LAST_PRINTABLE_UNICODE);
 117                 break;
 118             }
 119         }
 120         if(i == UNICODE_ENCODINGS.length) {
 121             eInfo = new EncodingInfo(encoding, jName, DEFAULT_LAST_PRINTABLE);
 122         }
 123         _encodings.put(jName, eInfo);
 124         return eInfo;
 125     }
 126 
 127     static final String JIS_DANGER_CHARS
 128     = "\\\u007e\u007f\u00a2\u00a3\u00a5\u00ac"
 129     +"\u2014\u2015\u2016\u2026\u203e\u203e\u2225\u222f\u301c"
 130     +"\uff3c\uff5e\uffe0\uffe1\uffe2\uffe3";
 131 
 132 }