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