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
22package com.sun.org.apache.xml.internal.serialize;
23
24
25import com.sun.org.apache.xerces.internal.util.EncodingMap;
26import java.io.UnsupportedEncodingException;
27import java.util.Locale;
28import java.util.Map;
29import 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
46class 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}
131