View Javadoc

1   /*
2    * Copyright 1999-2004 The Apache Software Foundation
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.jxpath;
17  
18  import java.beans.BeanInfo;
19  import java.beans.IntrospectionException;
20  import java.beans.Introspector;
21  import java.beans.PropertyDescriptor;
22  import java.util.Arrays;
23  import java.util.Comparator;
24  
25  /***
26   * An implementation of JXPathBeanInfo based on JavaBeans' BeanInfo. Properties
27   * advertised by JXPathBasicBeanInfo are the same as those advertised by
28   * BeanInfo for the corresponding class.
29   *
30   * See java.beans.BeanInfo, java.beans.Introspector
31   *
32   * @author Dmitri Plotnikov
33   * @version $Revision: 1.9 $ $Date: 2004/05/08 15:03:36 $
34   */
35  public class JXPathBasicBeanInfo implements JXPathBeanInfo {
36      private boolean atomic = false;
37      private Class clazz;
38      private PropertyDescriptor propertyDescriptors[];
39      private String[] propertyNames;
40      private Class dynamicPropertyHandlerClass;
41  
42      public JXPathBasicBeanInfo(Class clazz) {
43          this.clazz = clazz;
44      }
45  
46      public JXPathBasicBeanInfo(Class clazz, boolean atomic) {
47          this.clazz = clazz;
48          this.atomic = atomic;
49      }
50  
51      public JXPathBasicBeanInfo(Class clazz, Class dynamicPropertyHandlerClass) {
52          this.clazz = clazz;
53          this.atomic = false;
54          this.dynamicPropertyHandlerClass = dynamicPropertyHandlerClass;
55      }
56  
57      /***
58       * Returns true if objects of this class are treated as atomic
59       * objects which have no properties of their own.
60       */
61      public boolean isAtomic() {
62          return atomic;
63      }
64  
65      /***
66       * Return true if the corresponding objects have dynamic properties.
67       */
68      public boolean isDynamic() {
69          return dynamicPropertyHandlerClass != null;
70      }
71  
72      public PropertyDescriptor[] getPropertyDescriptors() {
73          if (propertyDescriptors == null) {
74              try {
75                  BeanInfo bi = null;
76                  if (clazz.isInterface()) {
77                      bi = Introspector.getBeanInfo(clazz);
78                  }
79                  else {
80                      bi = Introspector.getBeanInfo(clazz, Object.class);
81                  }
82                  PropertyDescriptor[] pds = bi.getPropertyDescriptors();
83                  propertyDescriptors = new PropertyDescriptor[pds.length];
84                  System.arraycopy(pds, 0, propertyDescriptors, 0, pds.length);
85                  Arrays.sort(propertyDescriptors, new Comparator() {
86                      public int compare(Object left, Object right) {
87                          return ((PropertyDescriptor) left).getName().compareTo(
88                              ((PropertyDescriptor) right).getName());
89                      }
90                  });
91              }
92              catch (IntrospectionException ex) {
93                  ex.printStackTrace();
94              }
95          }
96          return propertyDescriptors;
97      }
98  
99      public PropertyDescriptor getPropertyDescriptor(String propertyName) {
100         if (propertyNames == null) {
101             PropertyDescriptor[] pds = getPropertyDescriptors();
102             propertyNames = new String[pds.length];
103             for (int i = 0; i < pds.length; i++) {
104                 propertyNames[i] = pds[i].getName();
105             }
106         }
107 
108         for (int i = 0; i < propertyNames.length; i++) {
109             if (propertyNames[i] == propertyName) {
110                 return propertyDescriptors[i];
111             }
112         }
113 
114         for (int i = 0; i < propertyNames.length; i++) {
115             if (propertyNames[i].equals(propertyName)) {
116                 return propertyDescriptors[i];
117             }
118         }
119         return null;
120     }
121 
122     /***
123      * For  a dynamic class, returns the corresponding DynamicPropertyHandler
124      * class.
125      */
126     public Class getDynamicPropertyHandlerClass() {
127         return dynamicPropertyHandlerClass;
128     }
129 
130     public String toString() {
131         StringBuffer buffer = new StringBuffer();
132         buffer.append("BeanInfo [class = ");
133         buffer.append(clazz.getName());
134         if (isDynamic()) {
135             buffer.append(", dynamic");
136         }
137         if (isAtomic()) {
138             buffer.append(", atomic");
139         }
140         buffer.append(", properties = ");
141         PropertyDescriptor[] jpds = getPropertyDescriptors();
142         for (int i = 0; i < jpds.length; i++) {
143             buffer.append("\n    ");
144             buffer.append(jpds[i].getPropertyType());
145             buffer.append(": ");
146             buffer.append(jpds[i].getName());
147         }
148         buffer.append("]");
149         return buffer.toString();
150     }
151 }