1 package org.apache.commons.ognl;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.commons.ognl.internal.*;
23 import org.apache.commons.ognl.internal.entry.*;
24
25 import java.beans.PropertyDescriptor;
26 import java.lang.reflect.Constructor;
27 import java.lang.reflect.Field;
28 import java.lang.reflect.Method;
29 import java.security.Permission;
30 import java.util.Arrays;
31 import java.util.Collection;
32 import java.util.Enumeration;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Set;
37
38
39
40
41 public class OgnlCache {
42
43 private final CacheFactory cacheFactory = new HashMapCacheFactory();
44
45 private final ClassCache<MethodAccessor> methodAccessors = cacheFactory.createClassCache();
46 {
47 MethodAccessor methodAccessor = new ObjectMethodAccessor();
48 setMethodAccessor( Object.class, methodAccessor );
49 setMethodAccessor( byte[].class, methodAccessor );
50 setMethodAccessor( short[].class, methodAccessor );
51 setMethodAccessor( char[].class, methodAccessor );
52 setMethodAccessor( int[].class, methodAccessor );
53 setMethodAccessor( long[].class, methodAccessor );
54 setMethodAccessor( float[].class, methodAccessor );
55 setMethodAccessor( double[].class, methodAccessor );
56 setMethodAccessor( Object[].class, methodAccessor );
57 }
58
59 private final ClassCache<PropertyAccessor> propertyAccessors = cacheFactory.createClassCache();
60 {
61 PropertyAccessor propertyAccessor = new ArrayPropertyAccessor();
62 setPropertyAccessor( Object.class, new ObjectPropertyAccessor() );
63 setPropertyAccessor( byte[].class, propertyAccessor );
64 setPropertyAccessor( short[].class, propertyAccessor );
65 setPropertyAccessor( char[].class, propertyAccessor );
66 setPropertyAccessor( int[].class, propertyAccessor );
67 setPropertyAccessor( long[].class, propertyAccessor );
68 setPropertyAccessor( float[].class, propertyAccessor );
69 setPropertyAccessor( double[].class, propertyAccessor );
70 setPropertyAccessor( Object[].class, propertyAccessor );
71 setPropertyAccessor( List.class, new ListPropertyAccessor() );
72 setPropertyAccessor( Map.class, new MapPropertyAccessor() );
73 setPropertyAccessor( Set.class, new SetPropertyAccessor() );
74 setPropertyAccessor( Iterator.class, new IteratorPropertyAccessor() );
75 setPropertyAccessor( Enumeration.class, new EnumerationPropertyAccessor() );
76 }
77
78 private final ClassCache<ElementsAccessor> elementsAccessors = cacheFactory.createClassCache();
79 {
80 ElementsAccessor elementsAccessor = new ArrayElementsAccessor();
81 setElementsAccessor( Object.class, new ObjectElementsAccessor() );
82 setElementsAccessor( byte[].class, elementsAccessor );
83 setElementsAccessor( short[].class, elementsAccessor );
84 setElementsAccessor( char[].class, elementsAccessor );
85 setElementsAccessor( int[].class, elementsAccessor );
86 setElementsAccessor( long[].class, elementsAccessor );
87 setElementsAccessor( float[].class, elementsAccessor );
88 setElementsAccessor( double[].class, elementsAccessor );
89 setElementsAccessor( Object[].class, elementsAccessor );
90 setElementsAccessor( Collection.class, new CollectionElementsAccessor() );
91 setElementsAccessor( Map.class, new MapElementsAccessor() );
92 setElementsAccessor( Iterator.class, new IteratorElementsAccessor() );
93 setElementsAccessor( Enumeration.class, new EnumerationElementsAccessor() );
94 setElementsAccessor( Number.class, new NumberElementsAccessor() );
95 }
96
97 private final ClassCache<NullHandler> nullHandlers = cacheFactory.createClassCache( );
98 {
99 NullHandler nullHandler = new ObjectNullHandler();
100 setNullHandler( Object.class, nullHandler );
101 setNullHandler( byte[].class, nullHandler );
102 setNullHandler( short[].class, nullHandler );
103 setNullHandler( char[].class, nullHandler );
104 setNullHandler( int[].class, nullHandler );
105 setNullHandler( long[].class, nullHandler );
106 setNullHandler( float[].class, nullHandler );
107 setNullHandler( double[].class, nullHandler );
108 setNullHandler( Object[].class, nullHandler );
109 }
110
111 final ClassCache<Map<String, PropertyDescriptor>> propertyDescriptorCache =
112 cacheFactory.createClassCache( new PropertyDescriptorCacheEntryFactory() );
113
114 private final ClassCache<List<Constructor<?>>> constructorCache =
115 cacheFactory.createClassCache( new ClassCacheEntryFactory<List<Constructor<?>>>()
116 {
117 public List<Constructor<?>> create( Class<?> key )
118 throws CacheException
119 {
120 return Arrays.<Constructor<?>>asList( key.getConstructors() );
121 }
122 } );
123
124 private final Cache<DeclaredMethodCacheEntry, Map<String, List<Method>>> _methodCache =
125 cacheFactory.createCache( new DeclaredMethodCacheEntryFactory() );
126
127 private final Cache<PermissionCacheEntry, Permission> _invokePermissionCache =
128 cacheFactory.createCache( new PermissionCacheEntryFactory() );
129
130 private final ClassCache<Map<String, Field>> _fieldCache =
131 cacheFactory.createClassCache( new FieldCacheEntryFactory() );
132
133 private final Cache<Method, Class<?>[]> _methodParameterTypesCache =
134 cacheFactory.createCache( new CacheEntryFactory<Method, Class<?>[]>()
135 {
136 public Class<?>[] create( Method key )
137 throws CacheException
138 {
139 return key.getParameterTypes( );
140 }
141 } );
142
143 private final Cache<GenericMethodParameterTypeCacheEntry, Class<?>[]> _genericMethodParameterTypesCache =
144 cacheFactory.createCache( new GenericMethodParameterTypeFactory() );
145
146 private final Cache<Constructor<?>, Class<?>[]> _ctorParameterTypesCache =
147 cacheFactory.createCache( new CacheEntryFactory<Constructor<?>, Class<?>[]>()
148 {
149 public Class<?>[] create( Constructor<?> key ) throws CacheException
150 {
151 return key.getParameterTypes( );
152 }
153 } );
154
155 private final Cache<Method, MethodAccessEntryValue> _methodAccessCache =
156 cacheFactory.createCache( new MethodAccessCacheEntryFactory( ) );
157
158 private final MethodPermCacheEntryFactory methodPermCacheEntryFactory =
159 new MethodPermCacheEntryFactory( System.getSecurityManager() );
160
161 private final Cache<Method, Boolean> _methodPermCache = cacheFactory.createCache( methodPermCacheEntryFactory );
162
163 public Class<?>[] getMethodParameterTypes( Method method ) throws CacheException {
164 return _methodParameterTypesCache.get( method );
165 }
166
167 public Class<?>[] getParameterTypes( Constructor<?> constructor ) throws CacheException {
168 return _ctorParameterTypesCache.get( constructor );
169 }
170
171 public List<Constructor<?>> getConstructor( Class<?> clazz ) throws CacheException {
172 return constructorCache.get( clazz );
173 }
174
175 public Map<String, Field> getField( Class<?> clazz ) throws CacheException {
176 return _fieldCache.get( clazz );
177 }
178
179 public Map<String, List<Method>> getMethod( DeclaredMethodCacheEntry declaredMethodCacheEntry ) throws CacheException {
180 return _methodCache.get( declaredMethodCacheEntry );
181 }
182
183 public Map<String, PropertyDescriptor> getPropertyDescriptor( Class<?> clazz ) throws CacheException {
184 return propertyDescriptorCache.get( clazz );
185 }
186
187 public Permission getInvokePermission( PermissionCacheEntry permissionCacheEntry ) throws CacheException {
188 return _invokePermissionCache.get( permissionCacheEntry );
189 }
190
191 public MethodAccessor getMethodAccessor( Class<?> clazz ) throws OgnlException
192 {
193 MethodAccessor methodAccessor = ClassCacheHandler.getHandler( clazz, methodAccessors );
194 if ( methodAccessor != null )
195 {
196 return methodAccessor;
197 }
198 throw new OgnlException( "No method accessor for " + clazz );
199 }
200
201 public void setMethodAccessor( Class<?> clazz, MethodAccessor accessor )
202 {
203 methodAccessors.put( clazz, accessor );
204 }
205
206 public void setPropertyAccessor( Class<?> clazz, PropertyAccessor accessor )
207 {
208 propertyAccessors.put( clazz, accessor );
209 }
210
211 public PropertyAccessor getPropertyAccessor( Class<?> clazz )
212 throws OgnlException
213 {
214 PropertyAccessor propertyAccessor = ClassCacheHandler.getHandler( clazz, propertyAccessors );
215 if ( propertyAccessor != null )
216 {
217 return propertyAccessor;
218 }
219 throw new OgnlException( "No property accessor for class " + clazz );
220 }
221
222
223
224
225
226
227
228 public void setClassCacheInspector( ClassCacheInspector inspector )
229 {
230 propertyDescriptorCache.setClassInspector( inspector );
231 constructorCache.setClassInspector( inspector );
232
233
234
235 _fieldCache.setClassInspector( inspector );
236 }
237
238 public Class<?>[] getGenericMethodParameterTypes( GenericMethodParameterTypeCacheEntry key )
239 throws CacheException
240 {
241 return _genericMethodParameterTypesCache.get( key );
242 }
243
244 public boolean getMethodPerm( Method method ) throws CacheException
245 {
246 return _methodPermCache.get( method );
247 }
248
249 public MethodAccessEntryValue getMethodAccess( Method method ) throws CacheException
250 {
251 return _methodAccessCache.get( method );
252 }
253
254 public void clear() {
255 _methodParameterTypesCache.clear();
256 _ctorParameterTypesCache.clear();
257 propertyDescriptorCache.clear();
258 constructorCache.clear();
259 _methodCache.clear();
260 _invokePermissionCache.clear();
261 _fieldCache.clear();
262 _methodAccessCache.clear();
263 }
264
265 public ElementsAccessor getElementsAccessor( Class<?> clazz ) throws OgnlException
266 {
267 ElementsAccessor answer = ClassCacheHandler.getHandler( clazz, elementsAccessors );
268 if ( answer != null )
269 {
270 return answer;
271 }
272 throw new OgnlException( "No elements accessor for class " + clazz );
273 }
274
275 public void setElementsAccessor( Class<?> clazz, ElementsAccessor accessor )
276 {
277 elementsAccessors.put( clazz, accessor );
278 }
279
280 public NullHandler getNullHandler( Class<?> clazz ) throws OgnlException
281 {
282 NullHandler answer = ClassCacheHandler.getHandler( clazz, nullHandlers );
283 if ( answer != null )
284 {
285 return answer;
286 }
287 throw new OgnlException( "No null handler for class " + clazz );
288 }
289
290 public void setNullHandler( Class<?> clazz, NullHandler handler )
291 {
292 nullHandlers.put( clazz, handler );
293 }
294
295 public void setSecurityManager( SecurityManager securityManager )
296 {
297 methodPermCacheEntryFactory.setSecurityManager( securityManager );
298 }
299 }