1 /* 2 * Copyright (c) 2010, 2014, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4777124 6920545 6911753 27 * @summary Verify that all Charset subclasses are available through the API 28 */ 29 30 import java.io.File; 31 import java.io.FileInputStream; 32 import java.io.FileNotFoundException; 33 import java.io.IOException; 34 import java.nio.charset.Charset; 35 import java.security.AccessController; 36 import java.security.PrivilegedAction; 37 import java.util.Collection; 38 import java.util.HashSet; 39 import java.util.Iterator; 40 import java.util.Set; 41 import java.util.Vector; 42 import java.util.zip.ZipEntry; 43 import java.util.zip.ZipInputStream; 44 45 46 public class NIOCharsetAvailabilityTest { 47 48 public static void main(String[] args) throws Exception { 49 // build the set of all Charset subclasses in the 50 // two known charset implementation packages 51 Set charsets = new HashSet(); 52 addCharsets(charsets, "sun.nio.cs"); 53 addCharsets(charsets, "sun.nio.cs.ext"); 54 55 // remove the charsets that the API says are available 56 Collection availableCharsets = Charset.availableCharsets().values(); 57 Iterator iter = availableCharsets.iterator(); 58 while (iter.hasNext()) { 59 charsets.remove(((Charset) iter.next()).getClass()); 60 } 61 62 // remove the known pseudo-charsets that serve only to implement 63 // other charsets, but shouldn't be known to the public 64 charsets.remove(Class.forName("sun.nio.cs.Unicode")); 65 charsets.remove(Class.forName("sun.nio.cs.ext.ISO2022")); 66 charsets.remove(Class.forName("sun.nio.cs.ext.ISO2022_CN_GB")); 67 charsets.remove(Class.forName("sun.nio.cs.ext.ISO2022_CN_CNS")); 68 charsets.remove(Class.forName("sun.nio.cs.ext.JIS_X_0208_MS932")); 69 charsets.remove(Class.forName("sun.nio.cs.ext.JIS_X_0212_MS5022X")); 70 charsets.remove(Class.forName("sun.nio.cs.ext.JIS_X_0208_MS5022X")); 71 try { 72 charsets.remove(Class.forName("sun.nio.cs.ext.JIS_X_0208_Solaris")); 73 charsets.remove(Class.forName("sun.nio.cs.ext.JIS_X_0212_Solaris")); 74 } catch (ClassNotFoundException x) { 75 // these two might be moved into stdcs 76 charsets.remove(Class.forName("sun.nio.cs.JIS_X_0208_Solaris")); 77 charsets.remove(Class.forName("sun.nio.cs.JIS_X_0212_Solaris")); 78 } 79 80 // report the charsets that are implemented but not available 81 iter = charsets.iterator(); 82 while (iter.hasNext()) { 83 System.out.println("Unused Charset subclass: " + ((Class) iter.next()).getName()); 84 } 85 if (charsets.size() > 0) { 86 throw new RuntimeException(); 87 } 88 } 89 90 private static Vector classPathSegments = new Vector(); 91 92 private static void addCharsets(Set charsets, final String packageName) 93 throws Exception { 94 95 String classPath = AccessController.doPrivileged( 96 (PrivilegedAction<String>)() -> System.getProperty("sun.boot.class.path")); 97 String s = AccessController.doPrivileged( 98 (PrivilegedAction<String>)() -> System.getProperty("java.class.path")); 99 100 // Search combined system and application class path 101 if (s != null && s.length() != 0) { 102 classPath += File.pathSeparator + s; 103 } 104 while (classPath != null && classPath.length() != 0) { 105 int i = classPath.lastIndexOf(java.io.File.pathSeparatorChar); 106 String dir = classPath.substring(i + 1); 107 if (i == -1) { 108 classPath = null; 109 } else { 110 classPath = classPath.substring(0, i); 111 } 112 classPathSegments.insertElementAt(dir, 0); 113 } 114 115 String[] classList = (String[]) 116 java.security.AccessController.doPrivileged( 117 new java.security.PrivilegedAction() { 118 public Object run() { 119 return getClassList(packageName, ""); 120 } 121 }); 122 123 for (int i = 0; i < classList.length; i++) { 124 try { 125 Class clazz = Class.forName(packageName + "." + classList[i]); 126 Class superclazz = clazz.getSuperclass(); 127 while (superclazz != null && !superclazz.equals(Object.class)) { 128 if (superclazz.equals(Charset.class)) { 129 charsets.add(clazz); 130 break; 131 } else { 132 superclazz = superclazz.getSuperclass(); 133 } 134 } 135 } catch (ClassNotFoundException e) { 136 } 137 } 138 } 139 140 private static final char ZIPSEPARATOR = '/'; 141 142 /** 143 * Walk through CLASSPATH and find class list from a package. 144 * The class names start with prefix string 145 * @param package name, class name prefix 146 * @return class list in an array of String 147 */ 148 private static String[] getClassList(String pkgName, String prefix) { 149 Vector listBuffer = new Vector(); 150 String packagePath = pkgName.replace('.', File.separatorChar) 151 + File.separatorChar; 152 String zipPackagePath = pkgName.replace('.', ZIPSEPARATOR) 153 + ZIPSEPARATOR; 154 for (int i = 0; i < classPathSegments.size(); i++){ 155 String onePath = (String) classPathSegments.elementAt(i); 156 File f = new File(onePath); 157 if (!f.exists()) 158 continue; 159 if (f.isFile()) 160 scanFile(f, zipPackagePath, listBuffer, prefix); 161 else if (f.isDirectory()) { 162 String fullPath; 163 if (onePath.endsWith(File.separator)) 164 fullPath = onePath + packagePath; 165 else 166 fullPath = onePath + File.separatorChar + packagePath; 167 File dir = new File(fullPath); 168 if (dir.exists() && dir.isDirectory()) 169 scanDir(dir, listBuffer, prefix); 170 } 171 } 172 String[] classNames = new String[listBuffer.size()]; 173 listBuffer.copyInto(classNames); 174 return classNames; 175 } 176 177 private static void addClass (String className, Vector listBuffer, String prefix) { 178 if (className != null && className.startsWith(prefix) 179 && !listBuffer.contains(className)) 180 listBuffer.addElement(className); 181 } 182 183 private static String midString(String str, String pre, String suf) { 184 String midStr; 185 if (str.startsWith(pre) && str.endsWith(suf)) 186 midStr = str.substring(pre.length(), str.length() - suf.length()); 187 else 188 midStr = null; 189 return midStr; 190 } 191 192 private static void scanDir(File dir, Vector listBuffer, String prefix) { 193 String[] fileList = dir.list(); 194 for (int i = 0; i < fileList.length; i++) { 195 addClass(midString(fileList[i], "", ".class"), listBuffer, prefix); 196 } 197 } 198 199 private static void scanFile(File f, String packagePath, Vector listBuffer, 200 String prefix) { 201 try { 202 ZipInputStream zipFile = new ZipInputStream(new FileInputStream(f)); 203 ZipEntry entry; 204 while ((entry = zipFile.getNextEntry()) != null) { 205 String eName = entry.getName(); 206 if (eName.startsWith(packagePath)) { 207 if (eName.endsWith(".class")) { 208 addClass(midString(eName, packagePath, ".class"), 209 listBuffer, prefix); 210 } 211 } 212 } 213 } catch (FileNotFoundException e) { 214 System.out.println("file not found:" + e); 215 } catch (IOException e) { 216 System.out.println("file IO Exception:" + e); 217 } catch (Exception e) { 218 System.out.println("Exception:" + e); 219 } 220 } 221 }