KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > db4o > YapStreamBase


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.config.Configuration;
24 import com.db4o.config.Entry;
25 import com.db4o.config.QueryEvaluationMode;
26 import com.db4o.cs.ClassMetaHelper;
27 import com.db4o.ext.Db4oDatabase;
28 import com.db4o.ext.Db4oException;
29 import com.db4o.ext.Db4oUUID;
30 import com.db4o.ext.ExtObjectContainer;
31 import com.db4o.ext.MemoryFile;
32 import com.db4o.ext.ObjectInfo;
33 import com.db4o.ext.ObjectNotStorableException;
34 import com.db4o.ext.StoredClass;
35 import com.db4o.ext.SystemInfo;
36 import com.db4o.foundation.IntIdGenerator;
37 import com.db4o.foundation.Iterator4;
38 import com.db4o.foundation.Iterator4Impl;
39 import com.db4o.foundation.List4;
40 import com.db4o.foundation.PersistentTimeStampIdGenerator;
41 import com.db4o.foundation.Tree;
42 import com.db4o.foundation.Visitor4;
43 import com.db4o.inside.Exceptions4;
44 import com.db4o.inside.Global4;
45 import com.db4o.inside.callbacks.Callbacks;
46 import com.db4o.inside.marshall.MarshallerFamily;
47 import com.db4o.inside.query.AbstractQueryResult;
48 import com.db4o.inside.query.NativeQueryHandler;
49 import com.db4o.inside.query.ObjectSetFacade;
50 import com.db4o.inside.query.QueryResult;
51 import com.db4o.inside.replication.Db4oReplicationReferenceProvider;
52 import com.db4o.inside.replication.MigrationConnection;
53 import com.db4o.query.Predicate;
54 import com.db4o.query.Query;
55 import com.db4o.query.QueryComparator;
56 import com.db4o.reflect.ReflectClass;
57 import com.db4o.reflect.generic.GenericReflector;
58 import com.db4o.replication.ReplicationConflictHandler;
59 import com.db4o.replication.ReplicationProcess;
60 import com.db4o.types.Db4oCollections;
61 import com.db4o.types.Db4oType;
62 import com.db4o.types.SecondClass;
63 import com.db4o.types.TransientClass;
64
65 /**
66  * NOTE: This is just a 'partial' base class to allow for variant implementations
67  * in db4oj and db4ojdk1.2. It assumes that itself is an instance of YapStream
68  * and should never be used explicitly.
69  *
70  * @exclude
71  * @sharpen.partial
72  */

73 public abstract class YapStreamBase implements TransientClass, Internal4, YapStreamSpec {
74
75     private boolean i_amDuringFatalExit = false;
76
77     // Collection of all classes
78
// if (i_classCollection == null) the engine is down.
79
protected YapClassCollection _classCollection;
80     
81     protected ClassMetaHelper _classMetaHelper = new ClassMetaHelper();
82
83     // the Configuration context for this ObjectContainer
84
protected Config4Impl i_config;
85
86     // Counts the number of toplevel calls into YapStream
87
private int _stackDepth;
88
89     // Tree of all YapObject references, sorted by IdentityHashCode
90
private YapObject i_hcTree;
91
92     // Tree of all YapObject references, sorted by ID
93
private YapObject i_idTree;
94     private Tree i_justPeeked;
95
96     public final Object JavaDoc i_lock;
97
98     // currently used to resolve self-linking concurrency problems
99
// in cylic links, stores only YapClass objects
100
private List4 i_needsUpdate;
101
102     // the parent ObjectContainer for YapObjectCarrier or this for all
103
// others. Allows identifying the responsible Objectcontainer for IDs
104
final YapStream i_parent;
105
106     // allowed adding refresh with little code changes.
107
boolean i_refreshInsteadOfActivate;
108
109     // a value greater than 0 indicates class implementing the
110
// "Internal" interface are visible in queries and can
111
// be used.
112
int i_showInternalClasses = 0;
113     
114     private List4 i_stillToActivate;
115     private List4 i_stillToDeactivate;
116
117     private List4 i_stillToSet;
118
119     // used for YapClass and YapClassCollection
120
// may be parent or equal to i_trans
121
protected Transaction i_systemTrans;
122
123     // used for Objects
124
protected Transaction i_trans;
125
126     private boolean i_instantiating;
127
128     // all the per-YapStream references that we don't
129
// want created in YapobjectCarrier
130
public YapHandlers i_handlers;
131
132     // One of three constants in ReplicationHandler: NONE, OLD, NEW
133
// Detailed replication variables are stored in i_handlers.
134
// Call state has to be maintained here, so YapObjectCarrier (who shares i_handlers) does
135
// not accidentally think it operates in a replication call.
136
int _replicationCallState;
137
138     // weak reference management
139
YapReferences i_references;
140
141     private NativeQueryHandler _nativeQueryHandler;
142     
143     private final YapStream _this;
144
145     private Callbacks _callbacks = new com.db4o.inside.callbacks.NullCallbacks();
146     
147     protected final PersistentTimeStampIdGenerator _timeStampIdGenerator = new PersistentTimeStampIdGenerator();
148     
149     private int _topLevelCallId = 1;
150     
151     private IntIdGenerator _topLevelCallIdGenerator = new IntIdGenerator();
152
153     protected YapStreamBase(Configuration config,YapStream a_parent) {
154         _this = cast(this);
155         i_parent = a_parent == null ? _this : a_parent;
156         i_lock = a_parent == null ? new Object JavaDoc() : a_parent.i_lock;
157         initializeTransactions();
158         initialize1(config);
159     }
160
161     public void activate(Object JavaDoc a_activate, int a_depth) {
162         synchronized (i_lock) {
163             activate1(null, a_activate, a_depth);
164         }
165     }
166
167     final void activate1(Transaction ta, Object JavaDoc a_activate) {
168         activate1(ta, a_activate, configImpl().activationDepth());
169     }
170
171     public final void activate1(Transaction ta, Object JavaDoc a_activate, int a_depth) {
172         activate2(checkTransaction(ta), a_activate, a_depth);
173     }
174
175     final void activate2(Transaction ta, Object JavaDoc a_activate, int a_depth) {
176         beginTopLevelCall();
177         try {
178             stillToActivate(a_activate, a_depth);
179             activate3CheckStill(ta);
180         } catch (Throwable JavaDoc t) {
181             fatalException(t);
182         }finally{
183             endTopLevelCall();
184         }
185     }
186     
187     final void activate3CheckStill(Transaction ta){
188         while (i_stillToActivate != null) {
189
190             // TODO: Optimize! A lightweight int array would be faster.
191

192             Iterator4 i = new Iterator4Impl(i_stillToActivate);
193             i_stillToActivate = null;
194
195             while (i.moveNext()) {
196                 YapObject yo = (YapObject) i.current();
197                 
198                 i.moveNext();
199                 int depth = ((Integer JavaDoc) i.current()).intValue();
200                 
201                 Object JavaDoc obj = yo.getObject();
202                 if (obj == null) {
203                     removeReference(yo);
204                 } else {
205                     yo.activate1(ta, obj, depth, i_refreshInsteadOfActivate);
206                 }
207             }
208         }
209     }
210     
211     public int alignToBlockSize(int length){
212         return blocksFor(length) * blockSize();
213     }
214
215     public void bind(Object JavaDoc obj, long id) {
216         synchronized (i_lock) {
217             bind1(null, obj, id);
218         }
219     }
220
221     /** TODO: This is not transactional yet. */
222     final void bind1(Transaction ta, Object JavaDoc obj, long id) {
223         
224         if(DTrace.enabled){
225             DTrace.BIND.log(id, " ihc " + System.identityHashCode(obj));
226         }
227         
228         ta = checkTransaction(ta);
229         int intID = (int) id;
230         if (obj != null) {
231             Object JavaDoc oldObject = getByID(id);
232             if (oldObject != null) {
233                 YapObject yo = getYapObject(intID);
234                 if (yo != null) {
235                     if (ta.reflector().forObject(obj) == yo.getYapClass().classReflector()) {
236                         bind2(yo, obj);
237                     } else {
238                         throw new RuntimeException JavaDoc(Messages.get(57));
239                     }
240                 }
241             }
242         }
243     }
244     
245     final void bind2(YapObject a_yapObject, Object JavaDoc obj){
246         int id = a_yapObject.getID();
247         removeReference(a_yapObject);
248         a_yapObject = new YapObject(getYapClass(reflector().forObject(obj)),
249             id);
250         a_yapObject.setObjectWeak(_this, obj);
251         a_yapObject.setStateDirty();
252         idTreeAdd(a_yapObject);
253         hcTreeAdd(a_yapObject);
254     }
255     
256     public byte blockSize() {
257         return 1;
258     }
259
260     public int blocksFor(long bytes) {
261         int blockLen = blockSize();
262         int result = (int)(bytes / blockLen);
263         if (bytes % blockLen != 0) result++;
264         return result;
265     }
266     
267     private final boolean breakDeleteForEnum(YapObject reference, boolean userCall){
268         if(Deploy.csharp){
269             return false;
270         }
271         if(userCall){
272             return false;
273         }
274         if(reference == null){
275             return false;
276         }
277         return Platform4.jdk().isEnum(reflector(), reference.getYapClass().classReflector());
278     }
279
280     boolean canUpdate() {
281         return true;
282     }
283
284     public final void checkClosed() {
285         if (_classCollection == null) {
286             Exceptions4.throwRuntimeException(20, toString());
287         }
288     }
289
290     final void checkNeededUpdates() {
291         if (i_needsUpdate != null) {
292             Iterator4 i = new Iterator4Impl(i_needsUpdate);
293             while (i.moveNext()) {
294                 YapClass yapClass = (YapClass) i.current();
295                 yapClass.setStateDirty();
296                 yapClass.write(i_systemTrans);
297             }
298             i_needsUpdate = null;
299         }
300     }
301
302     final Transaction checkTransaction(Transaction ta) {
303         checkClosed();
304         if (ta != null) {
305             return ta;
306         }
307         return getTransaction();
308     }
309
310     public boolean close() {
311         synchronized (Global4.lock) {
312             synchronized (i_lock) {
313                 boolean ret = close1();
314                 return ret;
315             }
316         }
317     }
318
319     final boolean close1() {
320         // this is set to null in close2 and is therefore our check for down.
321
if (_classCollection == null) {
322             return true;
323         }
324         Platform4.preClose(_this);
325         checkNeededUpdates();
326         if (stateMessages()) {
327             logMsg(2, toString());
328         }
329         boolean closeResult = close2();
330         return closeResult;
331     }
332
333     protected boolean close2() {
334         stopSession();
335         i_hcTree = null;
336         i_idTree = null;
337         i_systemTrans = null;
338         i_trans = null;
339         if (stateMessages()) {
340             logMsg(3, toString());
341         }
342         if(DTrace.enabled){
343             DTrace.CLOSE.log();
344         }
345         return true;
346     }
347
348     public Db4oCollections collections() {
349         synchronized (i_lock) {
350             if (i_handlers.i_collections == null) {
351                 i_handlers.i_collections = Platform4.collections(this);
352             }
353             return i_handlers.i_collections;
354         }
355     }
356
357     public void commit() {
358         synchronized (i_lock) {
359             if(DTrace.enabled){
360                 DTrace.COMMIT.log();
361             }
362             beginTopLevelCall();
363             try{
364                 commit1();
365             }finally{
366                 endTopLevelCall();
367             }
368         }
369     }
370
371     public abstract void commit1();
372
373     public Configuration configure() {
374         return configImpl();
375     }
376     
377     public Config4Impl config(){
378         return configImpl();
379     }
380     
381     public abstract int converterVersion();
382
383     public abstract AbstractQueryResult newQueryResult(Transaction trans, QueryEvaluationMode mode);
384
385     protected void createStringIO(byte encoding) {
386         setStringIo(YapStringIO.forEncoding(encoding));
387     }
388
389     final protected void initializeTransactions() {
390         i_systemTrans = newTransaction(null);
391         i_trans = newTransaction();
392     }
393
394     public abstract Transaction newTransaction(Transaction parentTransaction);
395     
396     public Transaction newTransaction() {
397         return newTransaction(i_systemTrans);
398     }
399
400     public abstract long currentVersion();
401     
402     public boolean createYapClass(YapClass a_yapClass, ReflectClass a_class, YapClass a_superYapClass) {
403         return a_yapClass.init(_this, a_superYapClass, a_class);
404     }
405
406     /**
407      * allows special handling for all Db4oType objects.
408      * Redirected here from #set() so only instanceof check is necessary
409      * in the #set() method.
410      * @return object if handled here and #set() should not continue processing
411      */

412     public Db4oType db4oTypeStored(Transaction a_trans, Object JavaDoc a_object) {
413         if (a_object instanceof Db4oDatabase) {
414             Db4oDatabase database = (Db4oDatabase) a_object;
415             if (getYapObject(a_object) != null) {
416                 return database;
417             }
418             showInternalClasses(true);
419             Db4oDatabase res = database.query(a_trans);
420             showInternalClasses(false);
421             return res;
422         }
423         return null;
424     }
425
426     public void deactivate(Object JavaDoc a_deactivate, int a_depth) {
427         synchronized (i_lock) {
428             beginTopLevelCall();
429             try{
430                 deactivate1(a_deactivate, a_depth);
431             }catch (Throwable JavaDoc t) {
432                 fatalException(t);
433             }finally{
434                 endTopLevelCall();
435             }
436         }
437     }
438
439     private final void deactivate1(Object JavaDoc a_activate, int a_depth) {
440         stillToDeactivate(a_activate, a_depth, true);
441         while (i_stillToDeactivate != null) {
442             Iterator4 i = new Iterator4Impl(i_stillToDeactivate);
443             i_stillToDeactivate = null;
444             while (i.moveNext()) {
445                 YapObject currentObject = (YapObject) i.current();
446                 
447                 i.moveNext();
448                 Integer JavaDoc currentInteger = ((Integer JavaDoc) i.current());
449                 
450                 currentObject.deactivate(i_trans, currentInteger.intValue());
451             }
452         }
453     }
454
455     public void delete(Object JavaDoc a_object) {
456         delete(null, a_object);
457     }
458     
459     public void delete(Transaction trans, Object JavaDoc obj) {
460         synchronized (i_lock) {
461             trans = checkTransaction(trans);
462             delete1(trans, obj, true);
463             trans.processDeletes();
464         }
465     }
466
467     public final void delete1(Transaction trans, Object JavaDoc obj, boolean userCall) {
468         if (obj == null) {
469             return;
470         }
471         YapObject ref = getYapObject(obj);
472         if(ref == null){
473             return;
474         }
475         
476         if (Deploy.debug) {
477             delete2(trans, ref, obj, 0, userCall);
478             return;
479         }
480         
481         try {
482             delete2(trans, ref, obj, 0, userCall);
483         } catch (Throwable JavaDoc t) {
484             fatalException(t);
485         }
486     }
487     
488     final void delete2(Transaction trans, YapObject ref, Object JavaDoc obj, int cascade, boolean userCall) {
489         
490         // This check is performed twice, here and in delete3, intentionally.
491
if(breakDeleteForEnum(ref, userCall)){
492             return;
493         }
494         
495         if(obj instanceof SecondClass){
496             if(! flagForDelete(ref)){
497                 return;
498             }
499             delete3(trans, ref, cascade, userCall);
500             return;
501         }
502         
503         trans.delete(ref, ref.getID(), cascade);
504     }
505
506     final void delete3(Transaction trans, YapObject ref, int cascade, boolean userCall) {
507         
508         // The passed reference can be null, when calling from Transaction.
509
if(ref == null || ! ref.beginProcessing()){
510             return;
511         }
512                 
513         // This check is performed twice, here and in delete2, intentionally.
514
if(breakDeleteForEnum(ref, userCall)){
515             return;
516         }
517         
518         if(! ref.isFlaggedForDelete()){
519             return;
520         }
521         
522         YapClass yc = ref.getYapClass();
523         Object JavaDoc obj = ref.getObject();
524         
525         // We have to end processing temporarily here, otherwise the can delete callback
526
// can't do anything at all with this object.
527

528         ref.endProcessing();
529         
530         if (!objectCanDelete(yc, obj)) {
531             return;
532         }
533         
534         ref.beginProcessing();
535
536         if(DTrace.enabled){
537             DTrace.DELETE.log(ref.getID());
538         }
539         
540         if(delete4(trans, ref, cascade, userCall)){
541             objectOnDelete(yc, obj);
542             if (configImpl().messageLevel() > YapConst.STATE) {
543                 message("" + ref.getID() + " delete " + ref.getYapClass().getName());
544             }
545         }
546         
547         ref.endProcessing();
548     }
549     
550     private boolean objectCanDelete(YapClass yc, Object JavaDoc obj) {
551         return _this.callbacks().objectCanDelete(obj)
552             && yc.dispatchEvent(_this, obj, EventDispatcher.CAN_DELETE);
553     }
554     
555     private void objectOnDelete(YapClass yc, Object JavaDoc obj) {
556         _this.callbacks().objectOnDelete(obj);
557         yc.dispatchEvent(_this, obj, EventDispatcher.DELETE);
558     }
559     
560     public abstract boolean delete4(Transaction ta, YapObject yapObject, int a_cascade, boolean userCall);
561     
562     public Object JavaDoc descend(Object JavaDoc obj, String JavaDoc[] path){
563         synchronized (i_lock) {
564             return descend1(checkTransaction(null), obj, path);
565         }
566     }
567     
568     private Object JavaDoc descend1(Transaction trans, Object JavaDoc obj, String JavaDoc[] path){
569         YapObject yo = getYapObject(obj);
570         if(yo == null){
571             return null;
572         }
573         
574         Object JavaDoc child = null;
575         
576         final String JavaDoc fieldName = path[0];
577         if(fieldName == null){
578             return null;
579         }
580         YapClass yc = yo.getYapClass();
581         final YapField[] field = new YapField[]{null};
582         yc.forEachYapField(new Visitor4() {
583             public void visit(Object JavaDoc yf) {
584                 YapField yapField = (YapField)yf;
585                 if(yapField.canAddToQuery(fieldName)){
586                     field[0] = yapField;
587                 }
588             }
589         });
590         if(field[0] == null){
591             return null;
592         }
593         if(yo.isActive()){
594             child = field[0].get(obj);
595         }else{
596             YapReader reader = readReaderByID(trans, yo.getID());
597             if(reader == null){
598                 return null;
599             }
600             MarshallerFamily mf = yc.findOffset(reader, field[0]);
601             if(mf == null){
602                 return null;
603             }
604             try {
605                 child = field[0].readQuery(trans, mf, reader);
606             } catch (CorruptionException e) {
607             }
608         }
609         if(path.length == 1){
610             return child;
611         }
612         if(child == null){
613             return null;
614         }
615         String JavaDoc[] subPath = new String JavaDoc[path.length - 1];
616         System.arraycopy(path, 1, subPath, 0, path.length - 1);
617         return descend1(trans, child, subPath);
618     }
619
620     public boolean detectSchemaChanges() {
621         // overriden in YapClient
622
return configImpl().detectSchemaChanges();
623     }
624     
625     public boolean dispatchsEvents() {
626         return true;
627     }
628
629     protected boolean doFinalize() {
630         return true;
631     }
632     
633     void emergencyClose() {
634         stopSession();
635     }
636
637     public ExtObjectContainer ext() {
638         return _this;
639     }
640
641     void failedToShutDown() {
642         synchronized (Global4.lock) {
643             if (_classCollection == null) {
644                 return;
645             }
646             if(i_amDuringFatalExit){
647                 return;
648             }
649             if (_stackDepth == 0) {
650                 Messages.logErr(configImpl(), 50, toString(), null);
651                 while (!close()) {
652                 }
653             } else {
654                 emergencyClose();
655                 if (_stackDepth > 0) {
656                     Messages.logErr(configImpl(), 24, null, null);
657                 }
658             }
659         }
660     }
661
662     void fatalException(int msgID) {
663         fatalException(null,msgID);
664     }
665
666     void fatalException(Throwable JavaDoc t) {
667         fatalException(t,Messages.FATAL_MSG_ID);
668     }
669
670     void fatalException(Throwable JavaDoc t, int msgID) {
671         if (!i_amDuringFatalExit) {
672             i_amDuringFatalExit = true;
673             emergencyClose();
674             
675             Messages.logErr(configImpl(), (msgID==Messages.FATAL_MSG_ID ? 18 : msgID), null, t);
676         }
677         throw new RuntimeException JavaDoc(Messages.get(msgID));
678     }
679
680     
681     protected void finalize() {
682         if (doFinalize() && (configImpl() == null || configImpl().automaticShutDown())) {
683             failedToShutDown();
684         }
685     }
686
687     void gc() {
688         i_references.pollReferenceQueue();
689     }
690
691     public ObjectSet get(Object JavaDoc template) {
692         synchronized (i_lock) {
693             return get1(null, template);
694         }
695     }
696
697     ObjectSetFacade get1(Transaction ta, Object JavaDoc template) {
698         ta = checkTransaction(ta);
699         QueryResult res = null;
700         if (Deploy.debug) {
701             res = get2(ta, template);
702         } else {
703             try {
704                 res = get2(ta, template);
705             } catch (Throwable JavaDoc t) {
706                 Exceptions4.catchAllExceptDb4oException(t);
707                 fatalException(t);
708             }
709         }
710         return new ObjectSetFacade(res);
711     }
712
713     private final QueryResult get2(Transaction ta, Object JavaDoc template) {
714         if (template == null || template.getClass() == YapConst.CLASS_OBJECT) {
715             return getAll(ta);
716         }
717         Query q = query(ta);
718         q.constrain(template);
719         return executeQuery((QQuery)q);
720     }
721     
722     public abstract AbstractQueryResult getAll(Transaction ta);
723
724     public Object JavaDoc getByID(long id) {
725         synchronized (i_lock) {
726             return getByID1(null, id);
727         }
728     }
729
730     public final Object JavaDoc getByID1(Transaction ta, long id) {
731         ta = checkTransaction(ta);
732         try {
733             return getByID2(ta, (int) id);
734         } catch (Exception JavaDoc e) {
735             return null;
736         }
737     }
738     
739     final Object JavaDoc getByID2(Transaction ta, int a_id) {
740         if (a_id > 0) {
741             Object JavaDoc obj = objectForIDFromCache(a_id);
742             if(obj != null){
743                 
744                 // Take care about handling the returned candidate reference.
745
// If you loose the reference, weak reference management might also.
746
return obj;
747                 
748             }
749             try {
750                 return new YapObject(a_id).read(ta, null, null, 0,YapConst.ADD_TO_ID_TREE, true);
751             } catch (Throwable JavaDoc t) {
752                 if (Debug.atHome) {
753                     t.printStackTrace();
754                 }
755             }
756         }
757         return null;
758     }
759     
760     public final Object JavaDoc getActivatedObjectFromCache(Transaction ta, int id){
761         Object JavaDoc obj = objectForIDFromCache(id);
762         if(obj == null){
763             return null;
764         }
765         activate1(ta, obj, configImpl().activationDepth());
766         return obj;
767     }
768     
769     public final Object JavaDoc readActivatedObjectNotInCache(Transaction ta, int id){
770         Object JavaDoc obj = null;
771         beginTopLevelCall();
772         try {
773             obj = new YapObject(id).read(ta, null, null, configImpl().activationDepth(),YapConst.ADD_TO_ID_TREE, true);
774         } catch (Throwable JavaDoc t) {
775             if (Debug.atHome) {
776                 t.printStackTrace();
777             }
778         } finally{
779             endTopLevelCall();
780         }
781         activate3CheckStill(ta);
782         return obj;
783     }
784     
785     public final Object JavaDoc getByUUID(Db4oUUID uuid){
786         synchronized (i_lock) {
787             if(uuid == null){
788                 return null;
789             }
790             Transaction ta = checkTransaction(null);
791             Object JavaDoc[] arr = ta.objectAndYapObjectBySignature(
792                                 uuid.getLongPart(),
793                                 uuid.getSignaturePart());
794             return arr[0];
795         }
796     }
797
798     public long getID(Object JavaDoc obj) {
799         synchronized (i_lock) {
800             return getID1(obj);
801         }
802     }
803
804     public final int getID1(Object JavaDoc obj) {
805         checkClosed();
806
807         if(obj == null){
808             return 0;
809         }
810
811         YapObject yo = getYapObject(obj);
812         if (yo != null) {
813             return yo.getID();
814         }
815         return 0;
816     }
817     
818     public ObjectInfo getObjectInfo(Object JavaDoc obj){
819         synchronized(i_lock){
820             return getYapObject(obj);
821         }
822     }
823
824     public final Object JavaDoc[] getObjectAndYapObjectByID(Transaction ta, int a_id) {
825         Object JavaDoc[] arr = new Object JavaDoc[2];
826         if (a_id > 0) {
827             YapObject yo = getYapObject(a_id);
828             if (yo != null) {
829
830                 // Take care about handling the returned candidate reference.
831
// If you loose the reference, weak reference management might also.
832

833                 Object JavaDoc candidate = yo.getObject();
834                 if (candidate != null) {
835                     arr[0] = candidate;
836                     arr[1] = yo;
837                     return arr;
838                 }
839                 removeReference(yo);
840             }
841             try {
842                 yo = new YapObject(a_id);
843                 arr[0] = yo.read(ta, null, null, 0, YapConst.ADD_TO_ID_TREE, true);
844                 
845                 if(arr[0] == null){
846                     return arr;
847                 }
848                 
849                 // check class creation side effect and simply retry recursively
850
// if it hits:
851
if(arr[0] != yo.getObject()){
852                     return getObjectAndYapObjectByID(ta, a_id);
853                 }
854                 
855                 arr[1] = yo;
856                 
857             } catch (Throwable JavaDoc t) {
858                 if (Debug.atHome) {
859                     t.printStackTrace();
860                 }
861             }
862         }
863         return arr;
864     }
865
866     public final YapWriter getWriter(Transaction a_trans, int a_address, int a_length) {
867         if (Debug.exceedsMaximumBlockSize(a_length)) {
868             return null;
869         }
870         return new YapWriter(a_trans, a_address, a_length);
871     }
872
873     public final Transaction getSystemTransaction() {
874         return i_systemTrans;
875     }
876
877     public final Transaction getTransaction() {
878         return i_trans;
879     }
880     
881     public final YapClass getYapClass(ReflectClass claxx){
882         if(cantGetYapClass(claxx)){
883             return null;
884         }
885         YapClass yc = i_handlers.getYapClassStatic(claxx);
886         if (yc != null) {
887             return yc;
888         }
889         return _classCollection.getYapClass(claxx);
890     }
891     
892     // TODO: Some ReflectClass implementations could hold a
893
// reference to YapClass to improve lookup performance here.
894
public final YapClass produceYapClass(ReflectClass claxx) {
895         if(cantGetYapClass(claxx)){
896             return null;
897         }
898         YapClass yc = i_handlers.getYapClassStatic(claxx);
899         if (yc != null) {
900             return yc;
901         }
902         
903         return _classCollection.produceYapClass(claxx);
904     }
905     
906     /**
907      * Differentiating getActiveYapClass from getYapClass is a tuning
908      * optimization: If we initialize a YapClass, #set3() has to check for
909      * the possibility that class initialization associates the currently
910      * stored object with a previously stored static object, causing the
911      * object to be known afterwards.
912      *
913      * In this call we only return active YapClasses, initialization
914      * is not done on purpose
915      */

916     final YapClass getActiveYapClass(ReflectClass claxx) {
917         if(cantGetYapClass(claxx)){
918             return null;
919         }
920         YapClass yc = i_handlers.getYapClassStatic(claxx);
921         if (yc != null) {
922             return yc;
923         }
924         return _classCollection.getActiveYapClass(claxx);
925     }
926     
927     private final boolean cantGetYapClass(ReflectClass claxx){
928         if (claxx == null) {
929             return true;
930         }
931         if ((!showInternalClasses()) && i_handlers.ICLASS_INTERNAL.isAssignableFrom(claxx)) {
932             return true;
933         }
934         return false;
935     }
936
937     public YapClass getYapClass(int id) {
938         if(DTrace.enabled){
939             DTrace.YAPCLASS_BY_ID.log(id);
940         }
941         if (id == 0) {
942             return null;
943         }
944         YapClass yc = i_handlers.getYapClassStatic(id);
945         if (yc != null) {
946             return yc;
947         }
948         return _classCollection.getYapClass(id);
949     }
950     
951     public Object JavaDoc objectForIDFromCache(int id){
952         YapObject yo = getYapObject(id);
953         if (yo == null) {
954             return null;
955         }
956         Object JavaDoc candidate = yo.getObject();
957         if(candidate == null){
958             removeReference(yo);
959         }
960         return candidate;
961     }
962
963     public final YapObject getYapObject(int id) {
964         if(DTrace.enabled){
965             DTrace.GET_YAPOBJECT.log(id);
966         }
967         if(id <= 0){
968             return null;
969         }
970         return i_idTree.id_find(id);
971     }
972
973     public final YapObject getYapObject(Object JavaDoc a_object) {
974         return i_hcTree.hc_find(a_object);
975     }
976     
977     public YapHandlers handlers(){
978         return i_handlers;
979     }
980
981     public boolean needsLockFileThread() {
982         if (!Platform4.hasLockFileThread()) {
983             return false;
984         }
985         if (Platform4.hasNio()) {
986             return false;
987         }
988         if (configImpl().isReadOnly()) {
989             return false;
990         }
991         return configImpl().lockFile();
992     }
993
994     protected boolean hasShutDownHook() {
995         return configImpl().automaticShutDown();
996     }
997
998     final void hcTreeAdd(YapObject ref) {
999         if(Debug.checkSychronization){
1000            i_lock.notify();
1001        }
1002        if (Deploy.debug) {
1003            Object JavaDoc obj = ref.getObject();
1004            if (obj != null) {
1005                YapObject yo = getYapObject(obj);
1006                if (yo != null) {
1007                    System.out.println("Duplicate alarm hc_Tree");
1008                }
1009            }
1010        }
1011        i_hcTree = i_hcTree.hc_add(ref);
1012    }
1013
1014    final void idTreeAdd(YapObject a_yo) {
1015        if(Debug.checkSychronization){
1016            i_lock.notify();
1017        }
1018        if(DTrace.enabled){
1019            DTrace.ID_TREE_ADD.log(a_yo.getID());
1020        }
1021        if (Deploy.debug) {
1022            YapObject yo = getYapObject(a_yo.getID());
1023            if (yo != null) {
1024                System.out.println("Duplicate alarm id_Tree:" + a_yo.getID());
1025            }
1026        }
1027        i_idTree = i_idTree.id_add(a_yo);
1028    }
1029
1030    protected void initialize1(Configuration config) {
1031
1032        i_config = initializeConfig(config);
1033        i_handlers = new YapHandlers(_this, configImpl().encoding(), configImpl().reflector());
1034        
1035        if (i_references != null) {
1036            gc();
1037            i_references.stopTimer();
1038        }
1039
1040        i_references = new YapReferences(_this);
1041
1042        if (hasShutDownHook()) {
1043            Platform4.addShutDownHook(this, i_lock);
1044        }
1045        i_handlers.initEncryption(configImpl());
1046        initialize2();
1047        i_stillToSet = null;
1048    }
1049
1050    private Config4Impl initializeConfig(Configuration config) {
1051        Config4Impl impl=((Config4Impl)config);
1052        impl.stream(_this);
1053        impl.reflector().setTransaction(getSystemTransaction());
1054        return impl;
1055    }
1056
1057    /**
1058     * before file is open
1059     */

1060    void initialize2() {
1061
1062        // This is our one master root YapObject for the tree,
1063
// to allow us to ignore null.
1064
i_idTree = new YapObject(0);
1065        i_idTree.setObject(new Object JavaDoc());
1066        i_hcTree = i_idTree;
1067
1068        initialize2NObjectCarrier();
1069    }
1070
1071    /**
1072     * overridden in YapObjectCarrier
1073     */

1074    void initialize2NObjectCarrier() {
1075        _classCollection = new YapClassCollection(i_systemTrans);
1076        i_references.startTimer();
1077    }
1078
1079    protected void initialize3() {
1080        i_showInternalClasses = 100000;
1081        initialize4NObjectCarrier();
1082        i_showInternalClasses = 0;
1083    }
1084    
1085    void initialize4NObjectCarrier() {
1086        initializeEssentialClasses();
1087        rename(configImpl());
1088        _classCollection.initOnUp(i_systemTrans);
1089        if (configImpl().detectSchemaChanges()) {
1090            i_systemTrans.commit();
1091        }
1092    }
1093
1094    void initializeEssentialClasses(){
1095        for (int i = 0; i < YapConst.ESSENTIAL_CLASSES.length; i++) {
1096            produceYapClass(reflector().forClass(YapConst.ESSENTIAL_CLASSES[i]));
1097        }
1098    }
1099
1100    final void instantiating(boolean flag) {
1101        i_instantiating = flag;
1102    }
1103
1104    public boolean isActive(Object JavaDoc obj) {
1105        synchronized (i_lock) {
1106            return isActive1(obj);
1107        }
1108    }
1109
1110    final boolean isActive1(Object JavaDoc obj) {
1111        checkClosed();
1112        if (obj != null) {
1113            YapObject yo = getYapObject(obj);
1114            if (yo != null) {
1115                return yo.isActive();
1116            }
1117        }
1118        return false;
1119    }
1120
1121    public boolean isCached(long a_id) {
1122        synchronized (i_lock) {
1123            return objectForIDFromCache((int)a_id) != null;
1124        }
1125    }
1126
1127    /**
1128     * overridden in YapClient
1129     * This method will make it easier to refactor than
1130     * an "instanceof YapClient" check.
1131     */

1132    public boolean isClient() {
1133        return false;
1134    }
1135
1136    public boolean isClosed() {
1137        synchronized (i_lock) {
1138            return _classCollection == null;
1139        }
1140    }
1141
1142    final boolean isInstantiating() {
1143        return i_instantiating;
1144    }
1145
1146    boolean isServer() {
1147        return false;
1148    }
1149
1150    public boolean isStored(Object JavaDoc obj) {
1151        synchronized (i_lock) {
1152            return isStored1(obj);
1153        }
1154    }
1155
1156    final boolean isStored1(Object JavaDoc obj) {
1157        Transaction ta = checkTransaction(null);
1158        if (obj == null) {
1159            return false;
1160        }
1161        YapObject yo = getYapObject(obj);
1162        if (yo == null) {
1163            return false;
1164        }
1165        return !ta.isDeleted(yo.getID());
1166    }
1167    
1168    public ReflectClass[] knownClasses(){
1169        synchronized(i_lock){
1170            checkClosed();
1171            return reflector().knownClasses();
1172        }
1173    }
1174    
1175    public TypeHandler4 handlerByID(int id) {
1176        if (id < 1) {
1177            return null;
1178        }
1179        if (i_handlers.isSystemHandler(id)) {
1180            return i_handlers.getHandler(id);
1181        }
1182        return getYapClass(id);
1183    }
1184
1185    public Object JavaDoc lock() {
1186        return i_lock;
1187    }
1188
1189    public final void logMsg(int code, String JavaDoc msg) {
1190        Messages.logMsg(configImpl(), code, msg);
1191    }
1192
1193    public boolean maintainsIndices() {
1194        return true;
1195    }
1196
1197    protected YapWriter marshall(Transaction ta, Object JavaDoc obj) {
1198        // TODO: How about reuse of the MemoryFile here?
1199
int[] id = { 0};
1200        byte[] bytes = marshall(obj, id);
1201        YapWriter yapBytes = new YapWriter(ta, bytes.length);
1202        yapBytes.append(bytes);
1203        yapBytes.useSlot(id[0], 0, bytes.length);
1204        return yapBytes;
1205    }
1206
1207    byte[] marshall(Object JavaDoc obj, int[] id) {
1208        MemoryFile memoryFile = new MemoryFile();
1209        memoryFile.setInitialSize(223);
1210        memoryFile.setIncrementSizeBy(300);
1211        produceYapClass(reflector().forObject(obj));
1212        YapObjectCarrier carrier = new YapObjectCarrier(config(),_this, memoryFile);
1213        carrier.i_showInternalClasses = i_showInternalClasses;
1214        carrier.set(obj);
1215        id[0] = (int) carrier.getID(obj);
1216        carrier.close();
1217        return memoryFile.getBytes();
1218    }
1219
1220    void message(String JavaDoc msg) {
1221        new Message(_this, msg);
1222    }
1223
1224    public void migrateFrom(ObjectContainer objectContainer) {
1225        if(objectContainer == null){
1226            if(_replicationCallState == YapConst.NONE){
1227                return;
1228            }
1229            _replicationCallState = YapConst.NONE;
1230            if(i_handlers.i_migration != null){
1231                i_handlers.i_migration.terminate();
1232            }
1233            i_handlers.i_migration = null;
1234        }else{
1235            YapStream peer = (YapStream)objectContainer;
1236            _replicationCallState = YapConst.OLD;
1237            peer._replicationCallState = YapConst.OLD;
1238            i_handlers.i_migration = new MigrationConnection(_this, (YapStream)objectContainer);
1239            peer.i_handlers.i_migration = i_handlers.i_migration;
1240        }
1241    }
1242
1243    public final void needsUpdate(YapClass a_yapClass) {
1244        i_needsUpdate = new List4(i_needsUpdate, a_yapClass);
1245    }
1246    
1247    public long generateTimeStampId() {
1248        return _timeStampIdGenerator.next();
1249    }
1250
1251    public abstract int newUserObject();
1252
1253    public Object JavaDoc peekPersisted(Object JavaDoc obj, int depth, boolean committed) {
1254        
1255        // TODO: peekPersisted is not stack overflow safe, if depth is too high.
1256

1257        synchronized (i_lock) {
1258            beginTopLevelCall();
1259            try{
1260                i_justPeeked = null;
1261                Transaction ta = committed ? i_systemTrans
1262                    : checkTransaction(null);
1263                Object JavaDoc cloned = null;
1264                YapObject yo = getYapObject(obj);
1265                if (yo != null) {
1266                    cloned = peekPersisted1(ta, yo.getID(), depth);
1267                }
1268                i_justPeeked = null;
1269                return cloned;
1270            }finally{
1271                endTopLevelCall();
1272            }
1273        }
1274    }
1275
1276    Object JavaDoc peekPersisted1(Transaction a_ta, int a_id, int a_depth) {
1277        if(a_depth < 0){
1278            return null;
1279        }
1280        TreeInt ti = new TreeInt(a_id);
1281        TreeIntObject tio = (TreeIntObject) Tree.find(i_justPeeked, ti);
1282        if (tio == null) {
1283            return new YapObject(a_id).read(a_ta, null, null, a_depth,
1284                YapConst.TRANSIENT, false);
1285    
1286        }
1287        return tio._object;
1288    }
1289
1290    void peeked(int a_id, Object JavaDoc a_object) {
1291        i_justPeeked = Tree
1292            .add(i_justPeeked, new TreeIntObject(a_id, a_object));
1293    }
1294
1295    public void purge() {
1296        synchronized (i_lock) {
1297            purge1();
1298        }
1299    }
1300
1301    public void purge(Object JavaDoc obj) {
1302        synchronized (i_lock) {
1303            purge1(obj);
1304        }
1305    }
1306
1307    final void purge1() {
1308        checkClosed();
1309        System.gc();
1310        System.runFinalization();
1311        System.gc();
1312        gc();
1313        _classCollection.purge();
1314    }
1315
1316    final void purge1(Object JavaDoc obj) {
1317        if (obj == null || i_hcTree == null) {
1318            return;
1319        }
1320        
1321        if (obj instanceof YapObject) {
1322            removeReference((YapObject) obj);
1323            return;
1324        }
1325        
1326        YapObject ref = getYapObject(obj);
1327        if (ref != null) {
1328            removeReference(ref);
1329        }
1330    }
1331    
1332    public final NativeQueryHandler getNativeQueryHandler() {
1333        if (null == _nativeQueryHandler) {
1334            _nativeQueryHandler = new NativeQueryHandler(_this);
1335        }
1336        return _nativeQueryHandler;
1337    }
1338    
1339    public final ObjectSet query(Predicate predicate){
1340        return query(predicate,(QueryComparator)null);
1341    }
1342
1343    public final ObjectSet query(Predicate predicate,QueryComparator comparator){
1344        synchronized (i_lock) {
1345            return getNativeQueryHandler().execute(predicate,comparator);
1346        }
1347    }
1348
1349    public Query query() {
1350        synchronized (i_lock) {
1351            return query((Transaction)null);
1352        }
1353    }
1354    
1355    public final ObjectSet query(Class JavaDoc clazz) {
1356        return get(clazz);
1357    }
1358
1359    public final Query query(Transaction ta) {
1360        return new QQuery(checkTransaction(ta), null, null);
1361    }
1362
1363    public abstract void raiseVersion(long a_minimumVersion);
1364
1365    public abstract void readBytes(byte[] a_bytes, int a_address, int a_length);
1366
1367    public abstract void readBytes(byte[] bytes, int address, int addressOffset, int length);
1368
1369    public final YapReader readReaderByAddress(int a_address, int a_length) {
1370        if (a_address > 0) {
1371
1372            // TODO: possibly load from cache here
1373

1374            YapReader reader = new YapReader(a_length);
1375            readBytes(reader._buffer, a_address, a_length);
1376            i_handlers.decrypt(reader);
1377            return reader;
1378        }
1379        return null;
1380    }
1381
1382    public final YapWriter readWriterByAddress(Transaction a_trans,
1383        int a_address, int a_length) {
1384        if (a_address > 0) {
1385            // TODO:
1386
// load from cache here
1387
YapWriter reader = getWriter(a_trans, a_address, a_length);
1388            reader.readEncrypt(_this, a_address);
1389            return reader;
1390        }
1391        return null;
1392    }
1393
1394    public abstract YapWriter readWriterByID(Transaction a_ta, int a_id);
1395
1396    public abstract YapReader readReaderByID(Transaction a_ta, int a_id);
1397
1398    private void reboot() {
1399        commit();
1400        int ccID = _classCollection.getID();
1401        i_references.stopTimer();
1402        initialize2();
1403        _classCollection.setID(ccID);
1404        _classCollection.read(i_systemTrans);
1405    }
1406    
1407    public GenericReflector reflector(){
1408        return i_handlers._reflector;
1409    }
1410
1411    public void refresh(Object JavaDoc a_refresh, int a_depth) {
1412        synchronized (i_lock) {
1413            i_refreshInsteadOfActivate = true;
1414            try {
1415                activate1(null, a_refresh, a_depth);
1416            } finally {
1417                i_refreshInsteadOfActivate = false;
1418            }
1419        }
1420    }
1421
1422    final void refreshClasses() {
1423        synchronized (i_lock) {
1424            _classCollection.refreshClasses();
1425        }
1426    }
1427
1428    public abstract void releaseSemaphore(String JavaDoc name);
1429    
1430    void flagAsHandled(YapObject ref){
1431        ref.flagAsHandled(_topLevelCallId);
1432    }
1433    
1434    boolean flagForDelete(YapObject ref){
1435        if(ref == null){
1436            return false;
1437        }
1438        if(handledInCurrentTopLevelCall(ref)){
1439            return false;
1440        }
1441        ref.flagForDelete(_topLevelCallId);
1442        return true;
1443    }
1444    
1445    public abstract void releaseSemaphores(Transaction ta);
1446
1447    void rename(Config4Impl config) {
1448        boolean renamedOne = false;
1449        if (config.rename() != null) {
1450            renamedOne = rename1(config);
1451        }
1452        _classCollection.checkChanges();
1453        if (renamedOne) {
1454            reboot();
1455        }
1456    }
1457
1458    protected boolean rename1(Config4Impl config) {
1459        boolean renamedOne = false;
1460        try {
1461            Iterator4 i = config.rename().iterator();
1462            while (i.moveNext()) {
1463                Rename ren = (Rename) i.current();
1464                if (get(ren).size() == 0) {
1465                    boolean renamed = false;
1466
1467                    boolean isField = ren.rClass.length() > 0;
1468                    YapClass yapClass = _classCollection
1469                        .getYapClass(isField ? ren.rClass : ren.rFrom);
1470                    if (yapClass != null) {
1471                        if (isField) {
1472                            renamed = yapClass.renameField(ren.rFrom, ren.rTo);
1473                        } else {
1474                            YapClass existing = _classCollection
1475                                .getYapClass(ren.rTo);
1476                            if (existing == null) {
1477                                yapClass.setName(ren.rTo);
1478                                renamed = true;
1479                            } else {
1480                                logMsg(9, "class " + ren.rTo);
1481                            }
1482                        }
1483                    }
1484                    if (renamed) {
1485                        renamedOne = true;
1486                        setDirtyInSystemTransaction(yapClass);
1487
1488                        logMsg(8, ren.rFrom + " to " + ren.rTo);
1489
1490                        // delete all that rename from the new name
1491
// to allow future backswitching
1492
ObjectSet backren = get(new Rename(ren.rClass, null,
1493                            ren.rFrom));
1494                        while (backren.hasNext()) {
1495                            delete(backren.next());
1496                        }
1497
1498                        // store the rename, so we only do it once
1499
set(ren);
1500                    }
1501                }
1502            }
1503        } catch (Throwable JavaDoc t) {
1504            Messages.logErr(configImpl(), 10, null, t);
1505        }
1506        return renamedOne;
1507    }
1508
1509    public ReplicationProcess replicationBegin(ObjectContainer peerB, ReplicationConflictHandler conflictHandler) {
1510        return new ReplicationImpl(_this, peerB,conflictHandler);
1511    }
1512    
1513    final int oldReplicationHandles(Object JavaDoc obj){
1514        
1515        // The double check on i_migrateFrom is necessary:
1516
// i_handlers.i_replicateFrom may be set in YapObjectCarrier for parent YapStream
1517
if(_replicationCallState != YapConst.OLD){
1518            return 0;
1519        }
1520        
1521        if(i_handlers.i_replication == null){
1522            return 0;
1523        }
1524        
1525        if(obj instanceof Internal4){
1526            return 0;
1527        }
1528        
1529        YapObject reference = getYapObject(obj);
1530        if(reference != null && handledInCurrentTopLevelCall(reference)){
1531            return reference.getID();
1532        }
1533        
1534        return i_handlers.i_replication.tryToHandle(_this, obj);
1535    }
1536    
1537    public final boolean handledInCurrentTopLevelCall(YapObject ref){
1538        return ref.isFlaggedAsHandled(_topLevelCallId);
1539    }
1540
1541    void reserve(int byteCount) {
1542        // virtual: do nothing
1543
}
1544
1545    public void rollback() {
1546        synchronized (i_lock) {
1547            rollback1();
1548        }
1549    }
1550
1551    public abstract void rollback1();
1552
1553    public void send(Object JavaDoc obj) {
1554        // TODO: implement
1555
// so far this only works from YapClient
1556
}
1557
1558    public void set(Object JavaDoc a_object) {
1559        set(a_object, YapConst.UNSPECIFIED);
1560    }
1561    
1562    public final void set(Transaction trans, Object JavaDoc obj) {
1563        set(trans, obj, YapConst.UNSPECIFIED);
1564    }
1565    
1566    public final void set(Object JavaDoc obj, int depth) {
1567        set(i_trans, obj, depth);
1568    }
1569
1570    public void set(Transaction trans, Object JavaDoc obj, int depth) {
1571        synchronized (i_lock) {
1572            setInternal(trans, obj, depth, true);
1573        }
1574    }
1575    
1576    public final int setInternal(Transaction trans, Object JavaDoc obj, boolean checkJustSet) {
1577       return setInternal(trans, obj, YapConst.UNSPECIFIED, checkJustSet);
1578    }
1579    
1580    public final int setInternal(Transaction trans, Object JavaDoc obj, int depth, boolean checkJustSet) {
1581        beginTopLevelSet();
1582        try{
1583            int id = oldReplicationHandles(obj);
1584            if (id != 0){
1585                if(id < 0){
1586                    return 0;
1587                }
1588                return id;
1589            }
1590            return setAfterReplication(trans, obj, depth, checkJustSet);
1591        }finally{
1592            endTopLevelSet(trans);
1593        }
1594    }
1595    
1596    final int setAfterReplication(Transaction trans, Object JavaDoc obj, int depth, boolean checkJust) {
1597        
1598        if (obj instanceof Db4oType) {
1599            Db4oType db4oType = db4oTypeStored(trans, obj);
1600            if (db4oType != null) {
1601                return getID1(db4oType);
1602            }
1603        }
1604        
1605        if (Deploy.debug) {
1606            return set2(trans, obj, depth, checkJust);
1607        }
1608        
1609        try {
1610            return set2(trans, obj, depth, checkJust);
1611        } catch (ObjectNotStorableException e) {
1612            throw e;
1613        } catch (Db4oException exc) {
1614            throw exc;
1615        } catch (Throwable JavaDoc t) {
1616            fatalException(t);
1617            return 0;
1618        }
1619    }
1620    
1621    public final void setByNewReplication(Db4oReplicationReferenceProvider referenceProvider, Object JavaDoc obj){
1622        synchronized(i_lock){
1623            _replicationCallState = YapConst.NEW;
1624            i_handlers._replicationReferenceProvider = referenceProvider;
1625            
1626            set2(checkTransaction(null), obj, 1, false);
1627            
1628            _replicationCallState = YapConst.NONE;
1629            i_handlers._replicationReferenceProvider = null;
1630        }
1631    }
1632    
1633    private final int set2(Transaction trans, Object JavaDoc obj, int depth, boolean checkJust) {
1634        int id = set3(trans, obj, depth, checkJust);
1635        if(stackIsSmall()){
1636            checkStillToSet();
1637        }
1638        return id;
1639    }
1640    
1641    public void checkStillToSet() {
1642        List4 postponedStillToSet = null;
1643        while (i_stillToSet != null) {
1644            Iterator4 i = new Iterator4Impl(i_stillToSet);
1645            i_stillToSet = null;
1646            while (i.moveNext()) {
1647                Integer JavaDoc updateDepth = (Integer JavaDoc)i.current();
1648                
1649                i.moveNext();
1650                YapObject ref = (YapObject)i.current();
1651                
1652                i.moveNext();
1653                Transaction trans = (Transaction)i.current();
1654                
1655                if(! ref.continueSet(trans, updateDepth.intValue())){
1656                    postponedStillToSet = new List4(postponedStillToSet, trans);
1657                    postponedStillToSet = new List4(postponedStillToSet, ref);
1658                    postponedStillToSet = new List4(postponedStillToSet, updateDepth);
1659                }
1660            }
1661        }
1662        i_stillToSet = postponedStillToSet;
1663    }
1664    
1665    private void notStorable(ReflectClass claxx, Object JavaDoc obj){
1666        if(! configImpl().exceptionsOnNotStorable()){
1667            return;
1668        }
1669        
1670        // FIXME: Exceptions configuration setting cant be modified
1671
// from running ObjectContainer.
1672
// Right now all tests fail, if we don't jump out here.
1673

1674        // The StorePrimitiveDirectly test case documents the err.
1675

1676        if(true){
1677            return;
1678        }
1679        
1680        if(claxx != null){
1681            throw new ObjectNotStorableException(claxx);
1682        }
1683        
1684        throw new ObjectNotStorableException(obj.toString());
1685    }
1686    
1687
1688    public final int set3(Transaction trans, Object JavaDoc obj, int updateDepth, boolean checkJustSet) {
1689        if (obj == null || (obj instanceof TransientClass)) {
1690            return 0;
1691        }
1692            
1693        if (obj instanceof Db4oTypeImpl) {
1694            ((Db4oTypeImpl) obj).storedTo(trans);
1695        }
1696        
1697        YapClass yc = null;
1698        YapObject ref = getYapObject(obj);
1699        if (ref == null) {
1700            
1701            ReflectClass claxx = reflector().forObject(obj);
1702            
1703            if(claxx == null){
1704                notStorable(claxx, obj);
1705                return 0;
1706            }
1707            
1708            yc = getActiveYapClass(claxx);
1709            
1710            if (yc == null) {
1711                yc = produceYapClass(claxx);
1712                if ( yc == null){
1713                    notStorable(claxx, obj);
1714                    return 0;
1715                }
1716                
1717                // The following may return a reference if the object is held
1718
// in a static variable somewhere ( often: Enums) that gets
1719
// stored or associated on initialization of the YapClass.
1720

1721                ref = getYapObject(obj);
1722                
1723            }
1724            
1725        } else {
1726            yc = ref.getYapClass();
1727        }
1728        
1729        if (isPlainObjectOrPrimitive(yc) ) {
1730            notStorable(yc.classReflector(), obj);
1731            return 0;
1732        }
1733        
1734        if (ref == null) {
1735            if (!objectCanNew(yc, obj)) {
1736                return 0;
1737            }
1738            ref = new YapObject();
1739            ref.store(trans, yc, obj);
1740            idTreeAdd(ref);
1741            hcTreeAdd(ref);
1742            if(obj instanceof Db4oTypeImpl){
1743                ((Db4oTypeImpl)obj).setTrans(trans);
1744            }
1745            if (configImpl().messageLevel() > YapConst.STATE) {
1746                message("" + ref.getID() + " new " + ref.getYapClass().getName());
1747            }
1748            
1749            flagAsHandled(ref);
1750            stillToSet(trans, ref, updateDepth);
1751
1752        } else {
1753            if (canUpdate()) {
1754                if(checkJustSet){
1755                    if( (! ref.isNew()) && handledInCurrentTopLevelCall(ref)){
1756                        return ref.getID();
1757                    }
1758                }
1759                if (updateDepthSufficient(updateDepth)) {
1760                    flagAsHandled(ref);
1761                    ref.writeUpdate(trans, updateDepth);
1762                }
1763            }
1764        }
1765        checkNeededUpdates();
1766        return ref.getID();
1767    }
1768    
1769    private final boolean updateDepthSufficient(int updateDepth){
1770        return (updateDepth == YapConst.UNSPECIFIED) || (updateDepth > 0);
1771    }
1772
1773    private final boolean isPlainObjectOrPrimitive(YapClass yc) {
1774        return yc.getID() == YapHandlers.ANY_ID || yc.isPrimitive();
1775    }
1776
1777    private boolean objectCanNew(YapClass yc, Object JavaDoc a_object) {
1778        return callbacks().objectCanNew(a_object)
1779            && yc.dispatchEvent(_this, a_object, EventDispatcher.CAN_NEW);
1780    }
1781
1782    public abstract void setDirtyInSystemTransaction(YapMeta a_object);
1783
1784    public abstract boolean setSemaphore(String JavaDoc name, int timeout);
1785
1786    void setStringIo(YapStringIO a_io) {
1787        i_handlers.i_stringHandler.setStringIo(a_io);
1788    }
1789
1790    final boolean showInternalClasses() {
1791        return isServer() || i_showInternalClasses > 0;
1792    }
1793
1794    /**
1795     * Objects implementing the "Internal4" marker interface are
1796     * not visible to queries, unless this flag is set to true.
1797     * The caller should reset the flag after the call.
1798     */

1799    public synchronized void showInternalClasses(boolean show) {
1800        if (show) {
1801            i_showInternalClasses++;
1802        } else {
1803            i_showInternalClasses--;
1804        }
1805        if (i_showInternalClasses < 0) {
1806            i_showInternalClasses = 0;
1807        }
1808    }
1809    
1810    private final boolean stackIsSmall(){
1811        return _stackDepth < YapConst.MAX_STACK_DEPTH;
1812    }
1813
1814    boolean stateMessages() {
1815        return true; // overridden to do nothing in YapObjectCarrier
1816
}
1817
1818    /**
1819     * returns true in case an unknown single object is passed
1820     * This allows deactivating objects before queries are called.
1821     */

1822    final List4 stillTo1(List4 still, Object JavaDoc obj, int depth, boolean forceUnknownDeactivate) {
1823        
1824        if (obj == null || depth <= 0) {
1825            return still;
1826        }
1827        
1828        YapObject ref = getYapObject(obj);
1829        if (ref != null) {
1830            if(handledInCurrentTopLevelCall(ref)){
1831                return still;
1832            }
1833            flagAsHandled(ref);
1834            return new List4(new List4(still, new Integer JavaDoc(depth)), ref);
1835        }
1836        final ReflectClass clazz = reflector().forObject(obj);
1837        if (clazz.isArray()) {
1838            if (!clazz.getComponentType().isPrimitive()) {
1839                Object JavaDoc[] arr = YapArray.toArray(_this, obj);
1840                for (int i = 0; i < arr.length; i++) {
1841                    still = stillTo1(still, arr[i],
1842                        depth, forceUnknownDeactivate);
1843                }
1844            }
1845        } else {
1846            if (obj instanceof Entry) {
1847                still = stillTo1(still, ((Entry) obj).key, depth, false);
1848                still = stillTo1(still, ((Entry) obj).value, depth, false);
1849            } else {
1850                if (forceUnknownDeactivate) {
1851                    // Special handling to deactivate Top-Level unknown objects only.
1852
YapClass yc = getYapClass(reflector().forObject(obj));
1853                    if (yc != null) {
1854                        yc.deactivate(i_trans, obj, depth);
1855                    }
1856                }
1857            }
1858        }
1859        return still;
1860    }
1861
1862    void stillToActivate(Object JavaDoc a_object, int a_depth) {
1863
1864        // TODO: We don't want the simple classes to search the hc_tree
1865
// Kick them out here.
1866

1867        // if (a_object != null) {
1868
// Class clazz = a_object.getClass();
1869
// if(! clazz.isPrimitive()){
1870

1871        i_stillToActivate = stillTo1(i_stillToActivate, a_object, a_depth, false);
1872
1873        // }
1874
// }
1875
}
1876
1877    void stillToDeactivate(Object JavaDoc a_object, int a_depth,
1878        boolean a_forceUnknownDeactivate) {
1879        i_stillToDeactivate = stillTo1(i_stillToDeactivate, a_object, a_depth, a_forceUnknownDeactivate);
1880    }
1881
1882    void stillToSet(Transaction a_trans, YapObject a_yapObject, int a_updateDepth) {
1883        if(stackIsSmall()){
1884            if(a_yapObject.continueSet(a_trans, a_updateDepth)){
1885                return;
1886            }
1887        }
1888        i_stillToSet = new List4(i_stillToSet, a_trans);
1889        i_stillToSet = new List4(i_stillToSet, a_yapObject);
1890        i_stillToSet = new List4(i_stillToSet, new Integer JavaDoc(a_updateDepth));
1891    }
1892
1893    protected void stopSession() {
1894        if (hasShutDownHook()) {
1895            Platform4.removeShutDownHook(this, i_lock);
1896        }
1897        _classCollection = null;
1898        i_references.stopTimer();
1899    }
1900
1901    public StoredClass storedClass(Object JavaDoc clazz) {
1902        synchronized (i_lock) {
1903            checkClosed();
1904            ReflectClass claxx = configImpl().reflectorFor(clazz);
1905            if (claxx == null) {
1906                return null;
1907            }
1908            return getYapClass(claxx);
1909        }
1910    }
1911
1912    public StoredClass[] storedClasses() {
1913        synchronized (i_lock) {
1914            checkClosed();
1915            return _classCollection.storedClasses();
1916        }
1917    }
1918        
1919    public YapStringIO stringIO(){
1920        return i_handlers.i_stringHandler.i_stringIo;
1921    }
1922    
1923    public abstract SystemInfo systemInfo();
1924    
1925    public final void beginTopLevelCall(){
1926        if(DTrace.enabled){
1927            DTrace.BEGIN_TOP_LEVEL_CALL.log();
1928        }
1929        checkClosed();
1930        generateCallIDOnTopLevel();
1931        _stackDepth++;
1932    }
1933    
1934    public final void beginTopLevelSet(){
1935        beginTopLevelCall();
1936    }
1937    
1938    public final void endTopLevelCall(){
1939        if(DTrace.enabled){
1940            DTrace.END_TOP_LEVEL_CALL.log();
1941        }
1942        _stackDepth--;
1943        generateCallIDOnTopLevel();
1944    }
1945    
1946    public final void endTopLevelSet(Transaction trans){
1947        endTopLevelCall();
1948        if(_stackDepth == 0){
1949            trans.processDeletes();
1950        }
1951    }
1952    
1953    private final void generateCallIDOnTopLevel(){
1954        if(_stackDepth == 0){
1955            _topLevelCallId = _topLevelCallIdGenerator.next();
1956        }
1957    }
1958    
1959    public int stackDepth(){
1960        return _stackDepth;
1961    }
1962    
1963    public void stackDepth(int depth){
1964        _stackDepth = depth;
1965    }
1966    
1967    public int topLevelCallId(){
1968        return _topLevelCallId;
1969    }
1970    
1971    public void topLevelCallId(int id){
1972        _topLevelCallId = id;
1973    }
1974
1975    public Object JavaDoc unmarshall(YapWriter yapBytes) {
1976        return unmarshall(yapBytes._buffer, yapBytes.getID());
1977    }
1978
1979    Object JavaDoc unmarshall(byte[] bytes, int id) {
1980        MemoryFile memoryFile = new MemoryFile(bytes);
1981        YapObjectCarrier carrier = new YapObjectCarrier(configure(),_this, memoryFile);
1982        Object JavaDoc obj = carrier.getByID(id);
1983        carrier.activate(obj, Integer.MAX_VALUE);
1984        carrier.close();
1985        return obj;
1986    }
1987
1988    public long version(){
1989        synchronized(i_lock){
1990            return currentVersion();
1991        }
1992    }
1993
1994    public abstract void write(boolean shuttingDown);
1995
1996    public abstract void writeDirty();
1997
1998    public abstract void writeEmbedded(YapWriter a_parent, YapWriter a_child);
1999
2000    public abstract void writeNew(YapClass a_yapClass, YapWriter aWriter);
2001
2002    public abstract void writeTransactionPointer(int a_address);
2003
2004    public abstract void writeUpdate(YapClass a_yapClass, YapWriter a_bytes);
2005
2006    public final void removeReference(YapObject ref) {
2007        if(DTrace.enabled){
2008            DTrace.REFERENCE_REMOVED.log(ref.getID());
2009        }
2010
2011        i_hcTree = i_hcTree.hc_remove(ref);
2012        i_idTree = i_idTree.id_remove(ref.getID());
2013        
2014        // setting the ID to minus 1 ensures that the
2015
// gc mechanism does not kill the new YapObject
2016
ref.setID(-1);
2017        Platform4.killYapRef(ref.getObjectReference());
2018    }
2019    
2020    // cheat emulating '(YapStream)this'
2021
private static YapStream cast(YapStreamBase obj) {
2022        return (YapStream)obj;
2023    }
2024    
2025    public Callbacks callbacks() {
2026            return _callbacks;
2027    }
2028    
2029    public void callbacks(Callbacks cb) {
2030            if (cb == null) {
2031                throw new IllegalArgumentException JavaDoc();
2032            }
2033            _callbacks = cb;
2034    }
2035
2036    public Config4Impl configImpl() {
2037        return i_config;
2038    }
2039    
2040    public YapFieldUUID getFieldUUID() {
2041        return i_handlers.i_indexes.i_fieldUUID;
2042    }
2043
2044    public YapClassCollection classCollection() {
2045        return _classCollection;
2046    }
2047    
2048    public ClassMetaHelper getClassMetaHelper() {
2049        return _classMetaHelper;
2050    }
2051    
2052    public abstract long[] getIDsForClass(Transaction trans, YapClass clazz);
2053    
2054    public abstract QueryResult classOnlyQuery(Transaction trans, YapClass clazz);
2055    
2056    public abstract QueryResult executeQuery(QQuery query);
2057
2058}
Popular Tags