KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > db4o > YapClassCollection


1 /* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com
2
3 This file is part of the db4o open source object database.
4
5 db4o is free software; you can redistribute it and/or modify it under
6 the terms of version 2 of the GNU General Public License as published
7 by the Free Software Foundation and as clarified by db4objects' GPL
8 interpretation policy, available at
9 http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
10 Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
11 Suite 350, San Mateo, CA 94403, USA.
12
13 db4o is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

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 /**
29  * @exclude
30  */

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 JavaDoc str){
69         return stream().stringIO().write(str);
70     }
71
72     void attachQueryNode(final String JavaDoc 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 JavaDoc obj) {
79                         YapField yf = (YapField)obj;
80                         if(yf.canAddToQuery(fieldName)){
81                             a_visitor.visit(new Object JavaDoc[] {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 JavaDoc 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         // YapStream#createYapClass may add the YapClass already,
228
// so we have to check again
229

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 JavaDoc 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 JavaDoc 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 JavaDoc name) {
289         return asBytes(resolveAliasRuntimeName(name));
290     }
291
292     private String JavaDoc resolveAliasRuntimeName(String JavaDoc 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 JavaDoc map(Object JavaDoc current) {
340             return new Integer JavaDoc(((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 JavaDoc a_object) {
387                 String JavaDoc dbName = (String JavaDoc)a_object;
388                 byte[] dbbytes = getNameBytes(dbName);
389                 String JavaDoc useName = (String JavaDoc)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 JavaDoc toString(){
492         if(! Debug4.prettyToStrings){
493             return super.toString();
494         }
495         String JavaDoc 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