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 @Override
69 public String toString()
70 {
71 return this.value;
72 }
73
74
75
76
77
78
79 public static final String toDescriptor(final Class<?>[] classes)
80 {
81 StringBuilder result = new StringBuilder();
82 for (int i = 0; i < classes.length; i++)
83 {
84 result.append(FieldSignature.toDescriptor(classes[i]));
85 }
86 return result.toString();
87 }
88
89
90
91
92
93
94 public static final String toDescriptor(final Class<?> clazz)
95 {
96 if (clazz.getName().startsWith("["))
97 {
98 return clazz.getName().replace('.', '/');
99 }
100 if (clazz.isPrimitive())
101 {
102 if (clazz.equals(int.class))
103 {
104 return "I";
105 }
106 if (clazz.equals(double.class))
107 {
108 return "D";
109 }
110 if (clazz.equals(boolean.class))
111 {
112 return "Z";
113 }
114 if (clazz.equals(char.class))
115 {
116 return "C";
117 }
118 if (clazz.equals(byte.class))
119 {
120 return "B";
121 }
122 if (clazz.equals(float.class))
123 {
124 return "F";
125 }
126 if (clazz.equals(long.class))
127 {
128 return "J";
129 }
130 if (clazz.equals(short.class))
131 {
132 return "S";
133 }
134 return "V";
135 }
136 return "L" + clazz.getName().replace('.', '/') + ";";
137 }
138
139
140
141
142
143
144
145 public static final Class<?> toClass(final String descriptor) throws ClassNotFoundException
146 {
147 if (FieldSignature.CACHE.containsKey(descriptor))
148 {
149 return FieldSignature.CACHE.get(descriptor);
150 }
151 String className = descriptor;
152 Class<?> result = null;
153 int array = 0;
154 while (className.charAt(array) == '[')
155 {
156 array++;
157 }
158 className = className.substring(array);
159 if (className.startsWith("L"))
160 {
161 className = className.replaceAll("/", ".");
162 className = className.substring(1, className.length() - 1);
163 try
164 {
165 result = Class.forName(className);
166 }
167 catch (Exception exception)
168 {
169 result = Class.forName(className, true, Thread.currentThread().getContextClassLoader());
170 }
171 }
172 else
173 {
174 result = Primitive.forName(className);
175 }
176 if (result == null && !descriptor.startsWith("["))
177 {
178
179 return FieldSignature.toClass("L" + descriptor + ";");
180 }
181 if (array == 0)
182 {
183 FieldSignature.CACHE.put(descriptor, result);
184 return result;
185 }
186 try
187 {
188 int[] dimensions = new int[array];
189 result = Array.newInstance(result, dimensions).getClass();
190 }
191 catch (Exception exception)
192 {
193 throw new ClassNotFoundException(result + " class not found");
194 }
195 FieldSignature.CACHE.put(descriptor, result);
196 return result;
197 }
198 }