View Javadoc

1   /*
2    * Copyright (C) The MetaClass Group. All rights reserved.
3    *
4    * This software is published under the terms of the Spice
5    * Software License version 1.1, a copy of which has been included
6    * with this distribution in the LICENSE.txt file.
7    */
8   package org.codehaus.metaclass.introspector;
9   
10  import org.codehaus.metaclass.model.ClassDescriptor;
11  
12  /***
13   * This class is responsible for loading and caching the {@link ClassDescriptor}
14   * objects for corresponding java classes. It serves a similar purpose as the
15   * {@link java.beans.Introspector} class does for Java Beans.
16   * 
17   * @author Peter Donald
18   * @version $Revision: 1.9 $ $Date: 2004/01/16 00:25:55 $
19   */
20  public final class MetaClassIntrospector
21  {
22      /*** Permission needed to clear complete cache. */
23      private static final RuntimePermission CLEAR_CACHE_PERMISSION =
24          new RuntimePermission( "metaclass.clearCompleteCache" );
25  
26      /*** Permission needed to set the accessor. */
27      private static final RuntimePermission SET_ACCESSOR_PERMISSION =
28          new RuntimePermission( "metaclass.setAccessor" );
29  
30      /*** The cache in which descriptor objects are stored. */
31      private static final CachingMetaClassAccessor c_cachingAccessor =
32          new CachingMetaClassAccessor();
33  
34      /***
35       * Wrapper Accessor that is passed to the above accessor to retrieve
36       * ClassDescriptors. Ensures that no Accessor can get a direct reference to
37       * the CachingMetaClassAccessor and thus subvert descriptor loading
38       * process.
39       */
40      private static final WrapperMetaClassAccessor c_wrapperAccessor =
41          new WrapperMetaClassAccessor( c_cachingAccessor );
42  
43      /***
44       * Flush all of the Introspector's internal caches.  This method is not
45       * normally required.  It is normally only needed by advanced tools that
46       * update existing "Class" objects in-place and need to make the
47       * Introspector re-analyze existing Class objects.
48       * 
49       * <p>Note that the caller must have been granted the
50       * "metaclass.clearCompleteCache" {@link java.lang.RuntimePermission} or
51       * else a security exception will be thrown.</p>
52       * 
53       * @throws java.lang.SecurityException if the caller does not have
54       * permission to clear cache
55       */
56      public static synchronized void clearCompleteCache()
57      {
58          final SecurityManager sm = System.getSecurityManager();
59          if( null != sm )
60          {
61              sm.checkPermission( CLEAR_CACHE_PERMISSION );
62          }
63          c_cachingAccessor.clear();
64      }
65  
66      /***
67       * Set the MetaClassAccessor to use to locate ClassDescriptor objects.
68       * 
69       * <p>Note that the caller must have been granted the
70       * "metaclass.setAccessor" {@link java.lang.RuntimePermission} or else a
71       * security exception will be thrown.</p>
72       * 
73       * @param accessor the MetaClassAccessor
74       * @throws SecurityException if the caller does not have permission to clear
75       * cache
76       */
77      public static void setAccessor( final MetaClassAccessor accessor )
78      {
79          final SecurityManager sm = System.getSecurityManager();
80          if( null != sm )
81          {
82              sm.checkPermission( SET_ACCESSOR_PERMISSION );
83          }
84          c_cachingAccessor.setAccessor( accessor );
85      }
86  
87      /***
88       * @see MetaClassAccessor#getClassDescriptor
89       */
90      public static ClassDescriptor getClassDescriptor( final Class clazz )
91          throws MetaClassException
92      {
93          return getClassDescriptor( clazz.getName(), clazz.getClassLoader() );
94      }
95  
96      /***
97       * @see MetaClassAccessor#getClassDescriptor
98       */
99      public static ClassDescriptor
100         getClassDescriptor( final String classname,
101                             final ClassLoader classLoader )
102         throws MetaClassException
103     {
104         return c_cachingAccessor.getClassDescriptor( classname,
105                                                      classLoader,
106                                                      c_wrapperAccessor );
107     }
108 }