KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ozoneDB > core > storage > classicStore > ClassicObjectContainer


1 // You can redistribute this software and/or modify it under the terms of
2
// the Ozone Core License version 1 published by ozone-db.org.
3
//
4
// The original code and portions created by SMB are
5
// Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
6
//
7
// $Id$
8

9 package org.ozoneDB.core.storage.classicStore;
10
11 import java.io.*;
12 import java.util.*;
13 import java.lang.reflect.*;
14 import org.ozoneDB.*;
15 import org.ozoneDB.io.stream.ResolvingObjectInputStream;
16 import org.ozoneDB.tools.OPP.OPP;
17 import org.ozoneDB.DxLib.*;
18 import org.ozoneDB.core.*;
19 import org.ozoneDB.util.*;
20
21
22 /**
23  * @author <a HREF="http://www.softwarebuero.de/">SMB</a>
24  */

25 public final class ClassicObjectContainer extends AbstractObjectContainer implements Externalizable {
26
27     /** magic number for streaming */
28     protected final static long serialVersionUID = 2;
29     protected final static byte subSerialVersionUID = 1;
30
31     /** global method cache */
32     private static DxHashMap methodTable = new DxHashMap( 64 );
33
34     /** objekte werden nach transaktion nicht geloescht */
35     protected static boolean keepObjectsAlive = true;
36
37     /** The environment of this object. */
38     protected transient Env env;
39     protected transient ClusterSpace clusterSpace;
40
41     /** permissions */
42     protected Permissions permissions;
43
44     /** null, if not activted */
45     protected OzoneCompatible target;
46     /** */
47     protected OzoneCompatible targetShadow;
48     /** */
49     protected byte[] targetBackup;
50
51     /** time of last invoke */
52     protected long touchTime = System.currentTimeMillis();
53     protected short touchCount = 1;
54     protected boolean touched = false;
55
56     /** a possible name for the object */
57     protected String JavaDoc name;
58
59     /** the id of the object */
60     protected ObjectID objID;
61     /** the cluster id where the object is stored */
62     protected ClusterID clusterID;
63
64     /** the lock of the object */
65     protected Lock lock = null;
66
67     /** */
68     protected boolean deleted = false;
69     /** */
70     protected boolean created = false;
71
72
73     /**
74      * constructor fuer streaming
75      */

76     public ClassicObjectContainer() {
77         created = false;
78         deleted = false;
79     }
80
81
82     /**
83      * constructor; name ist optional
84      */

85     public ClassicObjectContainer( OzoneCompatible _target, ObjectID _objID, Permissions _permissions ) {
86         env = Env.currentEnv();
87         clusterSpace = ((ClassicStore)env.getStoreManager()).objectSpace.clusterSpace;
88
89         target = _target;
90         objID = _objID;
91         permissions = _permissions;
92         //lock = new DefaultLock();
93
//todo assign lock to one of the new Lock implementation classes
94
created = true;
95         deleted = false;
96
97         target.setContainer( this );
98     }
99
100     // #### methods from ObjectContainer ######################################
101

102     /**
103      * Returns the time when the container was last commited with lock level
104      * greater than Lock.LEVEL_READ. The value returned by this method should
105      * only be compared against return values of this method.
106      */

107     public long modTime() {
108         return 0;
109     }
110
111     public Lock lock() {
112         return null;
113     }
114
115     public void setTarget(OzoneCompatible _target) {
116     }
117
118     public Class JavaDoc targetClass() {
119         return null;
120     }
121
122     /**
123      Pins this ObjectContainer.
124      Every caller of this method must pair this call with a call to {@link #unpin}.
125      An ObjectContainer remains in main memory at least as long as it is pinned.
126      */

127     public void pin() {
128     }
129
130     /**
131      Unpins this ObjectContainer.
132      This method must be called exactly once for every call to {@link #pin}.
133      */

134     public void unpin() {
135     }
136
137     /**
138      Returns wether this ObjectContainer is pinned.
139      */

140     public boolean isPinned() {
141         return false;
142     }
143
144     /**
145      Ensures that the garbageCollectionLevel is at least the given currentGarbageCollectionLevel.
146      The return value is meaningful if the supplied newGarbageCollectionLevel is the currentGarbageCollectionLevel
147
148      @return
149      <=0 if this object still has to be processed.
150      This is the case if it belongs to the surelyReachable set but not to the processedReachable set
151      > otherwise
152
153      <0 if this object has been updated
154      =0 if this object has not been updated, it is surelyReachable
155      >0 if this object has not been updated, it is processedReachable
156      */

157     public int ensureGarbageCollectionLevel(int newGarbageCollectionLevel) {
158         return 0;
159     }
160
161     /**
162      Returns the garbageCollectionLevel this ObjectContainer has reached due to (not) calling {@link #ensureGarbageCollectionLevel}.
163      */

164     public int getGarbageCollectionLevel() {
165         return 0;
166     }
167
168
169     /**
170      * True, when bouth OzoneCompatibles have the same ID.
171      */

172     public boolean equals( Object JavaDoc obj ) {
173         if (obj instanceof ClassicObjectContainer) {
174             ClassicObjectContainer rhs = (ClassicObjectContainer)obj;
175             if (objID.equals( rhs.objID )) {
176                 return true;
177             }
178         }
179
180         return false;
181     }
182
183
184     /** */
185     public void finalizeTarget() throws Exception JavaDoc {
186         //activatedObject().done();
187
// todo replace the done() uncommented above with whatever is appropriate now
188
}
189
190
191     /** */
192     public ObjectID id() {
193         return objID;
194     }
195
196
197     /** */
198     public boolean isCreated() {
199         return created;
200     }
201
202
203     /** */
204     public void deleteTarget() {
205         deleted = true;
206     }
207
208
209     /** */
210     public boolean isDeleted() {
211         return deleted;
212     }
213
214
215     /** */
216     public Object JavaDoc invokeTarget( Env env, String JavaDoc methodName, String JavaDoc sig, Object JavaDoc[] args ) throws Exception JavaDoc {
217         clusterSpace.touchObject( objID );
218
219         Method method = methodFor( methodName, sig, args );
220         if (method == null) {
221             throw new MethodNotFoundException( methodName );
222         }
223
224         return method.invoke( activatedObject(), args );
225     }
226
227
228     /** */
229     public void touch() {
230         touched = true;
231         ++touchCount;
232         touchTime = System.currentTimeMillis();
233     }
234
235
236     /** */
237     public String JavaDoc name() {
238         return name;
239     }
240
241
242     /** */
243     public void setName( String JavaDoc _name ) {
244         nameTarget( _name );
245     }
246
247
248     /** */
249     public void nameTarget( String JavaDoc _name ) {
250         name = _name;
251     }
252
253
254     /** */
255     public Permissions permissions() {
256         return permissions;
257     }
258
259
260     /**
261      * Build a copy of the encap object. This is based on serialization,
262      * so no clone() method must be implemented by OzoneObjects.
263      */

264     public OzoneCompatible targetClone() throws Exception JavaDoc {
265         ByteArrayOutputStream bout = new ByteArrayOutputStream();
266         ObjectOutputStream out = new ObjectOutputStream( bout );
267         out.writeObject( activatedObject() );
268         out.close();
269         ObjectInputStream in = new ResolvingObjectInputStream( new ByteArrayInputStream( bout.toByteArray() ) );
270         OzoneCompatible result = (OzoneCompatible)in.readObject();
271         in.close();
272
273         return result;
274     }
275
276
277     /**
278      */

279     public OzoneProxy ozoneProxy() {
280         try {
281             String JavaDoc name = objectClass().getName() + PROXYNAME_POSTFIX;
282             OzoneProxy rObj = (OzoneProxy)env.classManager.classForName( name ).newInstance();
283             rObj.remoteID = id();
284             rObj.link = env.database;
285             return rObj;
286         } catch (Exception JavaDoc e) {
287             env.logWriter.newEntry( this, "ozoneProxy(): unable to create proper proxy object.", e, LogWriter.WARN );
288             return new OzoneProxy( id(), env.database );
289         }
290     }
291
292
293     /** */
294     public int lockLevel( Transaction ta ) {
295         return lock.level( ta );
296     }
297
298
299     /**
300      * @return a collection with holders of writeLocker or all
301      * readLocks, i.e. all potential hindering transactions
302      */

303     public DxCollection allLockers() {
304         DxCollection lockerIDs = lock.lockerIDs();
305
306         DxArrayBag result = new DxArrayBag( lockerIDs.count() );
307         DxIterator it = lockerIDs.iterator();
308         while (it.next() != null) {
309             result.add( env.transactionManager.taForID( (TransactionID)it.object() ) );
310         }
311
312         return result;
313     }
314
315
316     /** */
317     public synchronized void notifyAllTAs( Transaction ta ) {
318         env.logWriter.newEntry( this, ta.toString() + " notify all TAs...", LogWriter.DEBUG3 );
319         lock.notifyAll();
320     }
321
322
323     // #### methods from ClassicObjectContainer ###############################
324

325
326     /**
327      */

328     public OzoneCompatible targetShadow() {
329         return targetShadow;
330     }
331
332
333     /**
334      * Liefert referenz auf das eigentliche objekt. Darf nicht
335      * targetShadow beruecksichtigen, da ClusterSPace darauf aufbaut.
336      */

337     public OzoneCompatible target() {
338         return target;
339     }
340
341
342     /**
343      * Setzen oder loeschen des objektes. <method>commit()</method> ist unteilbar, deshalb
344      * kein snchronized.
345      * Achtung: object ist evtl. gerade geclustert und muss vorher
346      * eingelagert werden; das darf nicht hier gemacht werden, da
347      * diese methode auch vom store benutzt wird.
348      */

349     protected OzoneCompatible setObject( OzoneCompatible obj ) {
350         OzoneCompatible old = target;
351         target = obj;
352         if (target != null) {
353             target.setContainer( this );
354             if (targetShadow != null) {
355                 env.logWriter.newEntry( this, "setObject(): targetShadow != null !", LogWriter.WARN );
356             }
357         }
358         return old;
359     }
360
361
362     /** */
363     protected void setOwner( User newOwner ) {
364         permissions.setOwner( newOwner );
365     }
366
367
368     /** */
369     protected int touchCount() {
370         return touchCount;
371     }
372
373
374     /** */
375     protected boolean touched() {
376         return touched;
377     }
378
379
380     /** */
381     protected long touchTime() {
382         return touchTime;
383     }
384
385
386     /** */
387     protected ClusterID clusterID() {
388         return clusterID;
389     }
390
391
392     /** */
393     protected void setClusterID( ClusterID _clusterID ) {
394         clusterID = _clusterID;
395     }
396
397
398     /**
399      */

400     protected Class JavaDoc objectClass() throws Exception JavaDoc {
401         return activatedObject().getClass();
402     }
403
404
405     /**
406      * Liefert referenz auf das eigentliche objekt; das objekt wird
407      * nachgeladen, wenn es gerade nicht aktiv ist; waehrend einer
408      * update-ta wird nur der clone bearbeitet und somit auch
409      * nicht nachgeladen
410      */

411     protected OzoneCompatible activatedObject() throws Exception JavaDoc {
412         //meistens sollte _object initialisiert sein, deshalb wird
413
//das zuerst geprueft
414
if (target != null) {
415             return target;
416         } else if (targetShadow != null) {
417             return targetShadow;
418         } else {
419             clusterSpace.activateObject( this );
420             return target;
421         }
422     }
423
424
425     /** */
426     protected synchronized void commitTarget( Transaction ta ) {
427         if (targetShadow != null) {
428             target = targetShadow;
429             targetShadow = null;
430             targetBackup = null;
431         }
432         created = false;
433         lock.release( ta );
434     }
435
436
437     /** */
438     protected synchronized void abortTarget( Transaction ta ) {
439         if (targetShadow != null) {
440             try {
441                 ObjectInputStream in = new ResolvingObjectInputStream( new ByteArrayInputStream( targetBackup ) );
442                 target = (OzoneCompatible)in.readObject();
443                 in.close();
444             } catch (Exception JavaDoc e) {
445                 //kann/darf eigentlich nicht passieren
446
env.logWriter.newEntry( this, "abortObject(): ", e, LogWriter.WARN );
447                 target = null;
448             }
449             targetShadow = null;
450             targetBackup = null;
451         }
452         created = false;
453         deleted = false;
454         lock.release( ta );
455     }
456
457
458     /** */
459     protected synchronized void upgradeLockLevel( Transaction ta, int lockLevel ) throws Exception JavaDoc {
460         activatedObject();
461         lock.tryAcquire( ta, Lock.LEVEL_READ );
462         if (lockLevel > Lock.LEVEL_READ) {
463             lock.tryAcquire( ta, lockLevel );
464             // TODO: Should new created object be shadowed or not ??
465
if (!isCreated()) {
466                 createShadow();
467             }
468         }
469     }
470
471
472     /** */
473     protected synchronized void createShadow() throws Exception JavaDoc {
474         try {
475             ByteArrayOutputStream bout = new ByteArrayOutputStream();
476             ObjectOutputStream out = new ObjectOutputStream( bout );
477             out.writeObject( activatedObject() );
478             out.close();
479             targetBackup = bout.toByteArray();
480             targetShadow = target;
481             target = null;
482         } catch (Exception JavaDoc e) {
483             // darf/kann nicht passieren
484
env.logWriter.newEntry( this, "lockWrite(): ", e, LogWriter.WARN );
485         }
486     }
487
488
489     /**
490      * In stream schreiben - fuer DxDiskHashtable
491      */

492     public void writeExternal( ObjectOutput out ) throws IOException {
493         // if (_object != null)
494
// System.out.print ("#");
495
// else if (_targetShadow != null)
496
// System.out.print ("*");
497
// else
498
// System.out.print ("+");
499

500         out.writeByte( subSerialVersionUID );
501
502         out.writeObject( permissions );
503         out.writeObject( objID );
504         out.writeObject( target );
505         out.writeObject( targetShadow );
506         out.writeObject( targetBackup );
507         out.writeObject( name );
508         out.writeObject( clusterID );
509         out.writeLong( touchTime );
510         out.writeShort( touchCount );
511         out.writeBoolean( touched );
512         out.writeBoolean( created );
513         out.writeBoolean( deleted );
514         out.writeObject( lock );
515     }
516
517
518     /**
519      * Read from the stream - fuer DxDiskHashtable. The objID is
520      * normally referensed from the objID of the object.
521      */

522     public synchronized void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException JavaDoc {
523         env = Env.currentEnv();
524         clusterSpace = ((ClassicStore)env.getStoreManager()).objectSpace.clusterSpace;
525
526         byte streamVersionUID = in.readByte();
527
528         permissions = (Permissions)in.readObject();
529         objID = (ObjectID)in.readObject();
530         target = (OzoneCompatible)in.readObject();
531         targetShadow = (OzoneCompatible)in.readObject();
532         targetBackup = (byte[])in.readObject();
533         if (target != null) {
534             target.setContainer( this );
535         }
536         if (targetShadow != null) {
537             targetShadow.setContainer( this );
538         }
539
540         name = (String JavaDoc)in.readObject();
541         clusterID = (ClusterID)in.readObject();
542         touchTime = in.readLong();
543         touchCount = in.readShort();
544         touched = in.readBoolean();
545         created = in.readBoolean();
546         deleted = in.readBoolean();
547         lock = (Lock)in.readObject();
548
549     // if (_object != null)
550
// System.out.print (".");
551
// else if (_targetShadow != null)
552
// System.out.print (";");
553
// else
554
// System.out.print ("-");
555
}
556
557
558     /**
559      * Write to the Stream. Wird vom ClusterSpace verwendet.
560      */

561     protected void storeExternal( ObjectOutput out ) throws IOException {
562         out.writeLong( serialVersionUID );
563         out.writeObject( permissions );
564         out.writeObject( objID );
565         out.writeObject( name );
566         out.writeObject( clusterID );
567     }
568
569
570     /**
571      * Read from the stream - fuer ClusterSpace. Normally, objID is
572      * a referenz of the objID in the object.
573      */

574     protected void loadExternal( ObjectInput in ) throws IOException, ClassNotFoundException JavaDoc {
575         env = Env.currentEnv();
576         clusterSpace = ((ClassicStore)env.getStoreManager()).objectSpace.clusterSpace;
577
578         long streamSerialVersionUID = in.readLong();
579         permissions = (Permissions)in.readObject();
580         objID = (ObjectID)in.readObject();
581         name = (String JavaDoc)in.readObject();
582         clusterID = (ClusterID)in.readObject();
583
584         created = false;
585         deleted = false;
586         touchTime = System.currentTimeMillis();
587         touchCount = 1;
588         touched = false;
589         //lock = new DefaultLock();
590
// todo assign lock to one of the new lock implemetations
591
}
592
593
594     /**
595      * Search the method with the specified name and signature. Ones
596      * a method has been invoked it is stored in a global cache that holds
597      * the method objects of all database classes.
598      */

599     private Method methodFor( String JavaDoc methodName, String JavaDoc sig, Object JavaDoc[] args ) throws Exception JavaDoc {
600         String JavaDoc key = objectClass().getName() + methodName + sig;
601
602         Method method = (Method)methodTable.elementForKey( key );
603         // Method method = null;
604
if (method == null) {
605             int argNum = args.length;
606             Class JavaDoc[] classes = new Class JavaDoc[argNum];
607             if (sig == null) {
608                 //signatur aus den argumenten generieren; kann natuerlich
609
//falsch sein
610
for (int i = 0; i < argNum; i++) {
611                     classes[i] = args[i].getClass();
612                 }
613             } else {
614                 //signatur aus dem sig-string vom proxy generieren
615
StringTokenizer st = new StringTokenizer( sig, OPP.SIGNATURE_DELIMITER );
616                 int i = 0;
617                 while (st.hasMoreTokens()) {
618                     classes[i++] = env.classManager.classForName( st.nextToken() );
619                 }
620             // classes[i++] = Class.forName (st.nextToken());
621
}
622             method = objectClass().getMethod( methodName, classes );
623             methodTable.addForKey( method, key );
624         }
625
626         return method;
627     }
628 }
629
Popular Tags