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