1 21 package com.db4o; 22 23 import com.db4o.ext.*; 24 import com.db4o.foundation.*; 25 import com.db4o.inside.SystemData; 26 import com.db4o.reflect.*; 27 28 31 public final class YapClassCollection extends YapMeta { 32 33 private Collection4 i_classes; 34 private Hashtable4 i_creating; 35 36 private final Transaction _systemTransaction; 37 38 private Hashtable4 i_yapClassByBytes; 39 private Hashtable4 i_yapClassByClass; 40 private Hashtable4 i_yapClassByID; 41 42 private int i_yapClassCreationDepth; 43 private Queue4 i_initYapClassesOnUp; 44 45 private final PendingClassInits _classInits; 46 47 48 YapClassCollection(Transaction systemTransaction) { 49 _systemTransaction = systemTransaction; 50 i_initYapClassesOnUp = new Queue4(); 51 _classInits = new PendingClassInits(_systemTransaction); 52 } 53 54 public void addYapClass(YapClass yapClass) { 55 stream().setDirtyInSystemTransaction(this); 56 i_classes.add(yapClass); 57 if(yapClass.stateUnread()){ 58 i_yapClassByBytes.put(yapClass.i_nameBytes, yapClass); 59 }else{ 60 i_yapClassByClass.put(yapClass.classReflector(), yapClass); 61 } 62 if (yapClass.getID() == 0) { 63 yapClass.write(_systemTransaction); 64 } 65 i_yapClassByID.put(yapClass.getID(), yapClass); 66 } 67 68 private byte[] asBytes(String str){ 69 return stream().stringIO().write(str); 70 } 71 72 void attachQueryNode(final String fieldName, final Visitor4 a_visitor) { 73 YapClassCollectionIterator i = iterator(); 74 while (i.moveNext()) { 75 final YapClass yc = i.currentClass(); 76 if(! yc.isInternal()){ 77 yc.forEachYapField(new Visitor4() { 78 public void visit(Object obj) { 79 YapField yf = (YapField)obj; 80 if(yf.canAddToQuery(fieldName)){ 81 a_visitor.visit(new Object [] {yc, yf}); 82 } 83 } 84 }); 85 } 86 } 87 } 88 89 void checkChanges() { 90 Iterator4 i = i_classes.iterator(); 91 while (i.moveNext()) { 92 ((YapClass)i.current()).checkChanges(); 93 } 94 } 95 96 final boolean createYapClass(YapClass a_yapClass, ReflectClass a_class) { 97 i_yapClassCreationDepth++; 98 ReflectClass superClass = a_class.getSuperclass(); 99 YapClass superYapClass = null; 100 if (superClass != null && ! superClass.equals(stream().i_handlers.ICLASS_OBJECT)) { 101 superYapClass = produceYapClass(superClass); 102 } 103 boolean ret = stream().createYapClass(a_yapClass, a_class, superYapClass); 104 i_yapClassCreationDepth--; 105 initYapClassesOnUp(); 106 return ret; 107 } 108 109 public static void defrag(ReaderPair readers) { 110 if (Deploy.debug) { 111 readers.readBegin(YapConst.YAPCLASSCOLLECTION); 112 } 113 int numClasses=readers.readInt(); 114 for(int classIdx=0;classIdx<numClasses;classIdx++) { 115 readers.copyID(); 116 } 117 if (Deploy.debug) { 118 readers.readEnd(); 119 } 120 } 121 122 private void ensureAllClassesRead() { 123 boolean allClassesRead=false; 124 while(!allClassesRead) { 125 Collection4 unreadClasses=new Collection4(); 126 int numClasses=i_classes.size(); 127 Iterator4 classIter = i_classes.iterator(); 128 while(classIter.moveNext()) { 129 YapClass yapClass=(YapClass)classIter.current(); 130 if(yapClass.stateUnread()) { 131 unreadClasses.add(yapClass); 132 } 133 } 134 Iterator4 unreadIter=unreadClasses.iterator(); 135 while(unreadIter.moveNext()) { 136 YapClass yapClass=(YapClass)unreadIter.current(); 137 readYapClass(yapClass,null); 138 if(yapClass.classReflector() == null){ 139 yapClass.forceRead(); 140 } 141 } 142 allClassesRead=(i_classes.size()==numClasses); 143 } 144 applyReadAs(); 145 } 146 147 boolean fieldExists(String a_field) { 148 YapClassCollectionIterator i = iterator(); 149 while (i.moveNext()) { 150 if (i.currentClass().getYapField(a_field) != null) { 151 return true; 152 } 153 } 154 return false; 155 } 156 157 Collection4 forInterface(ReflectClass claxx) { 158 Collection4 col = new Collection4(); 159 YapClassCollectionIterator i = iterator(); 160 while (i.moveNext()) { 161 YapClass yc = i.currentClass(); 162 ReflectClass candidate = yc.classReflector(); 163 if(! candidate.isInterface()){ 164 if (claxx.isAssignableFrom(candidate)) { 165 col.add(yc); 166 Iterator4 j = new Collection4(col).iterator(); 167 while (j.moveNext()) { 168 YapClass existing = (YapClass)j.current(); 169 if(existing != yc){ 170 YapClass higher = yc.getHigherHierarchy(existing); 171 if (higher != null) { 172 if (higher == yc) { 173 col.remove(existing); 174 }else{ 175 col.remove(yc); 176 } 177 } 178 } 179 } 180 } 181 } 182 } 183 return col; 184 } 185 186 public byte getIdentifier() { 187 return YapConst.YAPCLASSCOLLECTION; 188 } 189 190 YapClass getActiveYapClass(ReflectClass a_class) { 191 return (YapClass)i_yapClassByClass.get(a_class); 192 } 193 194 YapClass getYapClass (ReflectClass a_class) { 195 YapClass yapClass = (YapClass)i_yapClassByClass.get(a_class); 196 if (yapClass != null) { 197 return yapClass; 198 } 199 yapClass = (YapClass)i_yapClassByBytes.remove(getNameBytes(a_class.getName())); 200 readYapClass(yapClass, a_class); 201 return yapClass; 202 } 203 204 YapClass produceYapClass(ReflectClass a_class) { 205 206 YapClass yapClass = getYapClass(a_class); 207 208 if (yapClass != null ) { 209 return yapClass; 210 } 211 212 yapClass = (YapClass)i_creating.get(a_class); 213 214 if(yapClass != null){ 215 return yapClass; 216 } 217 218 yapClass = new YapClass(stream(), a_class); 219 220 i_creating.put(a_class, yapClass); 221 222 if(! createYapClass(yapClass, a_class)){ 223 i_creating.remove(a_class); 224 return null; 225 } 226 227 230 boolean addMembers = false; 231 232 if (i_yapClassByClass.get(a_class) == null) { 233 addYapClass(yapClass); 234 addMembers = true; 235 } 236 237 int id = yapClass.getID(); 238 if(id == 0){ 239 yapClass.write(stream().getSystemTransaction()); 240 id = yapClass.getID(); 241 } 242 243 if(i_yapClassByID.get(id) == null){ 244 i_yapClassByID.put(id, yapClass); 245 addMembers = true; 246 } 247 248 if(addMembers || yapClass.i_fields == null){ 249 _classInits.process(yapClass); 250 } 251 252 i_creating.remove(a_class); 253 254 stream().setDirtyInSystemTransaction(this); 255 256 return yapClass; 257 } 258 259 YapClass getYapClass(int id) { 260 return readYapClass((YapClass)i_yapClassByID.get(id), null); 261 } 262 263 public YapClass getYapClass(String a_name) { 264 YapClass yapClass = (YapClass)i_yapClassByBytes.remove(getNameBytes(a_name)); 265 readYapClass(yapClass, null); 266 if (yapClass == null) { 267 YapClassCollectionIterator i = iterator(); 268 while (i.moveNext()) { 269 yapClass = (YapClass)i.current(); 270 if (a_name.equals(yapClass.getName())) { 271 readYapClass(yapClass, null); 272 return yapClass; 273 } 274 } 275 return null; 276 } 277 return yapClass; 278 } 279 280 public int getYapClassID(String name){ 281 YapClass yc = (YapClass)i_yapClassByBytes.get(getNameBytes(name)); 282 if(yc != null){ 283 return yc.getID(); 284 } 285 return 0; 286 } 287 288 byte[] getNameBytes(String name) { 289 return asBytes(resolveAliasRuntimeName(name)); 290 } 291 292 private String resolveAliasRuntimeName(String name) { 293 return stream().configImpl().resolveAliasRuntimeName(name); 294 } 295 296 void initOnUp(Transaction systemTrans) { 297 i_yapClassCreationDepth++; 298 systemTrans.stream().showInternalClasses(true); 299 Iterator4 i = i_classes.iterator(); 300 while (i.moveNext()) { 301 ((YapClass)i.current()).initOnUp(systemTrans); 302 } 303 systemTrans.stream().showInternalClasses(false); 304 i_yapClassCreationDepth--; 305 initYapClassesOnUp(); 306 } 307 308 void initTables(int a_size) { 309 i_classes = new Collection4(); 310 i_yapClassByBytes = new Hashtable4(a_size); 311 if (a_size < 16) { 312 a_size = 16; 313 } 314 i_yapClassByClass = new Hashtable4(a_size); 315 i_yapClassByID = new Hashtable4(a_size); 316 i_creating = new Hashtable4(1); 317 } 318 319 private void initYapClassesOnUp() { 320 if(i_yapClassCreationDepth == 0){ 321 YapClass yc = (YapClass)i_initYapClassesOnUp.next(); 322 while(yc != null){ 323 yc.initOnUp(_systemTransaction); 324 yc = (YapClass)i_initYapClassesOnUp.next(); 325 } 326 } 327 } 328 329 public YapClassCollectionIterator iterator(){ 330 return new YapClassCollectionIterator(this, new ArrayIterator4(i_classes.toArray())); 331 } 332 333 private static class ClassIDIterator extends MappingIterator { 334 335 public ClassIDIterator(Collection4 classes) { 336 super(classes.iterator()); 337 } 338 339 protected Object map(Object current) { 340 return new Integer (((YapClass)current).getID()); 341 } 342 } 343 344 public Iterator4 ids(){ 345 return new ClassIDIterator(i_classes); 346 } 347 348 public int ownLength() { 349 return YapConst.OBJECT_LENGTH 350 + YapConst.INT_LENGTH 351 + (i_classes.size() * YapConst.ID_LENGTH); 352 } 353 354 void purge() { 355 Iterator4 i = i_classes.iterator(); 356 while (i.moveNext()) { 357 ((YapClass)i.current()).purge(); 358 } 359 } 360 361 public final void readThis(Transaction a_trans, YapReader a_reader) { 362 int classCount = a_reader.readInt(); 363 364 initTables(classCount); 365 366 for (int i = classCount; i > 0; i--) { 367 YapClass yapClass = new YapClass(stream(), null); 368 int id = a_reader.readInt(); 369 yapClass.setID(id); 370 i_classes.add(yapClass); 371 i_yapClassByID.put(id, yapClass); 372 i_yapClassByBytes.put(yapClass.readName(a_trans), yapClass); 373 } 374 375 applyReadAs(); 376 377 } 378 379 Hashtable4 classByBytes(){ 380 return i_yapClassByBytes; 381 } 382 383 private void applyReadAs(){ 384 final Hashtable4 readAs = stream().configImpl().readAs(); 385 readAs.forEachKey(new Visitor4() { 386 public void visit(Object a_object) { 387 String dbName = (String )a_object; 388 byte[] dbbytes = getNameBytes(dbName); 389 String useName = (String )readAs.get(dbName); 390 byte[] useBytes = getNameBytes(useName); 391 if(classByBytes().get(useBytes) == null){ 392 YapClass yc = (YapClass)classByBytes().get(dbbytes); 393 if(yc != null){ 394 yc.i_nameBytes = useBytes; 395 yc.setConfig(stream().configImpl().configClass(dbName)); 396 classByBytes().put(dbbytes, null); 397 classByBytes().put(useBytes, yc); 398 } 399 } 400 } 401 }); 402 } 403 404 public YapClass readYapClass(YapClass yapClass, ReflectClass a_class) { 405 if(yapClass == null){ 406 return null; 407 } 408 if (! yapClass.stateUnread()) { 409 return yapClass; 410 } 411 i_yapClassCreationDepth++; 412 yapClass.createConfigAndConstructor(i_yapClassByBytes, stream(), a_class); 413 ReflectClass claxx = yapClass.classReflector(); 414 if(claxx != null){ 415 i_yapClassByClass.put(claxx, yapClass); 416 yapClass.readThis(); 417 yapClass.checkChanges(); 418 i_initYapClassesOnUp.add(yapClass); 419 } 420 i_yapClassCreationDepth--; 421 initYapClassesOnUp(); 422 return yapClass; 423 } 424 425 public void refreshClasses() { 426 YapClassCollection rereader = new YapClassCollection(_systemTransaction); 427 rereader.i_id = i_id; 428 rereader.read(stream().getSystemTransaction()); 429 Iterator4 i = rereader.i_classes.iterator(); 430 while (i.moveNext()) { 431 YapClass yc = (YapClass)i.current(); 432 if (i_yapClassByID.get(yc.getID()) == null) { 433 i_classes.add(yc); 434 i_yapClassByID.put(yc.getID(), yc); 435 if(yc.stateUnread()){ 436 i_yapClassByBytes.put(yc.readName(_systemTransaction), yc); 437 }else{ 438 i_yapClassByClass.put(yc.classReflector(), yc); 439 } 440 } 441 } 442 i = i_classes.iterator(); 443 while (i.moveNext()) { 444 YapClass yc = (YapClass)i.current(); 445 yc.refresh(); 446 } 447 } 448 449 void reReadYapClass(YapClass yapClass){ 450 if(yapClass != null){ 451 reReadYapClass(yapClass.i_ancestor); 452 yapClass.readName(_systemTransaction); 453 yapClass.forceRead(); 454 yapClass.setStateClean(); 455 yapClass.bitFalse(YapConst.CHECKED_CHANGES); 456 yapClass.bitFalse(YapConst.READING); 457 yapClass.bitFalse(YapConst.CONTINUE); 458 yapClass.bitFalse(YapConst.DEAD); 459 yapClass.checkChanges(); 460 } 461 } 462 463 public StoredClass[] storedClasses() { 464 ensureAllClassesRead(); 465 StoredClass[] sclasses = new StoredClass[i_classes.size()]; 466 i_classes.toArray(sclasses); 467 return sclasses; 468 } 469 470 public void writeAllClasses(){ 471 StoredClass[] storedClasses = storedClasses(); 472 for (int i = 0; i < storedClasses.length; i++) { 473 YapClass yc = (YapClass)storedClasses[i]; 474 yc.setStateDirty(); 475 } 476 477 for (int i = 0; i < storedClasses.length; i++) { 478 YapClass yc = (YapClass)storedClasses[i]; 479 yc.write(_systemTransaction); 480 } 481 } 482 483 public void writeThis(Transaction trans, YapReader a_writer) { 484 a_writer.writeInt(i_classes.size()); 485 Iterator4 i = i_classes.iterator(); 486 while (i.moveNext()) { 487 a_writer.writeIDOf(trans, i.current()); 488 } 489 } 490 491 public String toString(){ 492 if(! Debug4.prettyToStrings){ 493 return super.toString(); 494 } 495 String str = "Active:\n"; 496 Iterator4 i = i_classes.iterator(); 497 while(i.moveNext()){ 498 YapClass yc = (YapClass)i.current(); 499 str += yc.getID() + " " + yc + "\n"; 500 } 501 return str; 502 } 503 504 YapStream stream() { 505 return _systemTransaction.stream(); 506 } 507 508 public void setID(int a_id) { 509 if (stream().isClient()) { 510 super.setID(a_id); 511 return; 512 } 513 514 if(i_id == 0) { 515 systemData().classCollectionID(a_id); 516 } 517 super.setID(a_id); 518 } 519 520 private SystemData systemData() { 521 return _systemTransaction.i_file.systemData(); 522 } 523 524 } 525 | Popular Tags |