1/* GENERATED SOURCE. DO NOT MODIFY. */
2// © 2016 and later: Unicode, Inc. and others.
3// License & terms of use: http://www.unicode.org/copyright.html#License
4/*
5 *******************************************************************************
6 * Copyright (C) 2015, International Business Machines Corporation and
7 * others. All Rights Reserved.
8 *******************************************************************************
9 */
10package android.icu.impl;
11
12import java.security.AccessController;
13import java.security.PrivilegedAction;
14
15
16/**
17 * This utility class is used for resolving a right ClassLoader from
18 * a given class. getClassLoader always returns a non-null ClassLoader
19 * even a class is loaded through the bootstrap class loader of JRE.
20 * @hide Only a subset of ICU is exposed in Android
21 */
22public class ClassLoaderUtil {
23
24    private static class BootstrapClassLoader extends ClassLoader {
25        BootstrapClassLoader() {
26            // Object.class.getClassLoader() may return null.
27            //
28            // On Android, the behavior of super(null) is not guaranteed,
29            // but Object.class.getClassLoader() actually returns the
30            // bootstrap class loader. Note that we probably do not reach
31            // this constructor on Android, because ClassLoaderUtil.getClassLoader()
32            // should get non-null ClassLoader before calling
33            // ClassLoaderUtil.getBootstrapClassLoader().
34            //
35            // On other common JREs (such as Oracle, OpenJDK),
36            // Object.class.getClassLoader() returns null, but
37            // super(null) is commonly used for accessing the bootstrap
38            // class loader.
39            super(Object.class.getClassLoader());
40        }
41    }
42
43    private static volatile ClassLoader BOOTSTRAP_CLASSLOADER;
44
45    /**
46     * Lazily create a singleton BootstrapClassLoader.
47     * This class loader might be necessary when ICU4J classes are
48     * initialized by bootstrap class loader.
49     *
50     * @return The BootStrapClassLoader singleton instance
51     */
52    private static ClassLoader getBootstrapClassLoader() {
53        if (BOOTSTRAP_CLASSLOADER == null) {
54            synchronized(ClassLoaderUtil.class) {
55                if (BOOTSTRAP_CLASSLOADER == null) {
56                    ClassLoader cl = null;
57                    if (System.getSecurityManager() != null) {
58                        cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
59                            @Override
60                            public BootstrapClassLoader run() {
61                                return new BootstrapClassLoader();
62                            }
63                        });
64                    } else {
65                        cl = new BootstrapClassLoader();
66                    }
67                    BOOTSTRAP_CLASSLOADER = cl;
68                }
69            }
70        }
71        return BOOTSTRAP_CLASSLOADER;
72    }
73
74
75    /**
76     * Returns the class loader used for loading the specified class.
77     * @param cls The class
78     * @return the class loader
79     */
80    public static ClassLoader getClassLoader(Class<?> cls) {
81        ClassLoader cl = cls.getClassLoader();
82        if (cl == null) {
83            cl = getClassLoader();
84        }
85        return cl;
86    }
87
88    /**
89     * Returns a fallback class loader.
90     * @return A class loader
91     */
92    public static ClassLoader getClassLoader() {
93        ClassLoader cl = Thread.currentThread().getContextClassLoader();
94        if (cl == null) {
95            cl = ClassLoader.getSystemClassLoader();
96            if (cl == null) {
97                // When this method is called for initializing a ICU4J class
98                // during bootstrap, cl might be still null (other than Android?).
99                // In this case, we want to use the bootstrap class loader.
100                cl = getBootstrapClassLoader();
101            }
102        }
103        return cl;
104    }
105}
106