1
2
3
4
5
6
7
8
9
10 package nl.tudelft.simulation.language.reflection;
11
12 import java.io.Serializable;
13 import java.lang.reflect.Array;
14
15 import nl.tudelft.simulation.language.primitives.Primitive;
16
17 /***
18 * A field descriptor represents the type of a class, instance, or local
19 * variable. It is a series of characters generated by the grammar described at
20 * <a href =
21 * "http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#1169">
22 * The Java Virtual Machine Specification </a> <br>
23 * (c) copyright 2004 <a href="http://www.simulation.tudelft.nl">Delft
24 * University of Technology </a>, the Netherlands. <br>
25 * See for project information <a
26 * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
27 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
28 * License (GPL) </a>, no warranty <br>
29 *
30 * @author <a href="http://www.tbm.tudelft.nl/webstaf/peterja/index.htm">Peter
31 * Jacobs </a>, <a href="mailto:nlang@fbk.eur.nl">Niels Lang </a><a
32 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
33 * Verbraeck </a>
34 * @version 1.4 March 24, 2004
35 * @since 1.3
36 */
37 public class FieldSignature implements Serializable
38 {
39
40 /*** the value of the field descriptor */
41 private String value;
42
43 /***
44 * constructs a new FieldSignature
45 *
46 * @param value the value of the descriptor
47 */
48 public FieldSignature(final String value)
49 {
50 super();
51 this.value = value;
52 }
53
54 /***
55 * constructs a new FieldSignature
56 *
57 * @param clazz The class
58 */
59 public FieldSignature(final Class clazz)
60 {
61 this(FieldSignature.toDescriptor(clazz));
62 }
63
64 /***
65 * @return Returns the value of the field descriptor
66 */
67 public String getStringValue()
68 {
69 return this.value;
70 }
71
72 /***
73 * @return Returns the value of the field descriptor
74 * @throws ClassNotFoundException if the class cannot be found.
75 */
76 public Class getClassValue() throws ClassNotFoundException
77 {
78 return FieldSignature.toClass(this.value);
79 }
80
81 /***
82 * @see java.lang.Object#toString()
83 */
84 public String toString()
85 {
86 return this.value;
87 }
88
89 /***
90 * converts an array of fields to its descriptor
91 *
92 * @param classes the classes to represent
93 * @return String the descriptor String
94 */
95 public static final String toDescriptor(final Class[] classes)
96 {
97 String result = "";
98 for (int i = 0; i < classes.length; i++)
99 {
100 result = result + FieldSignature.toDescriptor(classes[i]);
101 }
102 return result;
103 }
104
105 /***
106 * converts a field to its descriptor
107 *
108 * @param clazz the clazz to represent
109 * @return String the descriptor String
110 */
111 public static final String toDescriptor(final Class clazz)
112 {
113 if (clazz.getName().startsWith("["))
114 {
115 return clazz.getName().replace('.', '/');
116 }
117 if (clazz.isPrimitive())
118 {
119 if (clazz.equals(int.class))
120 {
121 return "I";
122 }
123 if (clazz.equals(double.class))
124 {
125 return "D";
126 }
127 if (clazz.equals(boolean.class))
128 {
129 return "Z";
130 }
131 if (clazz.equals(char.class))
132 {
133 return "C";
134 }
135 if (clazz.equals(byte.class))
136 {
137 return "B";
138 }
139 if (clazz.equals(float.class))
140 {
141 return "F";
142 }
143 if (clazz.equals(long.class))
144 {
145 return "J";
146 }
147 if (clazz.equals(short.class))
148 {
149 return "S";
150 }
151 return "V";
152 }
153 return "L" + clazz.getName().replace('.', '/') + ";";
154 }
155
156 /***
157 * converts a fieldDescriptor to its class representation
158 *
159 * @param descriptor the descriptor
160 * @return Class the class
161 * @throws ClassNotFoundException on failure
162 */
163 public static final Class toClass(final String descriptor)
164 throws ClassNotFoundException
165 {
166 String className = descriptor;
167 Class result = null;
168 int array = 0;
169 while (className.charAt(array) == '[')
170 {
171 array++;
172 }
173 className = className.substring(array);
174 if (className.startsWith("L"))
175 {
176 className = className.replaceAll("/", ".");
177 className = className.substring(1, className.length() - 1);
178 try
179 {
180 result = Class.forName(className);
181 } catch (Exception exception)
182 {
183 result = Class.forName(className, true, Thread.currentThread()
184 .getContextClassLoader());
185 }
186 } else
187 {
188 result = Primitive.forName(className);
189 }
190 if (result == null && !descriptor.startsWith("["))
191 {
192
193 return FieldSignature.toClass("L" + descriptor + ";");
194 }
195 if (array == 0)
196 {
197 return result;
198 }
199 try
200 {
201 int[] dimensions = new int[array];
202 result = Array.newInstance(result, dimensions).getClass();
203 } catch (Exception exception)
204 {
205 throw new ClassNotFoundException(result + " class not found");
206 }
207 return result;
208 }
209 }