1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.el;
18
19 import java.beans.BeanInfo;
20 import java.beans.EventSetDescriptor;
21 import java.beans.IndexedPropertyDescriptor;
22 import java.beans.IntrospectionException;
23 import java.beans.Introspector;
24 import java.beans.PropertyDescriptor;
25 import java.lang.reflect.Method;
26 import java.lang.reflect.Modifier;
27 import java.util.HashMap;
28 import java.util.Map;
29
30 import javax.servlet.jsp.el.ELException;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public class BeanInfoManager
49 {
50
51
52
53 private static Log log = LogFactory.getLog(BeanInfoManager.class);
54
55
56
57
58
59
60 Class mBeanClass;
61 public Class getBeanClass ()
62 { return mBeanClass; }
63
64
65
66
67
68
69 BeanInfo mBeanInfo;
70
71
72 Map mPropertyByName;
73
74
75 Map mIndexedPropertyByName;
76
77
78 Map mEventSetByName;
79
80
81 boolean mInitialized;
82
83
84 static Map mBeanInfoManagerByClass = new HashMap ();
85
86
87
88
89
90
91 BeanInfoManager (Class pBeanClass)
92 {
93 mBeanClass = pBeanClass;
94 }
95
96
97
98
99
100
101 public static BeanInfoManager getBeanInfoManager (Class pClass)
102 {
103 BeanInfoManager ret = (BeanInfoManager)
104 mBeanInfoManagerByClass.get (pClass);
105 if (ret == null) {
106 ret = createBeanInfoManager (pClass);
107 }
108 return ret;
109 }
110
111
112
113
114
115
116
117 static synchronized BeanInfoManager createBeanInfoManager (Class pClass)
118 {
119
120
121
122
123
124
125
126
127 BeanInfoManager ret = (BeanInfoManager)
128 mBeanInfoManagerByClass.get (pClass);
129 if (ret == null) {
130 ret = new BeanInfoManager (pClass);
131 mBeanInfoManagerByClass.put (pClass, ret);
132 }
133 return ret;
134 }
135
136
137
138
139
140
141
142 public static BeanInfoProperty getBeanInfoProperty
143 (Class pClass,
144 String pPropertyName)
145 throws ELException
146 {
147 return getBeanInfoManager (pClass).getProperty (pPropertyName);
148 }
149
150
151
152
153
154
155
156 public static BeanInfoIndexedProperty getBeanInfoIndexedProperty
157 (Class pClass,
158 String pIndexedPropertyName)
159 throws ELException
160 {
161 return getBeanInfoManager
162 (pClass).getIndexedProperty (pIndexedPropertyName);
163 }
164
165
166
167
168
169
170
171 void checkInitialized ()
172 throws ELException
173 {
174 if (!mInitialized) {
175 synchronized (this) {
176 if (!mInitialized) {
177 initialize();
178 mInitialized = true;
179 }
180 }
181 }
182 }
183
184
185
186
187
188
189 void initialize ()
190 throws ELException
191 {
192 try {
193 mBeanInfo = Introspector.getBeanInfo (mBeanClass);
194
195 mPropertyByName = new HashMap ();
196 mIndexedPropertyByName = new HashMap ();
197 PropertyDescriptor [] pds = mBeanInfo.getPropertyDescriptors ();
198 for (int i = 0; pds != null && i < pds.length; i++) {
199
200 PropertyDescriptor pd = pds [i];
201 if (pd instanceof IndexedPropertyDescriptor) {
202 IndexedPropertyDescriptor ipd = (IndexedPropertyDescriptor) pd;
203 Method readMethod = getPublicMethod (ipd.getIndexedReadMethod ());
204 Method writeMethod = getPublicMethod (ipd.getIndexedWriteMethod ());
205 BeanInfoIndexedProperty property = new BeanInfoIndexedProperty
206 (readMethod,
207 writeMethod,
208 ipd);
209
210 mIndexedPropertyByName.put (ipd.getName (), property);
211 }
212
213 Method readMethod = getPublicMethod (pd.getReadMethod ());
214 Method writeMethod = getPublicMethod (pd.getWriteMethod ());
215 BeanInfoProperty property = new BeanInfoProperty
216 (readMethod,
217 writeMethod,
218 pd);
219
220 mPropertyByName.put (pd.getName (), property);
221 }
222
223 mEventSetByName = new HashMap ();
224 EventSetDescriptor [] esds = mBeanInfo.getEventSetDescriptors ();
225 for (int i = 0; esds != null && i < esds.length; i++) {
226 EventSetDescriptor esd = esds [i];
227 mEventSetByName.put (esd.getName (), esd);
228 }
229 }
230 catch (IntrospectionException exc) {
231 if (log.isWarnEnabled()) {
232 log.warn(
233 MessageUtil.getMessageWithArgs(
234 Constants.EXCEPTION_GETTING_BEANINFO, mBeanClass.getName()), exc);
235 }
236 }
237 }
238
239
240
241
242
243
244 BeanInfo getBeanInfo ()
245 throws ELException
246 {
247 checkInitialized();
248 return mBeanInfo;
249 }
250
251
252
253
254
255
256
257 public BeanInfoProperty getProperty (String pPropertyName)
258 throws ELException
259 {
260 checkInitialized();
261 return (BeanInfoProperty) mPropertyByName.get (pPropertyName);
262 }
263
264
265
266
267
268
269
270 public BeanInfoIndexedProperty getIndexedProperty
271 (String pIndexedPropertyName)
272 throws ELException
273 {
274 checkInitialized();
275 return (BeanInfoIndexedProperty)
276 mIndexedPropertyByName.get (pIndexedPropertyName);
277 }
278
279
280
281
282
283
284
285 public EventSetDescriptor getEventSet (String pEventSetName)
286 throws ELException
287 {
288 checkInitialized();
289 return (EventSetDescriptor) mEventSetByName.get (pEventSetName);
290 }
291
292
293
294
295
296
297
298
299
300
301
302
303
304 static Method getPublicMethod (Method pMethod)
305 {
306 if (pMethod == null) {
307 return null;
308 }
309
310
311 Class cl = pMethod.getDeclaringClass ();
312 if (Modifier.isPublic (cl.getModifiers ())) {
313 return pMethod;
314 }
315
316
317 Method ret = getPublicMethod (cl, pMethod);
318 if (ret != null) {
319 return ret;
320 }
321 else {
322 return pMethod;
323 }
324 }
325
326
327
328
329
330
331
332
333
334 static Method getPublicMethod (Class pClass,
335 Method pMethod)
336 {
337
338 if (Modifier.isPublic (pClass.getModifiers ())) {
339 try {
340 Method m;
341 try {
342 m = pClass.getDeclaredMethod (pMethod.getName (),
343 pMethod.getParameterTypes ());
344 } catch (java.security.AccessControlException ex) {
345
346
347
348 m = pClass.getMethod(pMethod.getName (),
349 pMethod.getParameterTypes ());
350 }
351 if (Modifier.isPublic (m.getModifiers ())) {
352 return m;
353 }
354 }
355 catch (NoSuchMethodException exc) {}
356 }
357
358
359 {
360 Class [] interfaces = pClass.getInterfaces ();
361 if (interfaces != null) {
362 for (int i = 0; i < interfaces.length; i++) {
363 Method m = getPublicMethod (interfaces [i], pMethod);
364 if (m != null) {
365 return m;
366 }
367 }
368 }
369 }
370
371
372 {
373 Class superclass = pClass.getSuperclass ();
374 if (superclass != null) {
375 Method m = getPublicMethod (superclass, pMethod);
376 if (m != null) {
377 return m;
378 }
379 }
380 }
381
382 return null;
383 }
384
385
386 }