1
2
3
4
5
6
7
8
9
10 package org.dom4j.bean;
11
12 import java.beans.BeanInfo;
13 import java.beans.IntrospectionException;
14 import java.beans.Introspector;
15 import java.beans.PropertyDescriptor;
16 import java.lang.reflect.Method;
17 import java.util.HashMap;
18 import java.util.Map;
19
20 import org.dom4j.DocumentFactory;
21 import org.dom4j.QName;
22
23 /*** <p><code>BeanMetaData</code> contains metadata about a bean class.</p>
24 *
25 * @author <a href="mailto:james.strachan@metastuff.com">James Strachan</a>
26 * @version $Revision: 1.8 $
27 */
28 public class BeanMetaData {
29
30 /*** Empty arguments for reflection calls */
31 protected static final Object[] NULL_ARGS = {};
32
33 /*** Singleton cache */
34 private static Map singletonCache = new HashMap();
35
36 private static final DocumentFactory DOCUMENT_FACTORY = BeanDocumentFactory.getInstance();
37
38 /*** The class of the bean */
39 private Class beanClass;
40
41 /*** Property descriptors for the bean */
42 private PropertyDescriptor[] propertyDescriptors;
43
44 /*** QNames for the attributes */
45 private QName[] qNames;
46
47 /*** Read methods used for getting properties */
48 private Method[] readMethods;
49
50 /*** Write methods used for setting properties */
51 private Method[] writeMethods;
52
53 /*** Index of names and QNames to indices */
54 private Map nameMap = new HashMap();
55
56
57 /*** Static helper method to find and cache meta data objects for bean types
58 */
59 public static BeanMetaData get(Class beanClass) {
60 BeanMetaData answer = (BeanMetaData) singletonCache.get( beanClass );
61 if ( answer == null ) {
62 answer = new BeanMetaData( beanClass );
63 singletonCache.put( beanClass, answer );
64 }
65 return answer;
66 }
67
68 public BeanMetaData(Class beanClass) {
69 this.beanClass = beanClass;
70 if ( beanClass != null ) {
71 try {
72 BeanInfo beanInfo = Introspector.getBeanInfo( beanClass );
73 propertyDescriptors = beanInfo.getPropertyDescriptors();
74 }
75 catch (IntrospectionException e) {
76 handleException(e);
77 }
78 }
79 if ( propertyDescriptors == null ) {
80 propertyDescriptors = new PropertyDescriptor[0];
81 }
82 int size = propertyDescriptors.length;
83 qNames = new QName[size];
84 readMethods = new Method[size];
85 writeMethods = new Method[size];
86 for ( int i = 0; i < size; i++ ) {
87 PropertyDescriptor propertyDescriptor = propertyDescriptors[i];
88 String name = propertyDescriptor.getName();
89 QName qName = DOCUMENT_FACTORY.createQName( name );
90 qNames[i] = qName;
91 readMethods[i] = propertyDescriptor.getReadMethod();
92 writeMethods[i] = propertyDescriptor.getWriteMethod();
93
94 Integer index = new Integer(i);
95 nameMap.put( name, index );
96 nameMap.put( qName, index );
97 }
98 }
99
100 /*** @return the number of attribtutes for this bean type
101 */
102 public int attributeCount() {
103 return propertyDescriptors.length;
104 }
105
106 public BeanAttributeList createAttributeList(BeanElement parent) {
107 return new BeanAttributeList( parent, this );
108 }
109
110 public QName getQName(int index) {
111 return qNames[index];
112 }
113
114 public int getIndex(String name) {
115 Integer index = (Integer) nameMap.get(name);
116 return ( index != null ) ? index.intValue() : -1;
117 }
118
119 public int getIndex(QName qName) {
120 Integer index = (Integer) nameMap.get(qName);
121 return ( index != null ) ? index.intValue() : -1;
122 }
123
124 public Object getData(int index, Object bean) {
125 try {
126 Method method = readMethods[index];
127 return method.invoke( bean, NULL_ARGS );
128 }
129 catch (Exception e) {
130 handleException(e);
131 return null;
132 }
133 }
134
135 public void setData(int index, Object bean, Object data) {
136 try {
137 Method method = writeMethods[index];
138 Object[] args = { data };
139 method.invoke( bean, args );
140 }
141 catch (Exception e) {
142 handleException(e);
143 }
144 }
145
146
147
148 protected void handleException(Exception e) {
149
150 }
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199