1 /*
2 * Copyright (c) 2000, 2013, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
376 throw new UnsupportedOperationException();
377 }
378
379 };
380 }
381
382 // Thread-local gate to prevent recursive provider lookups
383 private static ThreadLocal<ThreadLocal<?>> gate =
384 new ThreadLocal<ThreadLocal<?>>();
385
386 private static Charset lookupViaProviders(final String charsetName) {
387
388 // The runtime startup sequence looks up standard charsets as a
389 // consequence of the VM's invocation of System.initializeSystemClass
390 // in order to, e.g., set system properties and encode filenames. At
391 // that point the application class loader has not been initialized,
392 // however, so we can't look for providers because doing so will cause
393 // that loader to be prematurely initialized with incomplete
394 // information.
395 //
396 if (!sun.misc.VM.isBooted())
397 return null;
398
399 if (gate.get() != null)
400 // Avoid recursive provider lookups
401 return null;
402 try {
403 gate.set(gate);
404
405 return AccessController.doPrivileged(
406 new PrivilegedAction<>() {
407 public Charset run() {
408 for (Iterator<CharsetProvider> i = providers();
409 i.hasNext();) {
410 CharsetProvider cp = i.next();
411 Charset cs = cp.charsetForName(charsetName);
412 if (cs != null)
413 return cs;
414 }
415 return null;
416 }
427 // returns ExtendedProvider, if installed
428 private static CharsetProvider[] extendedProviders() {
429 return AccessController.doPrivileged(new PrivilegedAction<>() {
430 public CharsetProvider[] run() {
431 CharsetProvider[] cps = new CharsetProvider[1];
432 int n = 0;
433 ServiceLoader<CharsetProvider> sl =
434 ServiceLoader.loadInstalled(CharsetProvider.class);
435 for (CharsetProvider cp : sl) {
436 if (n + 1 > cps.length) {
437 cps = Arrays.copyOf(cps, cps.length << 1);
438 }
439 cps[n++] = cp;
440 }
441 return n == cps.length ? cps : Arrays.copyOf(cps, n);
442 }});
443 }
444 }
445
446 private static Charset lookupExtendedCharset(String charsetName) {
447 if (!sun.misc.VM.isBooted()) // see lookupViaProviders()
448 return null;
449 CharsetProvider[] ecps = ExtendedProviderHolder.extendedProviders;
450 for (CharsetProvider cp : ecps) {
451 Charset cs = cp.charsetForName(charsetName);
452 if (cs != null)
453 return cs;
454 }
455 return null;
456 }
457
458 private static Charset lookup(String charsetName) {
459 if (charsetName == null)
460 throw new IllegalArgumentException("Null charset name");
461 Object[] a;
462 if ((a = cache1) != null && charsetName.equals(a[0]))
463 return (Charset)a[1];
464 // We expect most programs to use one Charset repeatedly.
465 // We convey a hint to this effect to the VM by putting the
466 // level 1 cache miss code in a separate method.
467 return lookup2(charsetName);
468 }
469
|
1 /*
2 * Copyright (c) 2000, 2015, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
376 throw new UnsupportedOperationException();
377 }
378
379 };
380 }
381
382 // Thread-local gate to prevent recursive provider lookups
383 private static ThreadLocal<ThreadLocal<?>> gate =
384 new ThreadLocal<ThreadLocal<?>>();
385
386 private static Charset lookupViaProviders(final String charsetName) {
387
388 // The runtime startup sequence looks up standard charsets as a
389 // consequence of the VM's invocation of System.initializeSystemClass
390 // in order to, e.g., set system properties and encode filenames. At
391 // that point the application class loader has not been initialized,
392 // however, so we can't look for providers because doing so will cause
393 // that loader to be prematurely initialized with incomplete
394 // information.
395 //
396 // We must also guard against beeing called from the sun.misc.Launcher
397 // class initializer because in that case the bootstrap URLClassPath in
398 // the Launcher isn't initialized which is required by the ServiceLoader
399 // we use.
400 if (!sun.misc.VM.isBooted() ||
401 sun.misc.Launcher.getBootstrapClassPath() == null)
402 return null;
403
404 if (gate.get() != null)
405 // Avoid recursive provider lookups
406 return null;
407 try {
408 gate.set(gate);
409
410 return AccessController.doPrivileged(
411 new PrivilegedAction<>() {
412 public Charset run() {
413 for (Iterator<CharsetProvider> i = providers();
414 i.hasNext();) {
415 CharsetProvider cp = i.next();
416 Charset cs = cp.charsetForName(charsetName);
417 if (cs != null)
418 return cs;
419 }
420 return null;
421 }
432 // returns ExtendedProvider, if installed
433 private static CharsetProvider[] extendedProviders() {
434 return AccessController.doPrivileged(new PrivilegedAction<>() {
435 public CharsetProvider[] run() {
436 CharsetProvider[] cps = new CharsetProvider[1];
437 int n = 0;
438 ServiceLoader<CharsetProvider> sl =
439 ServiceLoader.loadInstalled(CharsetProvider.class);
440 for (CharsetProvider cp : sl) {
441 if (n + 1 > cps.length) {
442 cps = Arrays.copyOf(cps, cps.length << 1);
443 }
444 cps[n++] = cp;
445 }
446 return n == cps.length ? cps : Arrays.copyOf(cps, n);
447 }});
448 }
449 }
450
451 private static Charset lookupExtendedCharset(String charsetName) {
452 if (!sun.misc.VM.isBooted() || // see lookupViaProviders()
453 sun.misc.Launcher.getBootstrapClassPath() == null)
454 return null;
455 CharsetProvider[] ecps = ExtendedProviderHolder.extendedProviders;
456 if (ecps == null) return null; // protect against recursive invocation
457 for (CharsetProvider cp : ecps) {
458 Charset cs = cp.charsetForName(charsetName);
459 if (cs != null)
460 return cs;
461 }
462 return null;
463 }
464
465 private static Charset lookup(String charsetName) {
466 if (charsetName == null)
467 throw new IllegalArgumentException("Null charset name");
468 Object[] a;
469 if ((a = cache1) != null && charsetName.equals(a[0]))
470 return (Charset)a[1];
471 // We expect most programs to use one Charset repeatedly.
472 // We convey a hint to this effect to the VM by putting the
473 // level 1 cache miss code in a separate method.
474 return lookup2(charsetName);
475 }
476
|