1 16 package org.apache.commons.jxpath.ri.model.beans; 17 18 import java.beans.IndexedPropertyDescriptor ; 19 import java.beans.PropertyDescriptor ; 20 21 import org.apache.commons.jxpath.JXPathBeanInfo; 22 import org.apache.commons.jxpath.JXPathContext; 23 import org.apache.commons.jxpath.JXPathException; 24 import org.apache.commons.jxpath.ri.model.NodePointer; 25 import org.apache.commons.jxpath.util.ValueUtils; 26 27 33 public class BeanPropertyPointer extends PropertyPointer { 34 private String propertyName; 35 private JXPathBeanInfo beanInfo; 36 private PropertyDescriptor propertyDescriptors[]; 37 private PropertyDescriptor propertyDescriptor; 38 private String [] names; 39 private static final Object UNINITIALIZED = new Object (); 40 private Object baseValue = UNINITIALIZED; 41 private Object value = UNINITIALIZED; 42 43 private static final int UNKNOWN_LENGTH_MAX_COUNT = 10000; 44 45 public BeanPropertyPointer(NodePointer parent, JXPathBeanInfo beanInfo) { 46 super(parent); 47 this.beanInfo = beanInfo; 48 } 49 50 53 public boolean isContainer() { 54 return true; 55 } 56 57 60 public int getPropertyCount() { 61 return getPropertyDescriptors().length; 62 } 63 64 67 public String [] getPropertyNames() { 68 if (names == null) { 69 PropertyDescriptor pds[] = getPropertyDescriptors(); 70 names = new String [pds.length]; 71 for (int i = 0; i < names.length; i++) { 72 names[i] = pds[i].getName(); 73 } 74 } 75 return names; 76 } 77 78 81 public void setPropertyName(String propertyName) { 82 setPropertyIndex(UNSPECIFIED_PROPERTY); 83 this.propertyName = propertyName; 84 } 85 86 89 public void setPropertyIndex(int index) { 90 if (propertyIndex != index) { 91 super.setPropertyIndex(index); 92 propertyName = null; 93 propertyDescriptor = null; 94 baseValue = UNINITIALIZED; 95 value = UNINITIALIZED; 96 } 97 } 98 99 102 public Object getBaseValue() { 103 if (baseValue == UNINITIALIZED) { 104 PropertyDescriptor pd = getPropertyDescriptor(); 105 if (pd == null) { 106 return null; 107 } 108 baseValue = ValueUtils.getValue(getBean(), pd); 109 } 110 return baseValue; 111 } 112 113 public void setIndex(int index) { 114 if (this.index != index) { 115 if (this.index != WHOLE_COLLECTION 118 || index != 0 119 || isCollection()) { 120 super.setIndex(index); 121 value = UNINITIALIZED; 122 } 123 } 124 } 125 126 132 public Object getImmediateNode() { 133 if (value == UNINITIALIZED) { 134 if (index == WHOLE_COLLECTION) { 135 value = ValueUtils.getValue(getBaseValue()); 136 } 137 else { 138 PropertyDescriptor pd = getPropertyDescriptor(); 139 if (pd == null) { 140 value = null; 141 } 142 else { 143 value = ValueUtils.getValue(getBean(), pd, index); 144 } 145 } 146 } 147 return value; 148 } 149 150 protected boolean isActualProperty() { 151 return getPropertyDescriptor() != null; 152 } 153 154 public boolean isCollection() { 155 PropertyDescriptor pd = getPropertyDescriptor(); 156 if (pd == null) { 157 return false; 158 } 159 160 if (pd instanceof IndexedPropertyDescriptor ) { 161 return true; 162 } 163 164 int hint = ValueUtils.getCollectionHint(pd.getPropertyType()); 165 if (hint == -1) { 166 return false; 167 } 168 if (hint == 1) { 169 return true; 170 } 171 172 Object value = getBaseValue(); 173 return value != null && ValueUtils.isCollection(value); 174 } 175 176 180 public int getLength() { 181 PropertyDescriptor pd = getPropertyDescriptor(); 182 if (pd == null) { 183 return 1; 184 } 185 186 if (pd instanceof IndexedPropertyDescriptor ) { 187 return ValueUtils.getIndexedPropertyLength( 188 getBean(), 189 (IndexedPropertyDescriptor ) pd); 190 } 191 192 int hint = ValueUtils.getCollectionHint(pd.getPropertyType()); 193 if (hint == -1) { 194 return 1; 195 } 196 return ValueUtils.getLength(getBaseValue()); 197 } 198 199 204 public void setValue(Object value) { 205 PropertyDescriptor pd = getPropertyDescriptor(); 206 if (pd == null) { 207 throw new JXPathException( 208 "Cannot set property: " + asPath() + " - no such property"); 209 } 210 211 if (index == WHOLE_COLLECTION) { 212 ValueUtils.setValue(getBean(), pd, value); 213 } 214 else { 215 ValueUtils.setValue(getBean(), pd, index, value); 216 } 217 this.value = value; 218 } 219 220 223 public NodePointer createPath(JXPathContext context) { 224 if (getImmediateNode() == null) { 225 super.createPath(context); 226 baseValue = UNINITIALIZED; 227 value = UNINITIALIZED; 228 } 229 return this; 230 } 231 232 public void remove() { 233 if (index == WHOLE_COLLECTION) { 234 setValue(null); 235 } 236 else if (isCollection()) { 237 Object collection = ValueUtils.remove(getBaseValue(), index); 238 ValueUtils.setValue(getBean(), getPropertyDescriptor(), collection); 239 } 240 else if (index == 0) { 241 index = WHOLE_COLLECTION; 242 setValue(null); 243 } 244 } 245 246 249 public String getPropertyName() { 250 if (propertyName == null) { 251 PropertyDescriptor pd = getPropertyDescriptor(); 252 if (pd != null) { 253 propertyName = pd.getName(); 254 } 255 } 256 return propertyName != null ? propertyName : "*"; 257 } 258 259 263 private PropertyDescriptor getPropertyDescriptor() { 264 if (propertyDescriptor == null) { 265 int inx = getPropertyIndex(); 266 if (inx == UNSPECIFIED_PROPERTY) { 267 propertyDescriptor = 268 beanInfo.getPropertyDescriptor(propertyName); 269 } 270 else { 271 PropertyDescriptor propertyDescriptors[] = 272 getPropertyDescriptors(); 273 if (inx >= 0 && inx < propertyDescriptors.length) { 274 propertyDescriptor = propertyDescriptors[inx]; 275 } 276 else { 277 propertyDescriptor = null; 278 } 279 } 280 } 281 return propertyDescriptor; 282 } 283 284 protected PropertyDescriptor [] getPropertyDescriptors() { 285 if (propertyDescriptors == null) { 286 propertyDescriptors = beanInfo.getPropertyDescriptors(); 287 } 288 return propertyDescriptors; 289 } 290 } | Popular Tags |