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 java.util.Map;
11  import java.util.WeakHashMap;
12  import org.codehaus.metaclass.model.ClassDescriptor;
13  
14  /***
15   * Caching MetaClassAccessor implementation.
16   *
17   * @author Peter Donald
18   * @version $Revision: 1.7 $ $Date: 2003/12/11 08:41:50 $
19   */
20  public class CachingMetaClassAccessor
21      implements MetaClassAccessor
22  {
23      /*** Class used to access the MetaData. */
24      private MetaClassAccessor m_accessor = new DefaultMetaClassAccessor();
25  
26      /***
27       * The cache in which descriptor objects are stored. This cache stores maps
28       * for ClassLoaders which in turn stores descriptors for particular classes
29       * in classloader.
30       */
31      private final Map m_cache = new WeakHashMap();
32  
33      /***
34       * Set the MetaClassAccessor to use to locate ClassDescriptor objects.
35       *
36       * @param accessor the MetaClassAccessor
37       */
38      public synchronized void setAccessor( final MetaClassAccessor accessor )
39      {
40          if( null == accessor )
41          {
42              throw new NullPointerException( "accessor" );
43          }
44          m_accessor = accessor;
45      }
46  
47      /***
48       * Remove all descriptors from registry.
49       */
50      public synchronized void clear()
51      {
52          m_cache.clear();
53      }
54  
55      /***
56       * @see MetaClassAccessor#getClassDescriptor
57       */
58      public synchronized ClassDescriptor getClassDescriptor(
59          final String classname,
60          final ClassLoader classLoader,
61          final MetaClassAccessor accessor )
62          throws MetaClassException
63      {
64          if( null == classname )
65          {
66              throw new NullPointerException( "classname" );
67          }
68          if( null == classLoader )
69          {
70              throw new NullPointerException( "classLoader" );
71          }
72          final Map cache = getClassLoaderCache( classLoader );
73          ClassDescriptor descriptor = (ClassDescriptor)cache.get( classname );
74          if( null != descriptor )
75          {
76              return descriptor;
77          }
78          else
79          {
80              descriptor =
81              m_accessor.getClassDescriptor( classname,
82                                             classLoader,
83                                             accessor );
84              cache.put( classname, descriptor );
85              return descriptor;
86          }
87      }
88  
89      /***
90       * Register specified descriptor and associated with specified ClassLoader.
91       *
92       * @param descriptor the descriptor
93       * @param classLoader the ClassLoader
94       */
95      public synchronized void registerDescriptor(
96          final ClassDescriptor descriptor,
97          final ClassLoader classLoader )
98      {
99          if( null == descriptor )
100         {
101             throw new NullPointerException( "descriptor" );
102         }
103         if( null == classLoader )
104         {
105             throw new NullPointerException( "classLoader" );
106         }
107         final Map cache = getClassLoaderCache( classLoader );
108         cache.put( descriptor.getName(), descriptor );
109     }
110 
111     /***
112      * Get Cache for specified ClassLoader.
113      *
114      * @param classLoader the ClassLoader to get cache for
115      * @return the Map/Cache for ClassLoader
116      */
117     private synchronized Map getClassLoaderCache(
118         final ClassLoader classLoader )
119     {
120         Map map = (Map)m_cache.get( classLoader );
121         if( null == map )
122         {
123             map = new WeakHashMap();
124             m_cache.put( classLoader, map );
125         }
126         return map;
127     }
128 }