1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.betwixt.digester;
17
18 import java.beans.BeanInfo;
19 import java.beans.Introspector;
20 import java.beans.PropertyDescriptor;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24
25 /*** <p>Factors out common code used by Betwixt rules that access bean properties.
26 * Maybe a lot of this should be moved into <code>BeanUtils</code>.</p>
27 *
28 * @author Robert Burrell Donkin
29 * @sinec 0.5
30 */
31 public abstract class MappedPropertyRule extends RuleSupport {
32
33 /*** Logger */
34 private static final Log log = LogFactory.getLog( MappedPropertyRule.class );
35 /*** Classloader used to load classes by name */
36 private ClassLoader classLoader;
37 /*** Base constructor */
38 public MappedPropertyRule() {
39 this.classLoader = getClass().getClassLoader();
40 }
41
42
43
44
45
46
47 /***
48 * Returns the property descriptor for the class and property name.
49 * Note that some caching could be used to improve performance of
50 * this method. Or this method could be added to PropertyUtils.
51 *
52 * @param beanClass descriptor for property in this class
53 * @param propertyName descriptor for property with this name
54 * @return property descriptor for the named property in the given class
55 */
56 protected PropertyDescriptor getPropertyDescriptor( Class beanClass,
57 String propertyName ) {
58 if ( beanClass != null && propertyName != null ) {
59 if (log.isTraceEnabled()) {
60 log.trace("Searching for property " + propertyName + " on " + beanClass);
61 }
62 try {
63 BeanInfo beanInfo = Introspector.getBeanInfo( beanClass );
64 PropertyDescriptor[] descriptors =
65 beanInfo.getPropertyDescriptors();
66 if ( descriptors != null ) {
67 for ( int i = 0, size = descriptors.length; i < size; i++ ) {
68 PropertyDescriptor descriptor = descriptors[i];
69 if ( propertyName.equals( descriptor.getName() ) ) {
70 log.trace("Found matching method.");
71 return descriptor;
72 }
73 }
74 }
75 log.trace("No match found.");
76 return null;
77 } catch (Exception e) {
78 log.warn( "Caught introspection exception", e );
79 }
80 }
81 return null;
82 }
83
84
85 /***
86 * Gets the type of a property
87 *
88 * @param propertyClassName class name for property type (may be null)
89 * @param beanClass class that has property
90 * @param propertyName the name of the property whose type is to be determined
91 * @return property type
92 */
93 protected Class getPropertyType( String propertyClassName,
94 Class beanClass, String propertyName ) {
95
96
97 if ( propertyClassName != null ) {
98 try {
99 Class answer = classLoader.loadClass(propertyClassName);
100 if (answer != null) {
101 if (log.isTraceEnabled()) {
102 log.trace("Used specified type " + answer);
103 }
104 return answer;
105 }
106 } catch (Exception e) {
107 log.warn("Cannot load specified type", e);
108 }
109 }
110
111 PropertyDescriptor descriptor =
112 getPropertyDescriptor( beanClass, propertyName );
113 if ( descriptor != null ) {
114 return descriptor.getPropertyType();
115 }
116
117 if (log.isTraceEnabled()) {
118 log.trace("Cannot find property type.");
119 log.trace(" className=" + propertyClassName
120 + " base=" + beanClass + " name=" + propertyName);
121 }
122 return null;
123 }
124 }