1 package org.apache.ojb.broker.metadata.fieldaccess; 2 3 17 18 import java.beans.BeanInfo ; 19 import java.beans.IntrospectionException ; 20 import java.beans.Introspector ; 21 import java.beans.PropertyDescriptor ; 22 import java.lang.reflect.Method ; 23 import java.util.ArrayList ; 24 import java.util.List ; 25 26 import org.apache.commons.lang.StringUtils; 27 import org.apache.ojb.broker.core.proxy.ProxyHelper; 28 import org.apache.ojb.broker.metadata.MetadataException; 29 import org.apache.ojb.broker.util.ClassHelper; 30 import org.apache.ojb.broker.util.logging.Logger; 31 32 41 public class PersistentFieldIntrospectorImpl extends PersistentFieldBase 42 { 43 private static final long serialVersionUID = 8805309492150404444L; 44 private Class type; 45 private transient List propertyGraph; 46 47 public PersistentFieldIntrospectorImpl() 48 { 49 super(); 50 } 51 52 public PersistentFieldIntrospectorImpl(Class aClass, String aPropertyName) 53 { 54 super(aClass, aPropertyName); 55 } 56 57 public Class getType() 58 { 59 if (type == null) 60 { 61 type = getPropertyDescriptor().getPropertyType(); 62 } 63 return type; 64 } 65 66 public void set(Object target, Object value) throws MetadataException 67 { 68 if(target == null) return; 69 List propertyDescriptors = getPropertyGraph(); 70 int size = propertyDescriptors.size() - 1; 71 PropertyDescriptor pd; 72 for (int i = 0; i < size; i++) 73 { 74 Object attribute; 75 pd = (PropertyDescriptor ) propertyDescriptors.get(i); 76 attribute = getValueFrom(pd, target); 77 if (attribute != null || value != null) 78 { 79 if (attribute == null) 80 { 81 try 82 { 83 attribute = ClassHelper.newInstance(pd.getPropertyType()); 84 } 85 catch (Exception e) 86 { 87 throw new MetadataException("Can't instantiate nested object of type '" 88 + pd.getPropertyType() + "' for field '" 89 + pd.getName() + "'", e); 90 } 91 } 92 setValueFor(pd, target, attribute); 93 } 94 else 95 { 96 return; 97 } 98 target = attribute; 99 } 100 pd = (PropertyDescriptor ) propertyDescriptors.get(size); 101 setValueFor(pd, target, value); 102 } 103 104 public Object get(Object target) throws MetadataException 105 { 106 List propertyDescriptors = getPropertyGraph(); 107 for (int i = 0; i < propertyDescriptors.size(); i++) 108 { 109 PropertyDescriptor pd = (PropertyDescriptor ) propertyDescriptors.get(i); 110 target = getValueFrom(pd, target); 111 if (target == null) break; 112 } 113 return target; 114 } 115 116 private Object getValueFrom(PropertyDescriptor pd, Object target) 117 { 118 if (target == null) return null; 119 Method m = pd.getReadMethod(); 120 if (m != null) 121 { 122 try 123 { 124 return m.invoke(ProxyHelper.getRealObject(target), null); 125 } 126 catch (Throwable e) 127 { 128 logProblem(pd, target, null, "Can't read value from given object"); 129 throw new MetadataException("Error invoking method:" + m.getName() + " in object " + target.getClass().getName(), e); 130 } 131 } 132 else 133 { 134 throw new MetadataException("Can't get ReadMethod for property:" + pd.getName() + " in object " + target.getClass().getName()); 135 } 136 } 137 138 private void setValueFor(PropertyDescriptor pd, Object target, Object value) 139 { 140 Method m = pd.getWriteMethod(); 141 Object [] args = {value}; 142 if (m != null) 143 { 144 try 145 { 146 152 if ((value != null) || !m.getParameterTypes()[0].isPrimitive()) 153 { 154 m.invoke(ProxyHelper.getRealObject(target), args); 155 } 156 } 157 catch (Throwable e) 158 { 159 logProblem(pd, target, value, "Can't set value on given object."); 160 throw new MetadataException("Error invoking method:" + m.getName() + " in object:" + target.getClass().getName(), e); 161 } 162 } 163 else 164 { 165 throw new MetadataException("Can't get WriteMethod for property:" + pd.getName() + " in object:" + target.getClass().getName()); 166 } 167 } 168 169 private List getPropertyGraph() 170 { 171 if (propertyGraph == null) 172 { 173 propertyGraph = buildPropertyGraph(); 174 } 175 return propertyGraph; 176 } 177 178 private List buildPropertyGraph() 179 { 180 List result = new ArrayList (); 181 String [] fields = StringUtils.split(getName(), PATH_TOKEN); 182 PropertyDescriptor pd = null; 183 for (int i = 0; i < fields.length; i++) 184 { 185 String fieldName = fields[i]; 186 if (pd == null) 187 { 188 pd = findPropertyDescriptor(getDeclaringClass(), fieldName); 189 } 190 else 191 { 192 pd = findPropertyDescriptor(pd.getPropertyType(), fieldName); 193 } 194 result.add(pd); 195 } 196 return result; 197 } 198 199 202 protected static PropertyDescriptor findPropertyDescriptor(Class aClass, String aPropertyName) 203 { 204 BeanInfo info; 205 PropertyDescriptor [] pd; 206 PropertyDescriptor descriptor = null; 207 208 try 209 { 210 info = Introspector.getBeanInfo(aClass); 211 pd = info.getPropertyDescriptors(); 212 for (int i = 0; i < pd.length; i++) 213 { 214 if (pd[i].getName().equals(aPropertyName)) 215 { 216 descriptor = pd[i]; 217 break; 218 } 219 } 220 if (descriptor == null) 221 { 222 226 throw new MetadataException("Can't find property " + aPropertyName + " in " + aClass.getName()); 227 } 228 return descriptor; 229 } 230 catch (IntrospectionException ex) 231 { 232 236 throw new MetadataException("Can't find property " + aPropertyName + " in " + aClass.getName(), ex); 237 } 238 } 239 240 245 protected PropertyDescriptor getPropertyDescriptor() 246 { 247 return (PropertyDescriptor ) getPropertyGraph().get(getPropertyGraph().size() - 1); 248 } 249 250 253 public boolean makeAccessible() 254 { 255 return false; 256 } 257 258 263 public boolean usesAccessorsAndMutators() 264 { 265 return true; 266 } 267 268 271 protected void logProblem(PropertyDescriptor pd, Object anObject, Object aValue, String msg) 272 { 273 Logger logger = getLog(); 274 logger.error("Error in [PersistentFieldPropertyImpl], " + msg); 275 logger.error("Declaring class [" + getDeclaringClass().getName() + "]"); 276 logger.error("Property Name [" + getName() + "]"); 277 logger.error("Property Type [" + pd.getPropertyType().getName() + "]"); 278 279 if (anObject != null) 280 { 281 logger.error("anObject was class [" + anObject.getClass().getName() + "]"); 282 } 283 else 284 { 285 logger.error("anObject was null"); 286 } 287 if (aValue != null) 288 { 289 logger.error("aValue was class [" + aValue.getClass().getName() + "]"); 290 } 291 else 292 { 293 logger.error("aValue was null"); 294 } 295 } 296 } 297 | Popular Tags |