KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ozoneDB > ExternalDatabase


1 // You can redistribute this software and/or modify it under the terms of
2
// the Ozone Library 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: ExternalDatabase.java,v 1.21 2003/11/07 21:34:21 per_nyfelt Exp $
8

9 package org.ozoneDB;
10
11 import java.io.IOException JavaDoc;
12 import java.net.MalformedURLException JavaDoc;
13 import java.net.UnknownHostException JavaDoc;
14 import java.net.URISyntaxException JavaDoc;
15 import java.net.URI JavaDoc;
16 import java.util.Hashtable JavaDoc;
17 import java.util.StringTokenizer JavaDoc;
18 import javax.transaction.xa.XAResource JavaDoc;
19
20 import org.ozoneDB.DxLib.*;
21 import org.ozoneDB.core.DbRemote.*;
22 import org.ozoneDB.core.Transaction;
23 import org.ozoneDB.core.TransactionID;
24 import org.ozoneDB.core.admin.Admin;
25 import org.ozoneDB.core.admin.AdminImpl;
26 import org.ozoneDB.xa.OzoneXAResource;
27 import org.ozoneDB.xml.util.SAXChunkConsumer;
28 import org.w3c.dom.Document JavaDoc;
29 import org.w3c.dom.Node JavaDoc;
30 import org.xml.sax.ContentHandler JavaDoc;
31
32
33 /**
34  * Base class for implementations of the OzoneInterface which are used from
35  * a client application to access an ozone.<p>
36  *
37  * Each thread is associated with a server connection. This connection is used
38  * if the thread is not associated with a transaction. Otherwise the connection
39  * of the transaction is used. So in case the thread has *joined* a transaction
40  * it does not use its own connection but the connection of the transaction.
41  * The prepare/commit/abort methods don't need to be called from the thread that
42  * is joined to the transaction.<p>
43  *
44  * Impl. note: The OzoneInterface methods don't need to be synchronized any
45  * longer because each threads has its own connection.<p>
46  *
47  * @author <a HREF="http://www.softwarebuero.de/">SMB</a>
48  * @author <a HREF="http://www.medium.net/">Medium.net</a>
49  * @version $Revision: 1.21 $Date: 2003/11/07 21:34:21 $
50  * @see OzoneInterface
51  */

52 public abstract class ExternalDatabase extends AbstractDatabase {
53
54     // Constants
55

56     public final static String JavaDoc PROP_HOST = "host";
57
58     public final static String JavaDoc PROP_PORT = "port";
59
60     public final static String JavaDoc PROP_DIR = "dir";
61
62     public final static String JavaDoc PROP_USER = "user";
63
64     public final static String JavaDoc PROP_PASSWD = "passwd";
65
66     public final static String JavaDoc PROP_DEBUG = "debug";
67
68     // Data
69

70     /**
71      * The wrapper that uses this as its delegate or null if there is no such
72      * wrapper. Especially the linkForProxy() calls are redirected to the
73      * wrapper to have the proxies link to the wrapper instead of this database.
74      */

75     private ExternalDatabase wrapper;
76
77     /**
78      * Table of all current external transactions (thread -> transaction).
79      */

80     private DxMap txTable;
81
82     /**
83      * Pool of currently available database connections.
84      */

85     private DxDeque apool;
86
87     /**
88      * Pool of currently used database connections.
89      */

90     private DxSet upool;
91
92     /**
93      * The XAResource of this database connection.
94      */

95     private XAResource JavaDoc xares;
96
97     /**
98      * If this is non-null it is used by all threads as the current transaction.
99      */

100     // private AbstractTransaction globalTX;
101

102     /**
103      * All ExternalDatabase objects that have been created in the current VM.
104      * This is used by the forThread() method.
105      */

106     private static DxBag databases = new DxArrayBag();
107
108
109     /**
110      * Static method to find a database connection that has an associated
111      * transaction that has been joined by the given thread. Used by proxy
112      * constructors to determine its database. This method returns the first
113      * database that was found.
114      *
115      *
116      * @param _thread The thread for which to find the corresponding database.
117      * @return The database for the given thread.
118      */

119     public static ExternalDatabase forThread(Thread JavaDoc _thread) {
120         DxIterator it = databases.iterator();
121         ExternalDatabase db;
122         while ((db = (ExternalDatabase) it.next()) != null) {
123             DxSet threads = db.txTable.keySet();
124             if (threads.contains(_thread)) {
125                 return db;
126             }
127         }
128         return null;
129     }
130
131
132     // Constructors ***************************************
133

134     public ExternalDatabase() {
135     }
136
137
138     // XAResource factory *********************************
139

140     /**
141      * Return a new XAResource for this database connection.
142      * @return new XAResource.
143      */

144     public final XAResource JavaDoc getXAResource() {
145         if (xares == null) {
146             synchronized (this) {
147                 if (xares == null) {
148                     xares = new OzoneXAResource(this);
149                 }
150             }
151         }
152         return xares;
153     }
154
155
156     // external transaction handling **********************
157

158     protected final AbstractTransaction txForThread(Thread JavaDoc thread) {
159         return (AbstractTransaction) txTable.elementForKey(thread);
160     }
161
162
163     /**
164      * Create a new transaction. Before using this transaction it must be started.
165      *
166      * @return The newly created transaction.
167      */

168     public ExternalTransaction newTransaction() {
169         return new ExternalTransaction(this);
170     }
171
172
173     /**
174      * Obtain the {@link ExternalTransaction} that is assocaited to the
175      * caller's thread or null, if there is no such transaction. This does not
176      * necessarily mean that there is no transaction associated to this
177      * thread at all. For example there might be an XA transaction.
178      *
179      * @return The transaction that is associated to the caller's thread.
180      * @see #currentTransaction()
181      */

182     public ExternalTransaction currentExternalTransaction() {
183         AbstractTransaction atx = txForThread(Thread.currentThread());
184
185         if (atx instanceof ExternalTransaction) {
186             return (ExternalTransaction) atx;
187         } else {
188             return null;
189         }
190     }
191
192
193     /**
194      * Obtain the transaction that is assocaited to the caller's thread or null,
195      * if there is no such transaction. The transaction might be an instance
196      * of any subclass of AbstractTransaction, which includes also non-user
197      * transactions like org.ozoneDB.xa.XATransaction.
198      *
199      * @return The transaction that is associated to the caller's thread.
200      * @see #currentExternalTransaction()
201      */

202     public AbstractTransaction currentTransaction() {
203         return txForThread(Thread.currentThread());
204     }
205
206
207     /**
208      * This method is never directly called from the client code.
209      */

210     public void beginTX(AbstractTransaction tx) throws TransactionException, IOException JavaDoc {
211
212         // check if the transaction is already started
213
if (tx.connection != null) {
214             throw new TransactionException("Transaction already started.", TransactionException.STATE);
215         }
216
217         synchronized (tx) {
218             try {
219                 tx.connection = acquirePooledConnection();
220                 joinTX(tx);
221
222                 // exceptions are catched and re-thrown be sendCommand()
223
TransactionID taID = (TransactionID) sendCommand(new DbTransaction(DbTransaction.MODE_BEGIN), true, tx.connection);
224             } catch (IOException JavaDoc e) {
225                 throw e;
226             } catch (Exception JavaDoc e) {
227                 throw new TransactionException(e.toString(), TransactionException.UNEXPECTED);
228             }
229         }
230     }
231
232
233     /**
234      * This method is never directly called from the client code.
235      */

236     public void joinTX(AbstractTransaction tx) throws TransactionException {
237         Thread JavaDoc thread = Thread.currentThread();
238
239         synchronized (txTable) {
240             // check if the current thread is already joined to a transaction
241
AbstractTransaction txOfThread = (AbstractTransaction) txTable.elementForKey(thread);
242             if (txOfThread != null && txOfThread != tx) {
243                 throw new TransactionException("Thread is already joined to a transaction.", TransactionException.STATE);
244             }
245             txTable.addForKey(tx, thread);
246         }
247     }
248
249
250     /**
251      * This method is never directly called from the client code.
252      */

253     public boolean leaveTX(AbstractTransaction tx) {
254         return txTable.removeForKey(Thread.currentThread()) != null;
255     }
256
257
258     /**
259      * This method is never directly called from the client code.
260      */

261     public void checkpointTX(AbstractTransaction tx) throws TransactionException, IOException JavaDoc {
262         commandTX(tx, new DbTransaction(DbTransaction.MODE_CHECKPOINT));
263     }
264
265
266     /**
267      * This method is never directly called from the client code.
268      */

269     public void prepareTX(AbstractTransaction tx) throws TransactionException, IOException JavaDoc {
270         if (tx.connection == null) {
271             throw new TransactionException("Illegal state.", TransactionException.STATE);
272         }
273         commandTX(tx, new DbTransaction(DbTransaction.MODE_PREPARE));
274     }
275
276
277     /**
278      * This method is never directly called from the client code.
279      */

280     public void commitTX(AbstractTransaction tx, boolean onePhase) throws TransactionException, IOException JavaDoc {
281         synchronized (tx) {
282             if (tx.connection == null) {
283                 throw new TransactionException("Illegal state.", TransactionException.STATE);
284             }
285
286             if (onePhase) {
287                 commandTX(tx, new DbTransaction(DbTransaction.MODE_COMMIT_ONEPHASE));
288             } else {
289                 commandTX(tx, new DbTransaction(DbTransaction.MODE_COMMIT_TWOPHASE));
290             }
291             releasePooledConnection(tx.connection);
292             tx.connection = null;
293         }
294
295         synchronized (txTable) {
296             // disassociate all threads that have joined the transaction
297
DxIterator it = txTable.iterator();
298             AbstractTransaction cursorTX;
299             while ((cursorTX = (AbstractTransaction) it.next()) != null) {
300                 if (cursorTX == tx) {
301                     it.removeObject();
302                 }
303             }
304         }
305     }
306
307
308     /**
309      * This method is never directly called from the client code.
310      */

311     public void rollbackTX(AbstractTransaction tx) throws TransactionException, IOException JavaDoc {
312         synchronized (tx) {
313             if (tx.connection == null) {
314                 // don't throw an exception to allow subsequent calls
315
return;
316             }
317             commandTX(tx, new DbTransaction(DbTransaction.MODE_ABORT));
318             releasePooledConnection(tx.connection);
319             tx.connection = null;
320         }
321
322         synchronized (txTable) {
323             // disassociate all threads that have joined the transaction
324
DxIterator it = txTable.iterator();
325             AbstractTransaction cursorTX;
326             while ((cursorTX = (AbstractTransaction) it.next()) != null) {
327                 if (cursorTX == tx) {
328                     it.removeObject();
329                 }
330             }
331         }
332     }
333
334
335     /**
336      * Obtain the _internal_ server status of this transaction.
337      * @return Status of the transaction. Defined in
338      * {@link org.ozoneDB.core.Transaction}.<p>
339      *
340      * This method is never directly called from the client code.
341      */

342     public final int getStatusTX(AbstractTransaction tx) throws TransactionException, IOException JavaDoc {
343         if (tx.connection == null) {
344             return Transaction.STATUS_NONE;
345         } else {
346             DbTransaction command = new DbTransaction(DbTransaction.MODE_STATUS);
347             commandTX(tx, command);
348             return ((Integer JavaDoc) command.result).intValue();
349         }
350     }
351
352
353     /**
354      * This method is never directly called from the client code.
355      */

356     protected final Object JavaDoc commandTX(AbstractTransaction tx, DbTransaction command) throws TransactionException, IOException JavaDoc {
357         if (tx.connection == null) {
358             throw new TransactionException("Thread has not yet joined a transaction.", TransactionException.STATE);
359         }
360
361         try {
362             // exceptions are catched and re-thrown be sendCommand();
363
// use the connection of the transaction to allow non-joined
364
// transaction to complete the transaction
365
return sendCommand(command, true, tx.connection);
366         } catch (IOException JavaDoc e) {
367             throw e;
368         } catch (TransactionException e) {
369             throw e;
370         } catch (Exception JavaDoc e) {
371             throw new TransactionException(e.toString(), TransactionException.UNEXPECTED);
372         }
373     }
374
375
376     // connection pooling *********************************
377

378
379     /**
380      * The way for the actual database types to create a corresponding
381      * connection.
382      */

383     protected abstract DbClient newConnection() throws Exception JavaDoc;
384
385
386     /**
387      * Get a connection from the connection pool.<p>
388      *
389      * Earlier versions kept one connection for each client thread. That is,
390      * client threads were directly mapped to server threads. Especially for
391      * servlet environment this produces a lot of connections (server threads),
392      * which in fact is not needed.<p>
393      *
394      * So we are using a pool of connections now. Connections are actually
395      * created and added to the pool when the pool is empty. Currently connections
396      * are never closed once they are added to the pool.
397      *
398      */

399     protected final DbClient acquirePooledConnection() throws Exception JavaDoc {
400         // keep both pools stable while we are messing with them
401
synchronized (apool) {
402             synchronized (upool) {
403                 if (apool.isEmpty()) {
404                     DbClient connection = newConnection();
405                     apool.push(connection);
406                 }
407                 DbClient connection = (DbClient) apool.pop();
408                 if (upool.add(connection) == false) {
409                     throw new IllegalStateException JavaDoc("Connection is already in use.");
410                 }
411                 return connection;
412             }
413         }
414     }
415
416
417     /**
418      * Release a formerly acquired pooled connection so that it may used by
419      * another request.
420      *
421      * @param connection The pooled connection to be released
422      * @see #acquirePooledConnection
423      */

424     protected final void releasePooledConnection(DbClient connection) {
425         // keep both pools stable while we are messing with it
426
synchronized (apool) {
427             synchronized (upool) {
428                 if (upool.remove(connection) == false) {
429                     throw new IllegalStateException JavaDoc("Given connection is not element of the pool of used connections.");
430                 }
431                 apool.push(connection);
432             }
433         }
434     }
435
436
437     /**
438      * Return the server connection for the specified thread. If the thread is
439      * not yet joined to a connection create a new one and associate with the
440      * thread.
441      */

442 // protected final DbClient connectionForThread( Thread thread ) throws Exception {
443
// if (!isOpen()) {
444
// throw new RuntimeException( "Database not open" );
445
// }
446
//
447
// // is there a connection associated to this thread?
448
// DbClient connection = (DbClient)connectionTable.elementForKey( thread );
449
//
450
// if (connection == null) {
451
// synchronized (connectionTable) {
452
// // close all connections that are no longer used by a thread;
453
// // don't re-use connections because they are not really stateless
454
// DxIterator it = connectionTable.iterator();
455
// while (it.next() != null) {
456
// if (!((Thread)it.key()).isAlive()) {
457
// // System.out.println ("closing connection...");
458
// connection = (DbClient)it.removeObject();
459
// connection.send( new DbCloseConn() );
460
// connection.close();
461
// }
462
// }
463
// // make a new connection
464
// connection = newConnection();
465
// connectionTable.addForKey( connection, thread );
466
// }
467
// }
468
// return connection;
469
// }
470

471
472     /**
473      * Send the specified command to the server. If there is a global
474      * transaction, its connection is used. Else, if the current thread is joined
475      * to a transaction the connection of the transaction is used. Otherwise a
476      * connection from the pool is used.
477      */

478     protected final Object JavaDoc sendCommand(DbCommand command, boolean waitForResult) throws Exception JavaDoc,IOException JavaDoc,TransactionException,ClassNotFoundException JavaDoc,org.ozoneDB.OzoneObjectException {
479         if (!isOpen()) {
480             throw new IllegalStateException JavaDoc("Database is not open.");
481         }
482         Thread JavaDoc thread = Thread.currentThread();
483
484         AbstractTransaction txOfThread = (AbstractTransaction) txTable.elementForKey(thread);
485         if (txOfThread != null) {
486             DbClient connection = txOfThread.connection;
487             return sendCommand(command, waitForResult, connection);
488         } else {
489             DbClient connection = null;
490             try {
491                 connection = acquirePooledConnection();
492                 return sendCommand(command, waitForResult, connection);
493             } finally {
494                 releasePooledConnection(connection);
495             }
496         }
497     }
498
499
500     /**
501      * Send the specified command to the server. Use the specified connection.
502      * While working the connection is synchronized to allow multiple threads
503      * to use this connection.
504      *
505      * @param waitForResult
506      * true: read the result from the external database and return it
507      * false: do not read the result from the external database and return null.
508      * This is dangerous if not properly used. In this case, the result
509      * is not read from the stream and left to be read from the next reader.
510      * As this is not desireable, only supply false if the command does not return any result.
511      */

512     protected Object JavaDoc sendCommand(DbCommand command,boolean waitForResult,DbClient connection) throws Exception JavaDoc,IOException JavaDoc,TransactionException,ClassNotFoundException JavaDoc,OzoneObjectException {
513
514         Object JavaDoc result = null;
515
516         // this allows multiple thread to use one connection; this happens,
517
// if a thread joines a thransaction instead of beginning it
518
synchronized (connection) {
519             connection.send(command);
520             if (waitForResult) {
521                 //read the result and set proxy links
522
result = connection.receive();
523
524                 if (result != null) {
525                     // FIXME: It is not wise to overload the result with both a normal result and an exception.
526
if (result instanceof Throwable JavaDoc) {
527                         if (result instanceof RuntimeException JavaDoc) {
528                             if (result instanceof OzoneObjectException) {
529                                 throw (OzoneObjectException) result;
530                             } else {
531                                 ((Exception JavaDoc)result).fillInStackTrace();
532                                 throw (RuntimeException JavaDoc) result;
533                             }
534                         } else if (result instanceof Exception JavaDoc) {
535                             ((Exception JavaDoc)result).fillInStackTrace();
536                             throw (Exception JavaDoc) result;
537                         } else {
538                             if (result instanceof Error JavaDoc) {
539                                 ((Error JavaDoc) result).fillInStackTrace();
540                                 throw (Error JavaDoc) result;
541                             }
542                         }
543                     }
544                 }
545             }
546         }
547         return result;
548     }
549
550
551     protected ExternalDatabase linkForProxy(OzoneProxy proxy) {
552         ExternalDatabase link = wrapper != null ? wrapper : this;
553         // System.out.println ("*** linkForProxy(): " + link.getClass().getName());
554
return link;
555     }
556
557
558     protected synchronized void setWrapper(ExternalDatabase _wrapper) {
559         wrapper = _wrapper;
560     }
561
562
563     // OzoneInterface methods *****************************
564

565
566     public boolean isOpen() throws Exception JavaDoc {
567         return txTable!=null;
568     }
569
570
571     /**
572      * Open this database connection according to the specified properties.
573      */

574     protected void open(Hashtable JavaDoc _props) throws Exception JavaDoc {
575         txTable = new DxHashMap();
576         apool = new DxArrayDeque(32);
577         upool = new DxHashSet(32);
578
579         databases.add(this);
580     }
581
582
583     /**
584      * Factory method that creates a new database object. The actual type of the
585      * database object ({@link ExternalDatabase} or {@link LocalDatabase})
586      * depends on the specified database URL. The returned database connection
587      * is already open.
588      */

589     public static ExternalDatabase openDatabase(String JavaDoc _url, String JavaDoc _username, String JavaDoc _passwd) throws Exception JavaDoc {
590
591         Hashtable JavaDoc props = createProps(_url);
592         props.put(PROP_USER, _username);
593         props.put(PROP_PASSWD, _passwd);
594
595         if (_url.startsWith("ozonedb:remote")) {
596             RemoteDatabase db = new RemoteDatabase();
597             db.open(props);
598             return db;
599         } else if (_url.startsWith("ozonedb:local")) {
600             LocalDatabase db = new LocalDatabase();
601             db.open(props);
602             return db;
603         } else {
604             throw new MalformedURLException JavaDoc(_url);
605         }
606     }
607
608
609     /**
610      * @param _url The URL of the database (ozonedb:remote://host:port?user=<name>&password=<pwd> or
611      * ozonedb:local:///datadir?user=<name>&password=<pwd>)
612      */

613     public static ExternalDatabase openDatabase(String JavaDoc _url) throws Exception JavaDoc {
614
615         Hashtable JavaDoc props = createProps(_url);
616
617         if (_url.startsWith("ozonedb:remote")) {
618             RemoteDatabase db = new RemoteDatabase();
619             db.open(props);
620             return db;
621         } else if (_url.startsWith("ozonedb:local")) {
622             LocalDatabase db = new LocalDatabase();
623             db.open(props);
624             return db;
625         } else {
626             throw new MalformedURLException JavaDoc(_url);
627         }
628     }
629
630
631     /**
632      * @param _url The URL of the database (ozonedb:remote://host:port or
633      * ozonedb:local://datadir)
634      */

635     protected static Hashtable JavaDoc createProps(String JavaDoc _url) throws URISyntaxException JavaDoc, UnknownHostException JavaDoc {
636         Hashtable JavaDoc props = new Hashtable JavaDoc();
637
638         URI JavaDoc uri = new URI JavaDoc(_url);
639         String JavaDoc protocol = uri.getScheme();
640         if (!protocol.equals("ozonedb")) {
641             throw new URISyntaxException JavaDoc(_url, "unknown protocol: " + protocol);
642         }
643
644         URI JavaDoc subUri = new URI JavaDoc(uri.getSchemeSpecificPart());
645
646         String JavaDoc protocol2 = subUri.getScheme();
647         if (protocol2.equals("local")) {
648             String JavaDoc filename = subUri.getPath();
649             props.put(PROP_DIR, filename);
650         } else if (protocol2.equals("remote")) {
651             String JavaDoc hostname = subUri.getHost();
652             if (hostname == null) throw new UnknownHostException JavaDoc("host is null");
653             int port = subUri.getPort();
654             props.put(PROP_HOST, hostname);
655             props.put(PROP_PORT, new Integer JavaDoc(port));
656         } else {
657             throw new URISyntaxException JavaDoc(_url, "protocol: " + protocol2);
658         }
659
660         String JavaDoc query = subUri.getQuery();
661         // Note: could have use the (now deprecated) javax.servlet.http.HttpUtils.parseQueryString(),
662
// but that would come at the cost of ozone being j2ee dependend...
663
String JavaDoc user = null;
664         String JavaDoc password = null;
665         if (query != null) {
666             for(StringTokenizer JavaDoc amp = new StringTokenizer JavaDoc(query, "&"); amp.hasMoreElements(); ) {
667                 String JavaDoc keyWithValue = amp.nextToken();
668                 StringTokenizer JavaDoc eq = new StringTokenizer JavaDoc(keyWithValue, "=");
669                 if (eq.countTokens() != 2) throw new URISyntaxException JavaDoc(_url, "could not parse: " + keyWithValue);
670                 String JavaDoc key = eq.nextToken();
671                 if (key.equals("user")) {
672                     if (user == null) {
673                         user = eq.nextToken();
674                     } else throw new URISyntaxException JavaDoc(_url, "duplicate occurence of option " + key);
675                 } else if (key.equals("password")) {
676                     if (password == null) {
677                         password = eq.nextToken();
678                     } else throw new URISyntaxException JavaDoc(_url, "duplicate occurence of option " + key);
679                 } else throw new URISyntaxException JavaDoc(_url, "unknown option " + key);
680             }
681         }
682
683         if (user == null) {
684             user = System.getProperty("org.ozoneDB.user.name");
685             if (user == null) {
686                 user = System.getProperty("user.name");
687             }
688             if (user == null) {
689                 user="noname";
690             }
691         }
692         if (password == null) {
693             password = "";
694         }
695         props.put(PROP_USER, user);
696         props.put(PROP_PASSWD, password);
697
698         return props;
699     }
700
701     /**
702      * Close this database.
703      */

704     public synchronized void close() throws Exception JavaDoc {
705         if (isOpen()) {
706             databases.remove(this);
707
708             // close all current database connections.
709
try {
710                 apool.addAll(upool);
711
712                 DxIterator it = apool.iterator();
713                 DbClient connection;
714                 while ((connection = (DbClient) it.next()) != null) {
715                     try {
716                         connection.send(new DbCloseConn());
717                     }catch(java.io.IOException JavaDoc e){
718                         //lost connection, so couldn't send
719
//but we're trying to close, so that's OK
720
}
721                     Thread.sleep(1000);
722                     try {
723                         connection.close();
724                     }catch(java.io.IOException JavaDoc e){
725                         //lost connection, so couldn't send
726
//but we're trying to close, so that's OK
727
}
728                     it.removeObject();
729                 }
730             } finally {
731                 apool = null;
732                 upool = null;
733                 txTable = null;
734             }
735         }
736     }
737
738
739     protected void finalize() throws Throwable JavaDoc {
740         close();
741     }
742
743
744     public void reloadClasses() throws Exception JavaDoc {
745         Integer JavaDoc result = (Integer JavaDoc) sendCommand(new DbReloadClasses(), true);
746     }
747
748
749     public OzoneProxy createObject( String JavaDoc className, int access, String JavaDoc name, String JavaDoc sig, Object JavaDoc[] args ) throws RuntimeException JavaDoc, OzoneObjectException {
750         try {
751             OzoneProxy proxy = (OzoneProxy) sendCommand( new DbCreateObj( className, access, name, sig, args ), true );
752
753             if (org.ozoneDB.core.Env.selfCheck) {
754                 if (proxy==null) { // The proxy should never be null.
755
throw new Error JavaDoc("Found during createObject(\""+className+"\","+access+","+name+",\""+sig+"\"): returned proxy is "+proxy);
756                 }
757             }
758
759             return proxy;
760         } catch (OzoneObjectException e) {
761             throw e;
762         } catch (RuntimeException JavaDoc e) {
763             throw e;
764         } catch (Exception JavaDoc e) {
765             // only supported from JDK1.4 on
766
// throw new RuntimeException("Caught during createObject(\""+className+"\","+access+","+name+",\""+sig+"\")",e);
767
throw new RuntimeException JavaDoc("Caught during createObject(\""+className+"\","+access+","+name+",\""+sig+"\"): "+e);
768         }
769     }
770
771
772     public void deleteObject( OzoneRemote obj ) throws RuntimeException JavaDoc,OzoneObjectException {
773         try {
774             sendCommand( new DbDeleteObj( (OzoneProxy)obj ), true );
775         } catch (OzoneObjectException e) {
776             throw e;
777         } catch (Exception JavaDoc e) {
778             // only supported from JDK1.4 on
779
throw new RuntimeException JavaDoc("Caught during deleteObject()",e);
780             //throw new RuntimeException("Caught during deleteObject(): "+e);
781
}
782     }
783
784
785     public OzoneProxy copyObject(OzoneRemote obj) throws Exception JavaDoc {
786         return (OzoneProxy) sendCommand(new DbCopyObj((OzoneProxy) obj), true);
787     }
788
789
790     public void nameObject(OzoneRemote obj, String JavaDoc name) throws Exception JavaDoc {
791         sendCommand(new DbNameObj((OzoneProxy) obj, name), true);
792     }
793
794
795     public OzoneProxy objectForName(String JavaDoc name) throws Exception JavaDoc {
796         return (OzoneProxy) sendCommand(new DbObjForName(name), true);
797     }
798
799     public String JavaDoc[] objectNames() throws Exception JavaDoc {
800         //todo: maybe we should filter out Admin (AdminImpl.OZONE_DOCUMENT_FACTORY)?
801
DxSet nameSet = (DxSet)sendCommand(new DbObjectNames(), true);
802         Object JavaDoc[] keys = nameSet.toArray();
803         String JavaDoc[] names = new String JavaDoc[keys.length];
804         for (int i = 0; i < keys.length; i++) {
805             names[i] = (String JavaDoc) keys[i];
806         }
807         return names;
808     }
809
810     public OzoneProxy objectForHandle(String JavaDoc handle) throws Exception JavaDoc {
811         return (OzoneProxy) sendCommand(new DbObjForHandle(handle), true);
812     }
813
814
815     public Object JavaDoc invoke(OzoneProxy rObj, String JavaDoc methodName, String JavaDoc sig, Object JavaDoc[] args, int lockLevel)
816             throws Exception JavaDoc {
817         // Kommando verschicken
818
Object JavaDoc result = sendCommand(new DbInvoke(rObj, methodName, sig, args, lockLevel), true);
819         return result;
820     }
821
822
823     public Object JavaDoc invoke(OzoneProxy rObj, int methodIndex, Object JavaDoc[] args, int lockLevel) throws Exception JavaDoc {
824         // Kommando verschicken
825
Object JavaDoc result = sendCommand(new DbInvoke(rObj, methodIndex, args, lockLevel), true);
826         return result;
827     }
828
829
830     public OzoneCompatible fetch(OzoneProxy rObj, int lockLevel) throws Exception JavaDoc,org.ozoneDB.ObjectNotFoundException, java.io.IOException JavaDoc, java.lang.ClassNotFoundException JavaDoc, org.ozoneDB.TransactionException, org.ozoneDB.core.TransactionError {
831         return null;
832     }
833
834
835     public Node JavaDoc xmlForObject(OzoneRemote rObj, Document JavaDoc domFactory) throws Exception JavaDoc {
836         byte[] bytes = (byte[]) sendCommand(new DbXMLForObj((OzoneProxy) rObj), true);
837
838         SAXChunkConsumer consumer = new SAXChunkConsumer(domFactory, null);
839         consumer.processChunk(bytes);
840
841         return consumer.getResultNode();
842     }
843
844
845     public void xmlForObject(OzoneRemote rObj, ContentHandler JavaDoc ch) throws Exception JavaDoc {
846         byte[] bytes = (byte[]) sendCommand(new DbXMLForObj((OzoneProxy) rObj), true);
847
848         SAXChunkConsumer consumer = new SAXChunkConsumer(ch);
849         consumer.processChunk(bytes);
850     }
851
852
853     /**
854      * Return the administration object for this database.
855      *
856      * @return The admin object for this database;
857      */

858     public Admin admin() throws Exception JavaDoc {
859         Admin admin = (Admin) objectForName(AdminImpl.OBJECT_NAME);
860         return admin;
861     }
862
863     /**
864         Internal method. This method is called by {@link OzoneProxy}s when they are dying (during finalize()). This
865         is required, as the database may track the references the database client has to objects within the database
866         in order to properly support garbage collection. If this method is called from anyone else than from the
867         {@link OzoneProxy}.finalize()-Method, data loss may occur!
868
869         @param proxy the OzoneProxy object which is dying. It may call this method exaclty once.
870     */

871     public void notifyProxyDeath(OzoneProxy proxy) {
872         try {
873             sendCommand(new DbProxyDeath(proxy),false);
874         } catch (Exception JavaDoc e) {
875             // only supported from JDK1.4 on
876
// throw new RuntimeException("Caught during notifyProxyDeath()",e);
877
throw new RuntimeException JavaDoc("Caught during notifyProxyDeath(): "+e);
878         }
879     }
880 }
881
882
Popular Tags