8038310: Re-examine integration of extended Charsets
authorsherman
Thu, 28 May 2015 10:00:51 -0700
changeset 30818 56133cf1bf00
parent 30817 25cb1af9055f
child 30819 45d6fd3af6ac
child 30907 c064fa28311d
8038310: Re-examine integration of extended Charsets Summary: to use ServiceLoader to load the extended charsets Reviewed-by: alanb, mchung
jdk/src/java.base/share/classes/java/nio/charset/Charset.java
jdk/src/jdk.charsets/share/classes/META-INF/services/java.nio.charset.spi.CharsetProvider
--- a/jdk/src/java.base/share/classes/java/nio/charset/Charset.java	Thu May 28 09:55:32 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/nio/charset/Charset.java	Thu May 28 10:00:51 2015 -0700
@@ -30,6 +30,7 @@
 import java.nio.charset.spi.CharsetProvider;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -336,12 +337,10 @@
     //
     private static Iterator<CharsetProvider> providers() {
         return new Iterator<>() {
-
                 ClassLoader cl = ClassLoader.getSystemClassLoader();
                 ServiceLoader<CharsetProvider> sl =
                     ServiceLoader.load(CharsetProvider.class, cl);
                 Iterator<CharsetProvider> i = sl.iterator();
-
                 CharsetProvider next = null;
 
                 private boolean getNext() {
@@ -424,32 +423,36 @@
 
     /* The extended set of charsets */
     private static class ExtendedProviderHolder {
-        static final CharsetProvider extendedProvider = extendedProvider();
+        static final CharsetProvider[] extendedProviders = extendedProviders();
         // returns ExtendedProvider, if installed
-        private static CharsetProvider extendedProvider() {
-            return AccessController.doPrivileged(
-                       new PrivilegedAction<>() {
-                           public CharsetProvider run() {
-                                try {
-                                    Class<?> epc
-                                        = Class.forName("sun.nio.cs.ext.ExtendedCharsets");
-                                    return (CharsetProvider)epc.newInstance();
-                                } catch (ClassNotFoundException x) {
-                                    // Extended charsets not available
-                                    // (charsets.jar not present)
-                                } catch (InstantiationException |
-                                         IllegalAccessException x) {
-                                  throw new Error(x);
-                                }
-                                return null;
+        private static CharsetProvider[] extendedProviders() {
+            return AccessController.doPrivileged(new PrivilegedAction<>() {
+                    public CharsetProvider[] run() {
+                        CharsetProvider[] cps = new CharsetProvider[1];
+                        int n = 0;
+                        ServiceLoader<CharsetProvider> sl =
+                            ServiceLoader.loadInstalled(CharsetProvider.class);
+                        for (CharsetProvider cp : sl) {
+                            if (n + 1 > cps.length) {
+                                cps = Arrays.copyOf(cps, cps.length << 1);
                             }
-                        });
+                            cps[n++] = cp;
+                        }
+                        return n == cps.length ? cps : Arrays.copyOf(cps, n);
+                    }});
         }
     }
 
     private static Charset lookupExtendedCharset(String charsetName) {
-        CharsetProvider ecp = ExtendedProviderHolder.extendedProvider;
-        return (ecp != null) ? ecp.charsetForName(charsetName) : null;
+        if (!sun.misc.VM.isBooted())  // see lookupViaProviders()
+            return null;
+        CharsetProvider[] ecps = ExtendedProviderHolder.extendedProviders;
+        for (CharsetProvider cp : ecps) {
+            Charset cs = cp.charsetForName(charsetName);
+            if (cs != null)
+                return cs;
+        }
+        return null;
     }
 
     private static Charset lookup(String charsetName) {
@@ -576,9 +579,10 @@
                         new TreeMap<>(
                             ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER);
                     put(standardProvider.charsets(), m);
-                    CharsetProvider ecp = ExtendedProviderHolder.extendedProvider;
-                    if (ecp != null)
+                    CharsetProvider[] ecps = ExtendedProviderHolder.extendedProviders;
+                    for (CharsetProvider ecp :ecps) {
                         put(ecp.charsets(), m);
+                    }
                     for (Iterator<CharsetProvider> i = providers(); i.hasNext();) {
                         CharsetProvider cp = i.next();
                         put(cp.charsets(), m);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.charsets/share/classes/META-INF/services/java.nio.charset.spi.CharsetProvider	Thu May 28 10:00:51 2015 -0700
@@ -0,0 +1,2 @@
+# NIO charset SPI extended charset provider
+sun.nio.cs.ext.ExtendedCharsets