1/*
2 * Copyright (c) 2006, 2012, 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
23 * questions.
24 */
25package com.sun.beans.finder;
26
27import static sun.reflect.misc.ReflectUtil.checkPackageAccess;
28
29/**
30 * This is utility class that provides {@code static} methods
31 * to find a class with the specified name using the specified class loader.
32 *
33 * @since 1.7
34 *
35 * @author Sergey A. Malenkov
36 */
37public final class ClassFinder {
38
39    /**
40     * Returns the {@code Class} object associated
41     * with the class or interface with the given string name,
42     * using the default class loader.
43     * <p>
44     * The {@code name} can denote an array class
45     * (see {@link Class#getName} for details).
46     *
47     * @param name  fully qualified name of the desired class
48     * @return class object representing the desired class
49     *
50     * @throws ClassNotFoundException  if the class cannot be located
51     *                                 by the specified class loader
52     *
53     * @see Class#forName(String)
54     * @see Class#forName(String,boolean,ClassLoader)
55     * @see ClassLoader#getSystemClassLoader()
56     * @see Thread#getContextClassLoader()
57     */
58    public static Class<?> findClass(String name) throws ClassNotFoundException {
59        checkPackageAccess(name);
60        try {
61            ClassLoader loader = Thread.currentThread().getContextClassLoader();
62            if (loader == null) {
63                // can be null in IE (see 6204697)
64                loader = ClassLoader.getSystemClassLoader();
65            }
66            if (loader != null) {
67                return Class.forName(name, false, loader);
68            }
69
70        } catch (ClassNotFoundException exception) {
71            // use current class loader instead
72        } catch (SecurityException exception) {
73            // use current class loader instead
74        }
75        return Class.forName(name);
76    }
77
78    /**
79     * Returns the {@code Class} object associated with
80     * the class or interface with the given string name,
81     * using the given class loader.
82     * <p>
83     * The {@code name} can denote an array class
84     * (see {@link Class#getName} for details).
85     * <p>
86     * If the parameter {@code loader} is null,
87     * the class is loaded through the default class loader.
88     *
89     * @param name    fully qualified name of the desired class
90     * @param loader  class loader from which the class must be loaded
91     * @return class object representing the desired class
92     *
93     * @throws ClassNotFoundException  if the class cannot be located
94     *                                 by the specified class loader
95     *
96     * @see #findClass(String,ClassLoader)
97     * @see Class#forName(String,boolean,ClassLoader)
98     */
99    public static Class<?> findClass(String name, ClassLoader loader) throws ClassNotFoundException {
100        checkPackageAccess(name);
101        if (loader != null) {
102            try {
103                return Class.forName(name, false, loader);
104            } catch (ClassNotFoundException exception) {
105                // use default class loader instead
106            } catch (SecurityException exception) {
107                // use default class loader instead
108            }
109        }
110        return findClass(name);
111    }
112
113    /**
114     * Returns the {@code Class} object associated
115     * with the class or interface with the given string name,
116     * using the default class loader.
117     * <p>
118     * The {@code name} can denote an array class
119     * (see {@link Class#getName} for details).
120     * <p>
121     * This method can be used to obtain
122     * any of the {@code Class} objects
123     * representing {@code void} or primitive Java types:
124     * {@code char}, {@code byte}, {@code short},
125     * {@code int}, {@code long}, {@code float},
126     * {@code double} and {@code boolean}.
127     *
128     * @param name  fully qualified name of the desired class
129     * @return class object representing the desired class
130     *
131     * @throws ClassNotFoundException  if the class cannot be located
132     *                                 by the specified class loader
133     *
134     * @see #resolveClass(String,ClassLoader)
135     */
136    public static Class<?> resolveClass(String name) throws ClassNotFoundException {
137        return resolveClass(name, null);
138    }
139
140    /**
141     * Returns the {@code Class} object associated with
142     * the class or interface with the given string name,
143     * using the given class loader.
144     * <p>
145     * The {@code name} can denote an array class
146     * (see {@link Class#getName} for details).
147     * <p>
148     * If the parameter {@code loader} is null,
149     * the class is loaded through the default class loader.
150     * <p>
151     * This method can be used to obtain
152     * any of the {@code Class} objects
153     * representing {@code void} or primitive Java types:
154     * {@code char}, {@code byte}, {@code short},
155     * {@code int}, {@code long}, {@code float},
156     * {@code double} and {@code boolean}.
157     *
158     * @param name    fully qualified name of the desired class
159     * @param loader  class loader from which the class must be loaded
160     * @return class object representing the desired class
161     *
162     * @throws ClassNotFoundException  if the class cannot be located
163     *                                 by the specified class loader
164     *
165     * @see #findClass(String,ClassLoader)
166     * @see PrimitiveTypeMap#getType(String)
167     */
168    public static Class<?> resolveClass(String name, ClassLoader loader) throws ClassNotFoundException {
169        Class<?> type = PrimitiveTypeMap.getType(name);
170        return (type == null)
171                ? findClass(name, loader)
172                : type;
173    }
174
175    /**
176     * Disable instantiation.
177     */
178    private ClassFinder() {
179    }
180}
181