View Javadoc

1   /*
2    * @(#) FieldSignature.java Jan 12, 2004
3    * 
4    * Copyright (c) 2003 Delft University of Technology Jaffalaan 5, 2628 BX Delft,
5    * the Netherlands All rights reserved.
6    * 
7    * This software is proprietary information of Delft University of Technology
8    * The code is published under the General Public License
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 			//For some reason not all classes start with L and end with ;
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 }