1 8 9 package com.sleepycat.persist.impl; 10 11 import java.lang.reflect.AccessibleObject ; 12 import java.lang.reflect.Array ; 13 import java.lang.reflect.Constructor ; 14 import java.lang.reflect.Field ; 15 import java.lang.reflect.InvocationTargetException ; 16 import java.lang.reflect.Modifier ; 17 import java.util.List ; 18 19 24 class ReflectionAccessor implements Accessor { 25 26 private static final FieldAccess[] EMPTY_KEYS = {}; 27 28 private Class type; 29 private Accessor superAccessor; 30 private Constructor constructor; 31 private FieldAccess priKey; 32 private FieldAccess[] secKeys; 33 private FieldAccess[] nonKeys; 34 35 private ReflectionAccessor(Class type, Accessor superAccessor) { 36 this.type = type; 37 this.superAccessor = superAccessor; 38 try { 39 constructor = type.getDeclaredConstructor(); 40 } catch (NoSuchMethodException e) { 41 throw new IllegalStateException (type.getName()); 42 } 43 if (!Modifier.isPublic(constructor.getModifiers())) { 44 setAccessible(constructor, type.getName() + "()"); 45 } 46 } 47 48 ReflectionAccessor(Catalog catalog, 49 Class type, 50 Accessor superAccessor, 51 FieldInfo priKeyField, 52 List <FieldInfo> secKeyFields, 53 List <FieldInfo> nonKeyFields) { 54 this(type, superAccessor); 55 if (priKeyField != null) { 56 priKey = getField(catalog, priKeyField, true, false); 57 } else { 58 priKey = null; 59 } 60 if (secKeyFields.size() > 0) { 61 secKeys = getFields(catalog, secKeyFields, false, false); 62 } else { 63 secKeys = EMPTY_KEYS; 64 } 65 if (nonKeyFields.size() > 0) { 66 nonKeys = getFields(catalog, nonKeyFields, false, false); 67 } else { 68 nonKeys = EMPTY_KEYS; 69 } 70 } 71 72 ReflectionAccessor(Catalog catalog, 73 Class type, 74 List <FieldInfo> fieldInfos) { 75 this(type, null); 76 priKey = null; 77 secKeys = EMPTY_KEYS; 78 nonKeys = getFields(catalog, fieldInfos, true, true); 79 } 80 81 private FieldAccess[] getFields(Catalog catalog, 82 List <FieldInfo> fieldInfos, 83 boolean isRequiredKeyField, 84 boolean isCompositeKey) { 85 int index = 0; 86 FieldAccess[] fields = new FieldAccess[fieldInfos.size()]; 87 for (FieldInfo info : fieldInfos) { 88 fields[index] = getField 89 (catalog, info, isRequiredKeyField, isCompositeKey); 90 index += 1; 91 } 92 return fields; 93 } 94 95 private FieldAccess getField(Catalog catalog, 96 FieldInfo fieldInfo, 97 boolean isRequiredKeyField, 98 boolean isCompositeKey) { 99 Field field; 100 try { 101 field = type.getDeclaredField(fieldInfo.getName()); 102 } catch (NoSuchFieldException e) { 103 throw new IllegalStateException (e); 104 } 105 if (!Modifier.isPublic(field.getModifiers())) { 106 setAccessible(field, field.getName()); 107 } 108 Class fieldCls = field.getType(); 109 if (fieldCls.isPrimitive()) { 110 assert SimpleCatalog.isSimpleType(fieldCls); 111 return new PrimitiveAccess 112 (field, SimpleCatalog.getSimpleFormat(fieldCls)); 113 } else if (isRequiredKeyField) { 114 Format format = catalog.getFormat(fieldCls); 115 if (isCompositeKey && !SimpleCatalog.isSimpleType(fieldCls)) { 116 throw new IllegalArgumentException 117 ("Composite key class has non-simple type field: " + 118 type.getName() + '.' + field.getName()); 119 } 120 return new KeyObjectAccess(field, format); 121 } else { 122 return new ObjectAccess(field); 123 } 124 } 125 126 private void setAccessible(AccessibleObject object, String memberName) { 127 try { 128 object.setAccessible(true); 129 } catch (SecurityException e) { 130 throw new IllegalStateException 131 ("Unable to access non-public member: " + 132 type.getName() + '.' + memberName + 133 ". Please configure the Java Security Manager setting: " + 134 " ReflectPermission suppressAccessChecks", e); 135 } 136 } 137 138 public Object newInstance() { 139 try { 140 return constructor.newInstance(); 141 } catch (IllegalAccessException e) { 142 throw new IllegalStateException (e); 143 } catch (InstantiationException e) { 144 throw new IllegalStateException (e); 145 } catch (InvocationTargetException e) { 146 throw new IllegalStateException (e); 147 } 148 } 149 150 public Object newArray(int len) { 151 return Array.newInstance(type, len); 152 } 153 154 public boolean isPriKeyFieldNullOrZero(Object o) { 155 try { 156 if (priKey != null) { 157 return priKey.isNullOrZero(o); 158 } else if (superAccessor != null) { 159 return superAccessor.isPriKeyFieldNullOrZero(o); 160 } else { 161 throw new IllegalStateException ("No primary key field"); 162 } 163 } catch (IllegalAccessException e) { 164 throw new IllegalStateException (e); 165 } 166 } 167 168 public void writePriKeyField(Object o, EntityOutput output) { 169 try { 170 if (priKey != null) { 171 priKey.write(o, output); 172 } else if (superAccessor != null) { 173 superAccessor.writePriKeyField(o, output); 174 } else { 175 throw new IllegalStateException ("No primary key field"); 176 } 177 } catch (IllegalAccessException e) { 178 throw new IllegalStateException (e); 179 } 180 } 181 182 public void readPriKeyField(Object o, EntityInput input) { 183 try { 184 if (priKey != null) { 185 priKey.read(o, input); 186 } else if (superAccessor != null) { 187 superAccessor.readPriKeyField(o, input); 188 } else { 189 throw new IllegalStateException ("No primary key field"); 190 } 191 } catch (IllegalAccessException e) { 192 throw new IllegalStateException (e); 193 } 194 } 195 196 public void writeSecKeyFields(Object o, EntityOutput output) { 197 try { 198 if (priKey != null && !priKey.isPrimitive) { 199 output.registerPriKeyObject(priKey.field.get(o)); 200 } 201 if (superAccessor != null) { 202 superAccessor.writeSecKeyFields(o, output); 203 } 204 for (int i = 0; i < secKeys.length; i += 1) { 205 secKeys[i].write(o, output); 206 } 207 } catch (IllegalAccessException e) { 208 throw new IllegalStateException (e); 209 } 210 } 211 212 public void readSecKeyFields(Object o, 213 EntityInput input, 214 int startField, 215 int endField, 216 int superLevel) { 217 try { 218 if (priKey != null && !priKey.isPrimitive) { 219 input.registerPriKeyObject(priKey.field.get(o)); 220 } 221 if (superLevel != 0 && superAccessor != null) { 222 superAccessor.readSecKeyFields 223 (o, input, startField, endField, superLevel - 1); 224 } else { 225 if (superLevel > 0) { 226 throw new IllegalStateException 227 ("Superclass does not exist"); 228 } 229 } 230 if (superLevel <= 0) { 231 for (int i = startField; 232 i <= endField && i < secKeys.length; 233 i += 1) { 234 secKeys[i].read(o, input); 235 } 236 } 237 } catch (IllegalAccessException e) { 238 throw new IllegalStateException (e); 239 } 240 } 241 242 public void writeNonKeyFields(Object o, EntityOutput output) { 243 try { 244 if (superAccessor != null) { 245 superAccessor.writeNonKeyFields(o, output); 246 } 247 for (int i = 0; i < nonKeys.length; i += 1) { 248 nonKeys[i].write(o, output); 249 } 250 } catch (IllegalAccessException e) { 251 throw new IllegalStateException (e); 252 } 253 } 254 255 public void readNonKeyFields(Object o, 256 EntityInput input, 257 int startField, 258 int endField, 259 int superLevel) { 260 try { 261 if (superLevel != 0 && superAccessor != null) { 262 superAccessor.readNonKeyFields 263 (o, input, startField, endField, superLevel - 1); 264 } else { 265 if (superLevel > 0) { 266 throw new IllegalStateException 267 ("Superclass does not exist"); 268 } 269 } 270 if (superLevel <= 0) { 271 for (int i = startField; 272 i <= endField && i < nonKeys.length; 273 i += 1) { 274 nonKeys[i].read(o, input); 275 } 276 } 277 } catch (IllegalAccessException e) { 278 throw new IllegalStateException (e); 279 } 280 } 281 282 public Object getField(Object o, 283 int field, 284 int superLevel, 285 boolean isSecField) { 286 if (superLevel > 0) { 287 return superAccessor.getField 288 (o, field, superLevel - 1, isSecField); 289 } 290 try { 291 Field fld = isSecField ? secKeys[field].field 292 : nonKeys[field].field; 293 return fld.get(o); 294 } catch (IllegalAccessException e) { 295 throw new IllegalStateException (e); 296 } 297 } 298 299 public void setField(Object o, 300 int field, 301 int superLevel, 302 boolean isSecField, 303 Object value) { 304 if (superLevel > 0) { 305 superAccessor.setField 306 (o, field, superLevel - 1, isSecField, value); 307 } 308 try { 309 Field fld = isSecField ? secKeys[field].field 310 : nonKeys[field].field; 311 fld.set(o, value); 312 } catch (IllegalAccessException e) { 313 throw new IllegalStateException (e); 314 } 315 } 316 317 320 private static abstract class FieldAccess { 321 322 Field field; 323 boolean isPrimitive; 324 325 FieldAccess(Field field) { 326 this.field = field; 327 isPrimitive = field.getType().isPrimitive(); 328 } 329 330 333 abstract void write(Object o, EntityOutput out) 334 throws IllegalAccessException ; 335 336 339 abstract void read(Object o, EntityInput in) 340 throws IllegalAccessException ; 341 342 347 boolean isNullOrZero(Object o) 348 throws IllegalAccessException { 349 350 return field.get(o) == null; 351 } 352 } 353 354 357 private static class ObjectAccess extends FieldAccess { 358 359 ObjectAccess(Field field) { 360 super(field); 361 } 362 363 @Override 364 void write(Object o, EntityOutput out) 365 throws IllegalAccessException { 366 367 out.writeObject(field.get(o), null); 368 } 369 370 @Override 371 void read(Object o, EntityInput in) 372 throws IllegalAccessException { 373 374 field.set(o, in.readObject()); 375 } 376 } 377 378 382 private static class KeyObjectAccess extends FieldAccess { 383 384 private Format format; 385 386 KeyObjectAccess(Field field, Format format) { 387 super(field); 388 this.format = format; 389 } 390 391 @Override 392 void write(Object o, EntityOutput out) 393 throws IllegalAccessException { 394 395 out.writeKeyObject(field.get(o), format); 396 } 397 398 @Override 399 void read(Object o, EntityInput in) 400 throws IllegalAccessException { 401 402 field.set(o, in.readKeyObject(format)); 403 } 404 } 405 406 409 private static class PrimitiveAccess extends FieldAccess { 410 411 private SimpleFormat format; 412 413 PrimitiveAccess(Field field, SimpleFormat format) { 414 super(field); 415 this.format = format; 416 } 417 418 @Override 419 void write(Object o, EntityOutput out) 420 throws IllegalAccessException { 421 422 format.writePrimitiveField(o, out, field); 423 } 424 425 @Override 426 void read(Object o, EntityInput in) 427 throws IllegalAccessException { 428 429 format.readPrimitiveField(o, in, field); 430 } 431 432 @Override 433 boolean isNullOrZero(Object o) 434 throws IllegalAccessException { 435 436 return field.getLong(o) == 0; 437 } 438 } 439 } 440 | Popular Tags |