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. import java.beans.BeanInfo;
  18. import java.beans.IntrospectionException;
  19. import java.beans.Introspector;
  20. import java.beans.PropertyDescriptor;
  21. import java.util.Arrays;
  22. import java.util.Comparator;
  23. /**
  24. * An implementation of JXPathBeanInfo based on JavaBeans' BeanInfo. Properties
  25. * advertised by JXPathBasicBeanInfo are the same as those advertised by
  26. * BeanInfo for the corresponding class.
  27. *
  28. * See java.beans.BeanInfo, java.beans.Introspector
  29. *
  30. * @author Dmitri Plotnikov
  31. * @version $Revision: 1.9 $ $Date: 2004/05/08 15:03:36 $
  32. */
  33. public class JXPathBasicBeanInfo implements JXPathBeanInfo {
  34. private boolean atomic = false;
  35. private Class clazz;
  36. private PropertyDescriptor propertyDescriptors[];
  37. private String[] propertyNames;
  38. private Class dynamicPropertyHandlerClass;
  39. public JXPathBasicBeanInfo(Class clazz) {
  40. this.clazz = clazz;
  41. }
  42. public JXPathBasicBeanInfo(Class clazz, boolean atomic) {
  43. this.clazz = clazz;
  44. this.atomic = atomic;
  45. }
  46. public JXPathBasicBeanInfo(Class clazz, Class dynamicPropertyHandlerClass) {
  47. this.clazz = clazz;
  48. this.atomic = false;
  49. this.dynamicPropertyHandlerClass = dynamicPropertyHandlerClass;
  50. }
  51. /**
  52. * Returns true if objects of this class are treated as atomic
  53. * objects which have no properties of their own.
  54. */
  55. public boolean isAtomic() {
  56. return atomic;
  57. }
  58. /**
  59. * Return true if the corresponding objects have dynamic properties.
  60. */
  61. public boolean isDynamic() {
  62. return dynamicPropertyHandlerClass != null;
  63. }
  64. public PropertyDescriptor[] getPropertyDescriptors() {
  65. if (propertyDescriptors == null) {
  66. try {
  67. BeanInfo bi = null;
  68. if (clazz.isInterface()) {
  69. bi = Introspector.getBeanInfo(clazz);
  70. }
  71. else {
  72. bi = Introspector.getBeanInfo(clazz, Object.class);
  73. }
  74. PropertyDescriptor[] pds = bi.getPropertyDescriptors();
  75. propertyDescriptors = new PropertyDescriptor[pds.length];
  76. System.arraycopy(pds, 0, propertyDescriptors, 0, pds.length);
  77. Arrays.sort(propertyDescriptors, new Comparator() {
  78. public int compare(Object left, Object right) {
  79. return ((PropertyDescriptor) left).getName().compareTo(
  80. ((PropertyDescriptor) right).getName());
  81. }
  82. });
  83. }
  84. catch (IntrospectionException ex) {
  85. ex.printStackTrace();
  86. }
  87. }
  88. return propertyDescriptors;
  89. }
  90. public PropertyDescriptor getPropertyDescriptor(String propertyName) {
  91. if (propertyNames == null) {
  92. PropertyDescriptor[] pds = getPropertyDescriptors();
  93. propertyNames = new String[pds.length];
  94. for (int i = 0; i < pds.length; i++) {
  95. propertyNames[i] = pds[i].getName();
  96. }
  97. }
  98. for (int i = 0; i < propertyNames.length; i++) {
  99. if (propertyNames[i] == propertyName) {
  100. return propertyDescriptors[i];
  101. }
  102. }
  103. for (int i = 0; i < propertyNames.length; i++) {
  104. if (propertyNames[i].equals(propertyName)) {
  105. return propertyDescriptors[i];
  106. }
  107. }
  108. return null;
  109. }
  110. /**
  111. * For a dynamic class, returns the corresponding DynamicPropertyHandler
  112. * class.
  113. */
  114. public Class getDynamicPropertyHandlerClass() {
  115. return dynamicPropertyHandlerClass;
  116. }
  117. public String toString() {
  118. StringBuffer buffer = new StringBuffer();
  119. buffer.append("BeanInfo [class = ");
  120. buffer.append(clazz.getName());
  121. if (isDynamic()) {
  122. buffer.append(", dynamic");
  123. }
  124. if (isAtomic()) {
  125. buffer.append(", atomic");
  126. }
  127. buffer.append(", properties = ");
  128. PropertyDescriptor[] jpds = getPropertyDescriptors();
  129. for (int i = 0; i < jpds.length; i++) {
  130. buffer.append("\n ");
  131. buffer.append(jpds[i].getPropertyType());
  132. buffer.append(": ");
  133. buffer.append(jpds[i].getName());
  134. }
  135. buffer.append("]");
  136. return buffer.toString();
  137. }
  138. }