1 19 20 package org.apache.cayenne.reflect; 21 22 import java.beans.BeanInfo ; 23 import java.beans.IntrospectionException ; 24 import java.beans.Introspector ; 25 import java.beans.PropertyDescriptor ; 26 import java.lang.reflect.InvocationTargetException ; 27 import java.lang.reflect.Method ; 28 import java.util.Map ; 29 import java.util.StringTokenizer ; 30 31 import org.apache.cayenne.CayenneRuntimeException; 32 import org.apache.cayenne.map.Entity; 33 import org.apache.cayenne.util.Util; 34 35 44 public class PropertyUtils { 45 46 50 public static Object getProperty(Object object, String nestedPropertyName) 51 throws CayenneRuntimeException { 52 53 if (object == null) { 54 throw new IllegalArgumentException ("Null object."); 55 } 56 57 if (Util.isEmptyString(nestedPropertyName)) { 58 throw new IllegalArgumentException ("Null or empty property name."); 59 } 60 61 StringTokenizer path = new StringTokenizer ( 62 nestedPropertyName, 63 Entity.PATH_SEPARATOR); 64 int len = path.countTokens(); 65 66 Object value = object; 67 String pathSegment = null; 68 69 try { 70 for (int i = 1; i <= len; i++) { 71 pathSegment = path.nextToken(); 72 73 if (value == null) { 74 throw new CayenneRuntimeException( 76 "Null value in the middle of the path"); 77 } 78 79 value = getSimpleProperty(value, pathSegment); 80 } 81 82 return value; 83 } 84 catch (Exception e) { 85 String objectType = value != null ? value.getClass().getName() : "<null>"; 86 throw new CayenneRuntimeException("Error reading property segment '" 87 + pathSegment 88 + "' in path '" 89 + nestedPropertyName 90 + "' for type " 91 + objectType, e); 92 } 93 } 94 95 101 public static void setProperty(Object object, String nestedPropertyName, Object value) 102 throws CayenneRuntimeException { 103 104 if (object == null) { 105 throw new IllegalArgumentException ("Null object."); 106 } 107 108 if (Util.isEmptyString(nestedPropertyName)) { 109 throw new IllegalArgumentException ("Null or invalid property name."); 110 } 111 112 int dot = nestedPropertyName.lastIndexOf(Entity.PATH_SEPARATOR); 113 String lastSegment; 114 if (dot > 0) { 115 lastSegment = nestedPropertyName.substring(dot + 1); 116 String pathSegment = nestedPropertyName.substring(0, dot); 117 object = getProperty(object, pathSegment); 118 119 if (object == null) { 120 throw new IllegalArgumentException ( 121 "Null object at the end of the segment '" + pathSegment + "'"); 122 } 123 } 124 else { 125 lastSegment = nestedPropertyName; 126 } 127 128 try { 129 setSimpleProperty(object, lastSegment, value); 130 } 131 catch (Exception e) { 132 throw new CayenneRuntimeException("Error setting property segment '" 133 + lastSegment 134 + "' in path '" 135 + nestedPropertyName 136 + "'", e); 137 } 138 139 } 140 141 static Object getSimpleProperty(Object object, String pathSegment) 142 throws IntrospectionException , IllegalArgumentException , 143 IllegalAccessException , InvocationTargetException { 144 145 PropertyDescriptor descriptor = getPropertyDescriptor( 146 object.getClass(), 147 pathSegment); 148 149 if (descriptor != null) { 150 Method reader = descriptor.getReadMethod(); 151 152 if (reader == null) { 153 throw new IntrospectionException ("Unreadable property '" 154 + pathSegment 155 + "'"); 156 } 157 158 return reader.invoke(object, null); 159 } 160 else if (object instanceof Map ) { 163 return ((Map ) object).get(pathSegment); 164 } 165 else { 166 throw new IntrospectionException ("No property '" 167 + pathSegment 168 + "' found in class " 169 + object.getClass().getName()); 170 } 171 } 172 173 static void setSimpleProperty(Object object, String pathSegment, Object value) 174 throws IntrospectionException , IllegalArgumentException , 175 IllegalAccessException , InvocationTargetException { 176 177 PropertyDescriptor descriptor = getPropertyDescriptor( 178 object.getClass(), 179 pathSegment); 180 181 if (descriptor != null) { 182 Method writer = descriptor.getWriteMethod(); 183 184 if (writer == null) { 185 throw new IntrospectionException ("Unwritable property '" 186 + pathSegment 187 + "'"); 188 } 189 190 192 value = ConverterFactory.factory 193 .getConverter(descriptor.getPropertyType()) 194 .convert(value, descriptor.getPropertyType()); 195 196 writer.invoke(object, new Object [] { 198 value 199 }); 200 } 201 else if (object instanceof Map ) { 204 ((Map ) object).put(pathSegment, value); 205 } 206 else { 207 throw new IntrospectionException ("No property '" 208 + pathSegment 209 + "' found in class " 210 + object.getClass().getName()); 211 } 212 } 213 214 static PropertyDescriptor getPropertyDescriptor(Class beanClass, String propertyName) 215 throws IntrospectionException { 216 BeanInfo info = Introspector.getBeanInfo(beanClass); 219 PropertyDescriptor [] descriptors = info.getPropertyDescriptors(); 220 221 for (int i = 0; i < descriptors.length; i++) { 222 if (propertyName.equals(descriptors[i].getName())) { 223 return descriptors[i]; 224 } 225 } 226 227 return null; 228 } 229 230 233 static Class normalizeType(Class type) { 234 if (type.isPrimitive()) { 235 236 String className = type.getName(); 237 if ("byte".equals(className)) { 238 return Byte .class; 239 } 240 else if ("int".equals(className)) { 241 return Integer .class; 242 } 243 else if ("short".equals(className)) { 244 return Short .class; 245 } 246 else if ("char".equals(className)) { 247 return Character .class; 248 } 249 else if ("double".equals(className)) { 250 return Double .class; 251 } 252 else if ("float".equals(className)) { 253 return Float .class; 254 } 255 else if ("boolean".equals(className)) { 256 return Boolean .class; 257 } 258 } 259 260 return type; 261 } 262 263 267 static Object defaultNullValueForType(Class type) { 268 if (type.isPrimitive()) { 269 270 String className = type.getName(); 271 if ("byte".equals(className)) { 272 return new Byte ((byte) 0); 273 } 274 else if ("int".equals(className)) { 275 return new Integer (0); 276 } 277 else if ("short".equals(className)) { 278 return new Short ((short) 0); 279 } 280 else if ("char".equals(className)) { 281 return new Character ((char) 0); 282 } 283 else if ("double".equals(className)) { 284 return new Double (0d); 285 } 286 else if ("float".equals(className)) { 287 return new Float (0f); 288 } 289 else if ("boolean".equals(className)) { 290 return Boolean.FALSE; 291 } 292 } 293 294 return null; 295 } 296 297 private PropertyUtils() { 298 super(); 299 } 300 } 301 | Popular Tags |