1 21 package com.db4o.reflect.generic; 22 23 import com.db4o.*; 24 import com.db4o.foundation.*; 25 import com.db4o.inside.marshall.*; 26 import com.db4o.reflect.*; 27 28 31 public class GenericReflector implements Reflector, DeepClone { 32 33 private Reflector _delegate; 34 private GenericArrayReflector _array; 35 36 private final Hashtable4 _classByName = new Hashtable4(); 37 private final Hashtable4 _classByClass = new Hashtable4(); 38 private final Collection4 _classes = new Collection4(); 39 private final Hashtable4 _classByID = new Hashtable4(); 40 41 private Collection4 _collectionPredicates = new Collection4(); 42 private Collection4 _collectionUpdateDepths = new Collection4(); 43 private Collection4 _pendingClasses = new Collection4(); 44 45 private Transaction _trans; 46 private YapStream _stream; 47 48 public GenericReflector(Transaction trans, Reflector delegateReflector){ 49 setTransaction(trans); 50 _delegate = delegateReflector; 51 if(_delegate != null){ 52 _delegate.setParent(this); 53 } 54 } 55 56 public Object deepClone(Object obj) { 57 GenericReflector myClone = new GenericReflector(null, (Reflector)_delegate.deepClone(this)); 58 myClone._collectionPredicates = (Collection4)_collectionPredicates.deepClone(myClone); 59 myClone._collectionUpdateDepths = (Collection4)_collectionUpdateDepths.deepClone(myClone); 60 61 62 66 67 75 return myClone; 76 } 77 78 YapStream getStream(){ 79 return _stream; 80 } 81 82 public boolean hasTransaction(){ 83 return _trans != null; 84 } 85 86 public void setTransaction(Transaction trans){ 87 if(trans != null){ 88 _trans = trans; 89 _stream = trans.stream(); 90 } 91 } 92 93 public ReflectArray array() { 94 if(_array == null){ 95 _array = new GenericArrayReflector(this); 96 } 97 return _array; 98 } 99 100 public int collectionUpdateDepth(ReflectClass candidate) { 101 Iterator4 i = _collectionUpdateDepths.iterator(); 102 while(i.moveNext()){ 103 CollectionUpdateDepthEntry entry = (CollectionUpdateDepthEntry) i.current(); 104 if (entry._predicate.match(candidate)) { 105 return entry._depth; 106 } 107 } 108 return 2; 109 110 } 112 113 public boolean constructorCallsSupported() { 114 return _delegate.constructorCallsSupported(); 115 } 116 117 GenericClass ensureDelegate(ReflectClass clazz){ 118 if(clazz == null){ 119 return null; 120 } 121 GenericClass claxx = (GenericClass)_classByName.get(clazz.getName()); 122 if(claxx == null){ 123 String name = clazz.getName(); 126 claxx = new GenericClass(this,clazz, name,null); 127 _classes.add(claxx); 128 _classByName.put(name, claxx); 129 } 130 return claxx; 131 } 132 133 public ReflectClass forClass(Class clazz) { 134 if(clazz == null){ 135 return null; 136 } 137 ReflectClass claxx = (ReflectClass) _classByClass.get(clazz); 138 if(claxx != null){ 139 return claxx; 140 } 141 claxx = forName(clazz.getName()); 142 if(claxx != null){ 143 _classByClass.put(clazz, claxx); 144 return claxx; 145 } 146 claxx = _delegate.forClass(clazz); 147 if(claxx == null){ 148 return null; 149 } 150 claxx = ensureDelegate(claxx); 151 _classByClass.put(clazz, claxx); 152 return claxx; 153 } 154 155 156 public ReflectClass forName(String className) { 157 ReflectClass clazz = (ReflectClass)_classByName.get(className); 158 if(clazz != null){ 159 return clazz; 160 } 161 clazz = _delegate.forName(className); 162 if(clazz != null){ 163 return ensureDelegate(clazz); 164 } 165 166 if(_stream == null) { 167 return null; 168 } 169 170 if(_stream.classCollection() != null){ 171 int classID = _stream.classCollection().getYapClassID(className); 172 if(classID > 0){ 173 clazz = ensureClassInitialised(classID); 174 _classByName.put(className, clazz); 175 return clazz; 176 } 177 } 178 179 return null; 180 } 181 182 public ReflectClass forObject(Object obj) { 183 if (obj instanceof GenericObject){ 184 return forGenericObject((GenericObject)obj); 185 } 186 return _delegate.forObject(obj); 187 } 188 189 private ReflectClass forGenericObject(final GenericObject genericObject) { 190 GenericClass claxx = genericObject._class; 191 if(claxx == null){ 192 throw new IllegalStateException (); 193 } 194 String name = claxx.getName(); 195 if(name == null){ 196 throw new IllegalStateException (); 197 } 198 GenericClass existingClass = (GenericClass) _classByName.get(name); 199 if(existingClass == null){ 200 _classByName.put(name, claxx); 201 return claxx; 202 } 203 if(existingClass != claxx){ 206 207 throw new IllegalStateException (); 208 } 209 210 return claxx; 211 } 212 213 public Reflector getDelegate(){ 214 return _delegate; 215 } 216 217 public boolean isCollection(ReflectClass candidate) { 218 Iterator4 i = _collectionPredicates.iterator(); 220 while(i.moveNext()){ 221 if (((ReflectClassPredicate)i.current()).match(candidate)) { 222 return true; 223 } 224 } 225 return _delegate.isCollection(candidate.getDelegate()); 226 227 } 230 231 public void registerCollection(Class clazz) { 232 registerCollection(classPredicate(clazz)); 233 } 234 235 public void registerCollection(ReflectClassPredicate predicate) { 236 _collectionPredicates.add(predicate); 237 } 238 239 private ReflectClassPredicate classPredicate(Class clazz) { 240 final ReflectClass collectionClass = forClass(clazz); 241 ReflectClassPredicate predicate = new ReflectClassPredicate() { 242 public boolean match(ReflectClass candidate) { 243 return collectionClass.isAssignableFrom(candidate); 244 } 245 }; 246 return predicate; 247 } 248 249 public void registerCollectionUpdateDepth(Class clazz, int depth) { 250 registerCollectionUpdateDepth(classPredicate(clazz), depth); 251 } 252 253 public void registerCollectionUpdateDepth(ReflectClassPredicate predicate, int depth) { 254 _collectionUpdateDepths.add(new CollectionUpdateDepthEntry(predicate, depth)); 255 } 256 257 public void register(GenericClass clazz) { 258 String name = clazz.getName(); 259 if(_classByName.get(name) == null){ 260 _classByName.put(name, clazz); 261 _classes.add(clazz); 262 } 263 } 264 265 public ReflectClass[] knownClasses() { 266 readAll(); 267 268 Collection4 classes = new Collection4(); 269 collectKnownClasses(classes); 270 return (ReflectClass[])classes.toArray(new ReflectClass[classes.size()]); 271 } 272 273 private void collectKnownClasses(Collection4 classes) { 274 Iterator4 i = _classes.iterator(); 275 while(i.moveNext()){ 276 GenericClass clazz = (GenericClass)i.current(); 277 if(! _stream.i_handlers.ICLASS_INTERNAL.isAssignableFrom(clazz)){ 278 if(! clazz.isSecondClass()){ 279 if(! clazz.isArray()){ 280 classes.add(clazz); 281 } 282 } 283 } 284 } 285 } 286 287 private void readAll(){ 288 for(Iterator4 idIter=_stream.classCollection().ids();idIter.moveNext();) { 289 ensureClassAvailability(((Integer )idIter.current()).intValue()); 290 } 291 for(Iterator4 idIter=_stream.classCollection().ids();idIter.moveNext();) { 292 ensureClassRead(((Integer )idIter.current()).intValue()); 293 } 294 } 295 296 private GenericClass ensureClassInitialised (int id) { 297 GenericClass ret = ensureClassAvailability(id); 298 while(_pendingClasses.size() > 0) { 299 Collection4 pending = _pendingClasses; 300 _pendingClasses = new Collection4(); 301 Iterator4 i = pending.iterator(); 302 while(i.moveNext()) { 303 ensureClassRead(((Integer )i.current()).intValue()); 304 } 305 } 306 return ret; 307 } 308 309 private GenericClass ensureClassAvailability (int id) { 310 311 if(id == 0){ 312 return null; 313 } 314 315 GenericClass ret = (GenericClass)_classByID.get(id); 316 if(ret != null){ 317 return ret; 318 } 319 320 YapReader classreader=_stream.readWriterByID(_trans,id); 321 322 ClassMarshaller marshaller = marshallerFamily()._class; 323 RawClassSpec spec=marshaller.readSpec(_trans, classreader); 324 325 String className = spec.name(); 326 ret = (GenericClass)_classByName.get(className); 327 if(ret != null){ 328 _classByID.put(id, ret); 329 _pendingClasses.add(new Integer (id)); 330 return ret; 331 } 332 333 ReflectClass nativeClass = _delegate.forName(className); 334 ret = new GenericClass(this, nativeClass,className, ensureClassAvailability(spec.superClassID())); 335 ret.setDeclaredFieldCount(spec.numFields()); 336 337 _classByID.put(id, ret); 339 _pendingClasses.add(new Integer (id)); 340 341 return ret; 342 } 343 344 private MarshallerFamily marshallerFamily() { 345 return MarshallerFamily.forConverterVersion(_stream.converterVersion()); 346 } 347 348 private void ensureClassRead(int id) { 349 350 GenericClass clazz = (GenericClass)_classByID.get(id); 351 352 YapReader classreader=_stream.readWriterByID(_trans,id); 353 354 ClassMarshaller classMarshaller = marshallerFamily()._class; 355 RawClassSpec classInfo=classMarshaller.readSpec(_trans, classreader); 356 String className=classInfo.name(); 357 358 if(_classByName.get(className) != null){ 363 return; 364 } 365 366 _classByName.put(className, clazz); 368 _classes.add(clazz); 369 370 int numFields=classInfo.numFields(); 371 GenericField[] fields=new GenericField[numFields]; 372 FieldMarshaller fieldMarshaller=marshallerFamily()._field; 373 374 for (int i = 0; i < numFields; i++) { 375 376 RawFieldSpec fieldInfo=fieldMarshaller.readSpec(_stream, classreader); 377 String fieldName=fieldInfo.name(); 378 int handlerID=fieldInfo.handlerID(); 379 380 if (fieldInfo.isVirtual()) { 381 fields[i] = new GenericVirtualField(fieldName); 382 continue; 383 } 384 GenericClass fieldClass = null; 385 386 switch (handlerID){ 388 case YapHandlers.ANY_ID: 389 fieldClass = (GenericClass)forClass(Object .class); 390 break; 391 case YapHandlers.ANY_ARRAY_ID: 392 fieldClass = ((GenericClass)forClass(Object .class)).arrayClass(); 393 break; 394 default: 395 ensureClassAvailability(handlerID); 396 fieldClass = (GenericClass)_classByID.get(handlerID); 397 } 398 399 fields[i]=new GenericField(fieldName,fieldClass, fieldInfo.isPrimitive(), fieldInfo.isArray(), fieldInfo.isNArray()); 400 } 401 402 clazz.initFields(fields); 403 } 404 405 406 public void registerPrimitiveClass(int id, String name, GenericConverter converter) { 407 GenericClass existing = (GenericClass)_classByID.get(id); 408 if (existing != null) { 409 if (null != converter) { 410 existing.setSecondClass(); 411 } else { 412 existing.setConverter(null); 413 } 414 return; 415 } 416 ReflectClass clazz = _delegate.forName(name); 417 418 GenericClass claxx = null; 419 if(clazz != null) { 420 claxx = ensureDelegate(clazz); 421 }else { 422 claxx = new GenericClass(this, null, name, null); 423 _classByName.put(name, claxx); 424 claxx.initFields(new GenericField[] {new GenericField(null, null, true, false, false)}); 425 claxx.setConverter(converter); 426 _classes.add(claxx); 427 } 428 claxx.setSecondClass(); 429 claxx.setPrimitive(); 430 _classByID.put(id, claxx); 431 } 432 433 public void setParent(Reflector reflector) { 434 } 436 437 } 438
| Popular Tags
|