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); }}); }
/** * Retrieves a charset for the given charset name. * * @return A charset object for the charset with the specified name, or * <code>null</code> if no such charset exists. * * @throws IllegalCharsetNameException if the name is illegal */ private static Charset charsetForName(String charsetName) { checkName (charsetName); // Try the default provider first // (so we don't need to load external providers unless really necessary) // if it is an exotic charset try loading the external providers. Charset cs = provider().charsetForName(charsetName); if (cs == null) { CharsetProvider[] providers = providers2(); for (int i = 0; i < providers.length; i++) { cs = providers[i].charsetForName(charsetName); if (cs != null) break; } } return cs; }
/** * We need to support multiple providers, reading them from * java.nio.charset.spi.CharsetProvider in the resource directory * META-INF/services. This returns the "extra" charset providers. */ private static CharsetProvider[] providers2() { if (providers == null) { try { Iterator i = ServiceFactory.lookupProviders(CharsetProvider.class); LinkedHashSet set = new LinkedHashSet(); while (i.hasNext()) set.add(i.next()); providers = new CharsetProvider[set.size()]; set.toArray(providers); } catch (Exception e) { throw new RuntimeException(e); } } return providers; }
/** * Returns an immutable case-insensitive map from canonical names to {@code Charset} instances. * If multiple charsets have the same canonical name, it is unspecified which is returned in * the map. This method may be slow. If you know which charset you're looking for, use * {@link #forName}. * @return an immutable case-insensitive map from canonical names to {@code Charset} instances */ public static SortedMap<String, Charset> availableCharsets() { // Start with a copy of the built-in charsets... TreeMap<String, Charset> charsets = new TreeMap<String, Charset>(String.CASE_INSENSITIVE_ORDER); for (String charsetName : NativeConverter.getAvailableCharsetNames()) { Charset charset = NativeConverter.charsetForName(charsetName); charsets.put(charset.name(), charset); } // Add all charsets provided by all charset providers... for (CharsetProvider charsetProvider : ServiceLoader.load(CharsetProvider.class, null)) { Iterator<Charset> it = charsetProvider.charsets(); while (it.hasNext()) { Charset cs = it.next(); // A CharsetProvider can't override a built-in Charset. if (!charsets.containsKey(cs.name())) { charsets.put(cs.name(), cs); } } } return Collections.unmodifiableSortedMap(charsets); }
private static Charset lookupViaProviders(final String charsetName) { // The runtime startup sequence looks up standard charsets as a // consequence of the VM's invocation of System.initializeSystemClass // in order to, e.g., set system properties and encode filenames. At // that point the application class loader has not been initialized, // however, so we can't look for providers because doing so will cause // that loader to be prematurely initialized with incomplete // information. // if (!sun.misc.VM.isBooted()) return null; if (gate.get() != null) // Avoid recursive provider lookups return null; try { gate.set(gate); return AccessController.doPrivileged( new PrivilegedAction<Charset>() { public Charset run() { for (Iterator<CharsetProvider> i = providers(); i.hasNext();) { CharsetProvider cp = i.next(); Charset cs = cp.charsetForName(charsetName); if (cs != null) return cs; } return null; } }); } finally { gate.set(null); } }
private static Charset lookupViaProviders(final String charsetName) { // The runtime startup sequence looks up standard charsets as a // consequence of the VM's invocation of System.initializeSystemClass // in order to, e.g., set system properties and encode filenames. At // that point the application class loader has not been initialized, // however, so we can't look for providers because doing so will cause // that loader to be prematurely initialized with incomplete // information. // if (!VM.isBooted()) return null; if (gate.get() != null) // Avoid recursive provider lookups return null; try { gate.set(gate); return AccessController.doPrivileged( new PrivilegedAction<>() { public Charset run() { for (Iterator<CharsetProvider> i = providers(); i.hasNext();) { CharsetProvider cp = i.next(); Charset cs = cp.charsetForName(charsetName); if (cs != null) return cs; } return null; } }); } finally { gate.set(null); } }
private static Charset lookupExtendedCharset(String charsetName) { if (!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 CharsetProvider provider() { String useIconv = SystemProperties.getProperty ("gnu.classpath.nio.charset.provider.iconv"); if (useIconv != null) return IconvProvider.provider(); return Provider.provider(); }
private static Charset lookupViaProviders(final String charsetName) { // The runtime startup sequence looks up standard charsets as a // consequence of the VM's invocation of System.initializeSystemClass // in order to, e.g., set system properties and encode filenames. At // that point the application class loader has not been initialized, // however, so we can't look for providers because doing so will cause // that loader to be prematurely initialized with incomplete // information. // if (!sun.misc.VM.isBooted()) return null; if (gate.get() != null) // Avoid recursive provider lookups return null; try { gate.set(gate); return (Charset)AccessController .doPrivileged(new PrivilegedAction() { public Object run() { for (Iterator i = providers(); i.hasNext();) { CharsetProvider cp = (CharsetProvider)i.next(); Charset cs = cp.charsetForName(charsetName); if (cs != null) return cs; } return null; } }); } finally { gate.set(null); } }
private static Charset lookupExtendedCharset(String charsetName) { CharsetProvider ecp = null; synchronized (extendedProviderLock) { if (!extendedProviderProbed) { probeExtendedProvider(); extendedProviderProbed = true; } ecp = extendedProvider; } return (ecp != null) ? ecp.charsetForName(charsetName) : null; }
private static Charset lookupViaProviders(final String charsetName) { // The runtime startup sequence looks up standard charsets as a // consequence of the VM's invocation of System.initializeSystemClass // in order to, e.g., set system properties and encode filenames. At // that point the application class loader has not been initialized, // however, so we can't look for providers because doing so will cause // that loader to be prematurely initialized with incomplete // information. // if (!sun.misc.VM.isBooted()) return null; if (gate.get() != null) // Avoid recursive provider lookups return null; try { gate.set(gate); return AccessController.doPrivileged( new PrivilegedAction<Charset>() { public Charset run() { for (Iterator i = providers(); i.hasNext();) { CharsetProvider cp = (CharsetProvider)i.next(); Charset cs = cp.charsetForName(charsetName); if (cs != null) return cs; } return null; } }); } finally { gate.set(null); } }
/** * Returns a {@code Charset} instance for the named charset. * * @param charsetName a charset name (either canonical or an alias) * @throws IllegalCharsetNameException * if the specified charset name is illegal. * @throws UnsupportedCharsetException * if the desired charset is not supported by this runtime. */ public static Charset forName(String charsetName) { // Is this charset in our cache? Charset cs; synchronized (CACHED_CHARSETS) { cs = CACHED_CHARSETS.get(charsetName); if (cs != null) { return cs; } } // Is this a built-in charset supported by ICU? if (charsetName == null) { throw new IllegalCharsetNameException(charsetName); } checkCharsetName(charsetName); cs = NativeConverter.charsetForName(charsetName); if (cs != null) { return cacheCharset(charsetName, cs); } // Does a configured CharsetProvider have this charset? for (CharsetProvider charsetProvider : ServiceLoader.load(CharsetProvider.class, null)) { cs = charsetProvider.charsetForName(charsetName); if (cs != null) { return cacheCharset(charsetName, cs); } } throw new UnsupportedCharsetException(charsetName); }
private static void addCharsets(CharsetProvider cp, TreeMap<String, Charset> charsets) { Iterator<Charset> it = cp.charsets(); while (it.hasNext()) { Charset cs = it.next(); // Only new charsets will be added if (!charsets.containsKey(cs.name())) { charsets.put(cs.name(), cs); } } }