1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.crypto.utils;
19
20 import java.lang.ref.WeakReference;
21 import java.lang.reflect.Constructor;
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.Map;
25 import java.util.WeakHashMap;
26
27 import org.apache.commons.crypto.cipher.CryptoCipher;
28
29
30
31
32 public final class ReflectionUtils {
33
34
35
36
37
38 private static abstract class NegativeCacheSentinel {
39
40 }
41
42 private static final Map<ClassLoader, Map<String, WeakReference<Class<?>>>> CACHE_CLASSES = new WeakHashMap<>();
43
44 private static final ClassLoader CLASSLOADER;
45
46 static {
47 final ClassLoader threadClassLoader = Thread.currentThread().getContextClassLoader();
48 CLASSLOADER = threadClassLoader != null ? threadClassLoader : CryptoCipher.class.getClassLoader();
49 }
50
51
52
53
54 private static final Class<?> NEGATIVE_CACHE_SENTINEL = NegativeCacheSentinel.class;
55
56
57
58
59
60
61
62
63 public static Class<?> getClassByName(final String name) throws ClassNotFoundException {
64 final Class<?> ret = getClassByNameOrNull(name);
65 if (ret == null) {
66 throw new ClassNotFoundException("Class " + name + " not found");
67 }
68 return ret;
69 }
70
71
72
73
74
75
76
77
78 private static Class<?> getClassByNameOrNull(final String name) {
79 final Map<String, WeakReference<Class<?>>> map;
80
81 synchronized (CACHE_CLASSES) {
82 map = CACHE_CLASSES.computeIfAbsent(CLASSLOADER, k -> Collections.synchronizedMap(new WeakHashMap<>()));
83 }
84
85 Class<?> clazz = null;
86 final WeakReference<Class<?>> ref = map.get(name);
87 if (ref != null) {
88 clazz = ref.get();
89 }
90
91 if (clazz == null) {
92 try {
93 clazz = Class.forName(name, true, CLASSLOADER);
94 } catch (final ClassNotFoundException e) {
95
96 map.put(name, new WeakReference<>(NEGATIVE_CACHE_SENTINEL));
97 return null;
98 }
99
100 map.put(name, new WeakReference<>(clazz));
101 return clazz;
102 }
103 if (clazz == NEGATIVE_CACHE_SENTINEL) {
104 return null;
105 }
106
107 return clazz;
108 }
109
110
111
112
113
114
115
116
117
118
119
120
121
122 public static <T> T newInstance(final Class<T> klass, final Object... args) {
123 try {
124 final Constructor<T> ctor;
125 final int argsLength = args.length;
126
127 if (argsLength == 0) {
128 ctor = klass.getDeclaredConstructor();
129 } else {
130 final Class<?>[] argClses = new Class[argsLength];
131 Arrays.setAll(argClses, i -> args[i].getClass());
132 ctor = klass.getDeclaredConstructor(argClses);
133 }
134 ctor.setAccessible(true);
135 return ctor.newInstance(args);
136 } catch (final Exception e) {
137 throw new IllegalArgumentException(e);
138 }
139 }
140
141
142
143
144 private ReflectionUtils() {
145 }
146 }