    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 }