1
2
3
4
5
6
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 }