1
16 package io.jsonwebtoken.lang;
17
18 import java.io.InputStream;
19 import java.lang.reflect.Constructor;
20
21
24 public final class Classes {
25
26 private static final Classes INSTANCE = new Classes();
27
28 private Classes() {}
29
30
33 private static final ClassLoaderAccessor THREAD_CL_ACCESSOR = new ExceptionIgnoringAccessor() {
34 @Override
35 protected ClassLoader doGetClassLoader() throws Throwable {
36 return Thread.currentThread().getContextClassLoader();
37 }
38 };
39
40
43 private static final ClassLoaderAccessor CLASS_CL_ACCESSOR = new ExceptionIgnoringAccessor() {
44 @Override
45 protected ClassLoader doGetClassLoader() throws Throwable {
46 return Classes.class.getClassLoader();
47 }
48 };
49
50
53 private static final ClassLoaderAccessor SYSTEM_CL_ACCESSOR = new ExceptionIgnoringAccessor() {
54 @Override
55 protected ClassLoader doGetClassLoader() throws Throwable {
56 return ClassLoader.getSystemClassLoader();
57 }
58 };
59
60
72 public static Class forName(String fqcn) throws UnknownClassException {
73
74 Class clazz = THREAD_CL_ACCESSOR.loadClass(fqcn);
75
76 if (clazz == null) {
77 clazz = CLASS_CL_ACCESSOR.loadClass(fqcn);
78 }
79
80 if (clazz == null) {
81 clazz = SYSTEM_CL_ACCESSOR.loadClass(fqcn);
82 }
83
84 if (clazz == null) {
85 String msg = "Unable to load class named [" + fqcn + "] from the thread context, current, or " +
86 "system/application ClassLoaders. All heuristics have been exhausted. Class could not be found.";
87
88 if (fqcn != null && fqcn.startsWith("com.stormpath.sdk.impl")) {
89 msg += " Have you remembered to include the stormpath-sdk-impl .jar in your runtime classpath?";
90 }
91
92 throw new UnknownClassException(msg);
93 }
94
95 return clazz;
96 }
97
98
110 public static InputStream getResourceAsStream(String name) {
111
112 InputStream is = THREAD_CL_ACCESSOR.getResourceStream(name);
113
114 if (is == null) {
115 is = CLASS_CL_ACCESSOR.getResourceStream(name);
116 }
117
118 if (is == null) {
119 is = SYSTEM_CL_ACCESSOR.getResourceStream(name);
120 }
121
122 return is;
123 }
124
125 public static boolean isAvailable(String fullyQualifiedClassName) {
126 try {
127 forName(fullyQualifiedClassName);
128 return true;
129 } catch (UnknownClassException e) {
130 return false;
131 }
132 }
133
134 @SuppressWarnings("unchecked")
135 public static Object newInstance(String fqcn) {
136 return newInstance(forName(fqcn));
137 }
138
139 @SuppressWarnings("unchecked")
140 public static Object newInstance(String fqcn, Object... args) {
141 return newInstance(forName(fqcn), args);
142 }
143
144 public static <T> T newInstance(Class<T> clazz) {
145 if (clazz == null) {
146 String msg = "Class method parameter cannot be null.";
147 throw new IllegalArgumentException(msg);
148 }
149 try {
150 return clazz.newInstance();
151 } catch (Exception e) {
152 throw new InstantiationException("Unable to instantiate class [" + clazz.getName() + "]", e);
153 }
154 }
155
156 public static <T> T newInstance(Class<T> clazz, Object... args) {
157 Class[] argTypes = new Class[args.length];
158 for (int i = 0; i < args.length; i++) {
159 argTypes[i] = args[i].getClass();
160 }
161 Constructor<T> ctor = getConstructor(clazz, argTypes);
162 return instantiate(ctor, args);
163 }
164
165 public static <T> Constructor<T> getConstructor(Class<T> clazz, Class... argTypes) {
166 try {
167 return clazz.getConstructor(argTypes);
168 } catch (NoSuchMethodException e) {
169 throw new IllegalStateException(e);
170 }
171
172 }
173
174 public static <T> T instantiate(Constructor<T> ctor, Object... args) {
175 try {
176 return ctor.newInstance(args);
177 } catch (Exception e) {
178 String msg = "Unable to instantiate instance with constructor [" + ctor + "]";
179 throw new InstantiationException(msg, e);
180 }
181 }
182
183
186 private static interface ClassLoaderAccessor {
187 Class loadClass(String fqcn);
188
189 InputStream getResourceStream(String name);
190 }
191
192
195 private static abstract class ExceptionIgnoringAccessor implements ClassLoaderAccessor {
196
197 public Class loadClass(String fqcn) {
198 Class clazz = null;
199 ClassLoader cl = getClassLoader();
200 if (cl != null) {
201 try {
202 clazz = cl.loadClass(fqcn);
203 } catch (ClassNotFoundException e) {
204
205 }
206 }
207 return clazz;
208 }
209
210 public InputStream getResourceStream(String name) {
211 InputStream is = null;
212 ClassLoader cl = getClassLoader();
213 if (cl != null) {
214 is = cl.getResourceAsStream(name);
215 }
216 return is;
217 }
218
219 protected final ClassLoader getClassLoader() {
220 try {
221 return doGetClassLoader();
222 } catch (Throwable t) {
223
224 }
225 return null;
226 }
227
228 protected abstract ClassLoader doGetClassLoader() throws Throwable;
229 }
230 }
231
232