KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > reflect > plugins > javassist > JavassistTypeInfo


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2006, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.reflect.plugins.javassist;
23
24 import java.lang.reflect.Array JavaDoc;
25 import java.lang.reflect.Modifier JavaDoc;
26 import java.util.Collection JavaDoc;
27 import java.util.Map JavaDoc;
28
29 import javassist.CtClass;
30 import javassist.CtConstructor;
31 import javassist.CtField;
32 import javassist.CtMethod;
33 import javassist.NotFoundException;
34
35 import org.jboss.reflect.plugins.ValueConvertor;
36 import org.jboss.reflect.spi.AnnotationValue;
37 import org.jboss.reflect.spi.ClassInfo;
38 import org.jboss.reflect.spi.ConstructorInfo;
39 import org.jboss.reflect.spi.FieldInfo;
40 import org.jboss.reflect.spi.InterfaceInfo;
41 import org.jboss.reflect.spi.MethodInfo;
42 import org.jboss.reflect.spi.TypeInfo;
43 import org.jboss.util.collection.CollectionsFactory;
44 import org.jboss.util.JBossStringBuilder;
45
46 /**
47  * JavassistTypeInfo.
48  *
49  * @author <a HREF="adrian@jboss.com">Adrian Brock</a>
50  * @version $Revision: 57321 $
51  */

52 public class JavassistTypeInfo extends JavassistInheritableAnnotationHolder implements ClassInfo, InterfaceInfo
53 {
54    /** The factory */
55    private JavassistTypeInfoFactoryImpl factory;
56
57    /** The class */
58    private Class JavaDoc<? extends Object JavaDoc> clazz;
59
60    /** The constructors */
61    private Map JavaDoc<SignatureKey, JavassistConstructorInfo> constructors = CollectionsFactory.createLazyMap();
62
63    /** The constructors */
64    private ConstructorInfo[] constructorArray;
65
66    /** The fields */
67    private Map JavaDoc<String JavaDoc, JavassistFieldInfo> fields = CollectionsFactory.createLazyMap();
68
69    /** The fields */
70    private FieldInfo[] fieldArray;
71
72    /** The methods */
73    private Map JavaDoc<SignatureKey, JavassistMethodInfo> methods = CollectionsFactory.createLazyMap();
74
75    /** The methods */
76    private MethodInfo[] methodArray;
77
78    /**
79     * Create a new JavassistTypeInfo.
80     *
81     * @param factory the factory
82     * @param ctClass the ctClass
83     * @param clazz the class
84     */

85    JavassistTypeInfo(JavassistTypeInfoFactoryImpl factory, CtClass ctClass, Class JavaDoc<? extends Object JavaDoc> clazz)
86    {
87       super(ctClass, factory);
88       this.factory = factory;
89       this.clazz = clazz;
90    }
91
92    public String JavaDoc getName()
93    {
94       return ctClass.getName();
95    }
96
97    public boolean isInterface()
98    {
99       return ctClass.isInterface();
100    }
101
102    public int getModifiers()
103    {
104       return ctClass.getModifiers();
105    }
106
107    public boolean isPublic()
108    {
109       return Modifier.isPublic(getModifiers());
110    }
111
112    public boolean isStatic()
113    {
114       return Modifier.isStatic(getModifiers());
115    }
116
117    public Class JavaDoc<? extends Object JavaDoc> getType()
118    {
119       return clazz;
120    }
121
122    public ClassInfo getSuperclass()
123    {
124       try
125       {
126          CtClass superclass = ctClass.getSuperclass();
127          if (superclass == null)
128             return null;
129          return (ClassInfo) factory.getTypeInfo(superclass);
130       }
131       catch (NotFoundException e)
132       {
133          throw JavassistTypeInfoFactoryImpl.raiseClassNotFound(clazz.getSuperclass().getName(), e);
134       }
135    }
136
137    public InterfaceInfo[] getInterfaces()
138    {
139       try
140       {
141          CtClass[] interfaces = ctClass.getInterfaces();
142          if (interfaces == null || interfaces.length == 0)
143             return null;
144          InterfaceInfo[] result = new InterfaceInfo[interfaces.length];
145          for (int i = 0; i < result.length; ++i)
146             result[i] = (InterfaceInfo) factory.getTypeInfo(interfaces[i]);
147          return result;
148       }
149       catch (NotFoundException e)
150       {
151          throw JavassistTypeInfoFactoryImpl.raiseClassNotFound("for interfaces of " + getName(), e);
152       }
153    }
154
155    public ConstructorInfo[] getDeclaredConstructors()
156    {
157       if (constructorArray == null)
158       {
159          CtConstructor[] declaredConstructors = ctClass.getDeclaredConstructors();
160          if (declaredConstructors == null || declaredConstructors.length == 0)
161             constructorArray = new ConstructorInfo[0];
162          else
163          {
164             synchronized (constructors)
165             {
166                for (int i = 0; i < declaredConstructors.length; ++i)
167                   generateConstructorInfo(declaredConstructors[i]);
168                Collection JavaDoc<JavassistConstructorInfo> constructorCollection = constructors.values();
169                constructorArray = constructorCollection.toArray(new ConstructorInfo[constructorCollection.size()]);
170             }
171          }
172       }
173       return constructorArray;
174    }
175
176    public FieldInfo getDeclaredField(String JavaDoc name)
177    {
178       synchronized (fields)
179       {
180          FieldInfo field = fields.get(name);
181          if (field != null)
182             return field;
183       }
184       if (fieldArray != null)
185          return null;
186       try
187       {
188          CtField field = ctClass.getDeclaredField(name);
189          if (field == null)
190             return null;
191          return generateFieldInfo(field);
192       }
193       catch (NotFoundException e)
194       {
195          return null;
196       }
197    }
198
199    public FieldInfo[] getDeclaredFields()
200    {
201       if (fieldArray == null)
202       {
203          CtField[] declaredFields = ctClass.getDeclaredFields();
204          if (declaredFields == null || declaredFields.length == 0)
205             fieldArray = new FieldInfo[0];
206          else
207          {
208             synchronized (fields)
209             {
210                for (int i = 0; i < declaredFields.length; ++i)
211                   generateFieldInfo(declaredFields[i]);
212                Collection JavaDoc<JavassistFieldInfo> fieldCollection = fields.values();
213                fieldArray = fieldCollection.toArray(new FieldInfo[fieldCollection.size()]);
214             }
215          }
216       }
217       return fieldArray;
218    }
219
220    public MethodInfo getDeclaredMethod(String JavaDoc name, TypeInfo[] parameters)
221    {
222       SignatureKey key = new SignatureKey(name, parameters);
223       synchronized (methods)
224       {
225          MethodInfo method = methods.get(key);
226          if (method != null)
227             return method;
228       }
229       if (methodArray != null)
230          return null;
231       return generateMethodInfo(key);
232    }
233
234    public MethodInfo[] getDeclaredMethods()
235    {
236       if (methodArray == null)
237       {
238          CtMethod[] declaredMethods = ctClass.getDeclaredMethods();
239          if (declaredMethods == null || declaredMethods.length == 0)
240             methodArray = new MethodInfo[0];
241          else
242          {
243             synchronized (methods)
244             {
245                for (int i = 0; i < declaredMethods.length; ++i)
246                   generateMethodInfo(declaredMethods[i]);
247                Collection JavaDoc<JavassistMethodInfo> methodCollection = methods.values();
248                methodArray = methodCollection.toArray(new MethodInfo[methodCollection.size()]);
249             }
250          }
251       }
252       return methodArray;
253    }
254
255    public boolean isArray()
256    {
257       return getType().isArray();
258    }
259
260    /**
261     * Get an array class
262     *
263     * @todo there must be a better way to do this!
264     * @param clazz the class
265     * @param depth the depth
266     * @return the array class
267     */

268    public static Class JavaDoc getArrayClass(Class JavaDoc clazz, int depth)
269    {
270       return Array.newInstance(clazz, depth).getClass();
271    }
272
273    public TypeInfo getArrayType(int depth)
274    {
275       Class JavaDoc arrayClass = getArrayClass(getType(), depth);
276       return factory.getTypeInfo(arrayClass);
277    }
278
279    public Object JavaDoc[] newArrayInstance(int size) throws Throwable JavaDoc
280    {
281       Class JavaDoc clazz = getType();
282       if (clazz.isArray() == false)
283          throw new ClassCastException JavaDoc(clazz + " is not an array.");
284       return (Object JavaDoc[]) Array.newInstance(clazz.getComponentType(), size);
285    }
286
287    public Object JavaDoc convertValue(Object JavaDoc value) throws Throwable JavaDoc
288    {
289       return ValueConvertor.convertValue(getType(), value);
290    }
291
292    protected int getHashCode()
293    {
294       return getName().hashCode();
295    }
296
297    public boolean equals(Object JavaDoc obj)
298    {
299       if (obj == this)
300          return true;
301       if (obj == null || obj instanceof TypeInfo == false)
302          return false;
303
304       TypeInfo other = (TypeInfo) obj;
305       return getName().equals(other.getName());
306    }
307
308    public void toShortString(JBossStringBuilder buffer)
309    {
310       buffer.append(getName());
311    }
312
313    protected void toString(JBossStringBuilder buffer)
314    {
315       buffer.append("name=").append(getName());
316       super.toString(buffer);
317    }
318
319    /**
320     * Get the factory
321     *
322     * @return the factory
323     */

324    protected JavassistTypeInfoFactoryImpl getFactory()
325    {
326       return factory;
327    }
328
329    /**
330     * Generate constructor info
331     *
332     * @param constructor the constructor
333     * @return the constructor info
334     */

335    protected ConstructorInfo generateConstructorInfo(CtConstructor constructor)
336    {
337       try
338       {
339          CtClass[] parameterTypes = constructor.getParameterTypes();
340          String JavaDoc[] params = new String JavaDoc[parameterTypes.length];
341          for (int i = 0; i < params.length; ++i)
342             params[i] = parameterTypes[i].getName();
343          SignatureKey key = new SignatureKey(null, params);
344          JavassistConstructorInfo info = new JavassistConstructorInfo(factory, this, constructor);
345          synchronized (constructors)
346          {
347             constructors.put(key, info);
348          }
349          return info;
350       }
351       catch (NotFoundException e)
352       {
353          throw JavassistTypeInfoFactoryImpl.raiseClassNotFound("for constructor of " + getName(), e);
354       }
355    }
356
357    /**
358     * Generate field info
359     *
360     * @param field the field
361     * @return the field info
362     */

363    protected FieldInfo generateFieldInfo(CtField field)
364    {
365       JavassistFieldInfo info = new JavassistFieldInfo(factory, this, field);
366       synchronized (fields)
367       {
368          fields.put(field.getName(), info);
369       }
370       return info;
371    }
372
373    /**
374     * Generate method info
375     *
376     * @param key the key
377     * @return the method info
378     */

379    protected MethodInfo generateMethodInfo(SignatureKey key)
380    {
381       CtClass[] params = getParameterTypes(key);
382       try
383       {
384          CtMethod ctMethod = ctClass.getDeclaredMethod(key.name, params);
385          return generateMethodInfo(key, ctMethod);
386       }
387       catch (NotFoundException e)
388       {
389          throw JavassistTypeInfoFactoryImpl.raiseMethodNotFound("for method " + key.name, e);
390       }
391    }
392
393    /**
394     * Generate method info
395     *
396     * @param method the method
397     * @return the method info
398     */

399    protected MethodInfo generateMethodInfo(CtMethod method)
400    {
401       try
402       {
403          CtClass[] parameterTypes = method.getParameterTypes();
404          String JavaDoc[] params = new String JavaDoc[parameterTypes.length];
405          for (int i = 0; i < params.length; ++i)
406             params[i] = parameterTypes[i].getName();
407          SignatureKey key = new SignatureKey(method.getName(), params);
408          return generateMethodInfo(key, method);
409       }
410       catch (NotFoundException e)
411       {
412          throw JavassistTypeInfoFactoryImpl.raiseClassNotFound("for method " + method.getName(), e);
413       }
414    }
415
416    /**
417     * Generate method info
418     *
419     * @param key the key
420     * @param method the method
421     * @return the method info
422     */

423    protected MethodInfo generateMethodInfo(SignatureKey key, CtMethod method)
424    {
425       JavassistMethodInfo info = new JavassistMethodInfo(factory, this, key, method);
426       synchronized (methods)
427       {
428          methods.put(key, info);
429       }
430       return info;
431    }
432
433    /**
434     * Get the parameter types
435     *
436     * @param key the key
437     * @return the parameter types
438     */

439    protected CtClass[] getParameterTypes(SignatureKey key)
440    {
441       if (key.params == null)
442          return null;
443
444       CtClass[] result = new CtClass[key.params.length];
445       for (int i = 0; i < key.params.length; ++i)
446          result[i] = factory.getCtClass(key.params[i]);
447
448       return result;
449    }
450
451    protected Object JavaDoc getAnnotatedTarget()
452    {
453       return ctClass;
454    }
455    
456    public AnnotationValue[] getAnnotations()
457    {
458       return getAnnotations(ctClass);
459    }
460
461    @Override JavaDoc
462    public JavassistInheritableAnnotationHolder getSuperHolder()
463    {
464       try
465       {
466          CtClass zuper = ctClass.getSuperclass();
467          if (zuper == null)
468          {
469             return null;
470          }
471          return (JavassistTypeInfo)factory.getTypeInfo(zuper);
472       }
473       catch (NotFoundException e)
474       {
475          throw new RuntimeException JavaDoc(e);
476       }
477    }
478
479 }
480
Popular Tags