1 package org.djutils.reflection;
2
3 import java.io.Serializable;
4 import java.lang.reflect.Array;
5 import java.util.LinkedHashMap;
6 import java.util.Map;
7
8 import org.djutils.primitives.Primitive;
9
10
11
12
13
14
15
16
17
18
19
20
21
22 public class FieldSignature implements Serializable
23 {
24
25 private static final long serialVersionUID = 20191230L;
26
27
28 private static final Map<String, Class<?>> CACHE = new LinkedHashMap<String, Class<?>>();
29
30
31 private String value;
32
33
34
35
36
37 public FieldSignature(final String value)
38 {
39 this.value = value;
40 }
41
42
43
44
45
46 public FieldSignature(final Class<?> clazz)
47 {
48 this(FieldSignature.toDescriptor(clazz));
49 }
50
51
52
53
54 public String getStringValue()
55 {
56 return this.value;
57 }
58
59
60
61
62
63 public Class<?> getClassValue() throws ClassNotFoundException
64 {
65 return FieldSignature.toClass(this.value);
66 }
67
68
69 @Override
70 public String toString()
71 {
72 return this.value;
73 }
74
75
76
77
78
79
80 public static final String toDescriptor(final Class<?>[] classes)
81 {
82 StringBuilder result = new StringBuilder();
83 for (int i = 0; i < classes.length; i++)
84 {
85 result.append(FieldSignature.toDescriptor(classes[i]));
86 }
87 return result.toString();
88 }
89
90
91
92
93
94
95 public static final String toDescriptor(final Class<?> clazz)
96 {
97 if (clazz.getName().startsWith("["))
98 {
99 return clazz.getName().replace('.', '/');
100 }
101 if (clazz.isPrimitive())
102 {
103 if (clazz.equals(int.class))
104 {
105 return "I";
106 }
107 if (clazz.equals(double.class))
108 {
109 return "D";
110 }
111 if (clazz.equals(boolean.class))
112 {
113 return "Z";
114 }
115 if (clazz.equals(char.class))
116 {
117 return "C";
118 }
119 if (clazz.equals(byte.class))
120 {
121 return "B";
122 }
123 if (clazz.equals(float.class))
124 {
125 return "F";
126 }
127 if (clazz.equals(long.class))
128 {
129 return "J";
130 }
131 if (clazz.equals(short.class))
132 {
133 return "S";
134 }
135 return "V";
136 }
137 return "L" + clazz.getName().replace('.', '/') + ";";
138 }
139
140
141
142
143
144
145
146 public static final Class<?> toClass(final String descriptor) throws ClassNotFoundException
147 {
148 if (FieldSignature.CACHE.containsKey(descriptor))
149 {
150 return FieldSignature.CACHE.get(descriptor);
151 }
152 String className = descriptor;
153 Class<?> result = null;
154 int array = 0;
155 while (className.charAt(array) == '[')
156 {
157 array++;
158 }
159 className = className.substring(array);
160 if (className.startsWith("L"))
161 {
162 className = className.replaceAll("/", ".");
163 className = className.substring(1, className.length() - 1);
164 try
165 {
166 result = Class.forName(className);
167 }
168 catch (Exception exception)
169 {
170 result = Class.forName(className, true, Thread.currentThread().getContextClassLoader());
171 }
172 }
173 else
174 {
175 result = Primitive.forName(className);
176 }
177 if (result == null && !descriptor.startsWith("["))
178 {
179
180 return FieldSignature.toClass("L" + descriptor + ";");
181 }
182 if (array == 0)
183 {
184 FieldSignature.CACHE.put(descriptor, result);
185 return result;
186 }
187 try
188 {
189 int[] dimensions = new int[array];
190 result = Array.newInstance(result, dimensions).getClass();
191 }
192 catch (Exception exception)
193 {
194 throw new ClassNotFoundException(result + " class not found");
195 }
196 FieldSignature.CACHE.put(descriptor, result);
197 return result;
198 }
199 }