Source Code Cross Referenced for ExternalDatabase.java in  » Database-DBMS » Ozone-1.1 » org » ozoneDB » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » Ozone 1.1 » org.ozoneDB 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // You can redistribute this software and/or modify it under the terms of
002:        // the Ozone Library License version 1 published by ozone-db.org.
003:        //
004:        // The original code and portions created by SMB are
005:        // Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
006:        //
007:        // $Id: ExternalDatabase.java,v 1.5 2002/06/25 11:34:38 mediumnet Exp $
008:
009:        package org.ozoneDB;
010:
011:        import java.io.IOException;
012:        import java.net.MalformedURLException;
013:        import java.util.Hashtable;
014:        import java.util.StringTokenizer;
015:        import javax.transaction.xa.XAResource;
016:
017:        import org.ozoneDB.DxLib.*;
018:        import org.ozoneDB.core.DbRemote.*;
019:        import org.ozoneDB.core.Transaction;
020:        import org.ozoneDB.core.TransactionID;
021:        import org.ozoneDB.core.admin.Admin;
022:        import org.ozoneDB.core.admin.AdminImpl;
023:        import org.ozoneDB.xa.OzoneXAResource;
024:        import org.ozoneDB.xml.util.SAXChunkConsumer;
025:        import org.w3c.dom.Document;
026:        import org.w3c.dom.Node;
027:        import org.xml.sax.ContentHandler;
028:
029:        /**
030:         * Base class for implementations of the OzoneInterface which are used from
031:         * a client application to access an ozone.<p>
032:         *
033:         * Each thread is associated with a server connection. This connection is used
034:         * if the thread is not associated with a transaction. Otherwise the connection
035:         * of the transaction is used. So in case the thread has *joined* a transaction
036:         * it does not use its own connection but the connection of the transaction.
037:         * The prepare/commit/abort methods don't need to be called from the thread that
038:         * is joined to the transaction.<p>
039:         *
040:         * Impl. note: The OzoneInterface methods don't need to be synchronized any
041:         * longer because each threads has its own connection.<p>
042:         *
043:         * @author <a href="http://www.softwarebuero.de/">SMB</a>
044:         * @author <a href="http://www.medium.net/">Medium.net</a>
045:         * @version $Revision: 1.5 $Date: 2002/06/25 11:34:38 $
046:         * @see OzoneInterface
047:         */
048:        public abstract class ExternalDatabase extends AbstractDatabase
049:                implements  OzoneInterface {
050:
051:            // Constants
052:
053:            public final static String PROP_HOST = "host";
054:
055:            public final static String PROP_PORT = "port";
056:
057:            public final static String PROP_DIR = "dir";
058:
059:            public final static String PROP_USER = "user";
060:
061:            public final static String PROP_PASSWD = "passwd";
062:
063:            public final static String PROP_DEBUG = "debug";
064:
065:            // Data
066:
067:            /**
068:             * The wrapper that uses this as its delegate or null if there is no such
069:             * wrapper. Especially the linkForProxy() calls are redirected to the
070:             * wrapper to have the proxies link to the wrapper instead of this database.
071:             */
072:            private ExternalDatabase wrapper;
073:
074:            /**
075:             * Table of all current external transactions. thread -> transaction
076:             */
077:            private DxMap txTable;
078:
079:            /**
080:             * Pool of currently available database connections.
081:             */
082:            private DxDeque apool;
083:
084:            /**
085:             * Pool of currently used database connections.
086:             */
087:            private DxSet upool;
088:
089:            /**
090:             * The XAResource of this database connection.
091:             */
092:            private XAResource xares;
093:
094:            /**
095:             * If this is non-null it is used by all threads as the current transaction.
096:             */
097:            // private AbstractTransaction	globalTX;
098:            /**
099:             * All ExternalDatabase objects that have been created in the current VM.
100:             * This is used by the forThread() method.
101:             */
102:            private static DxBag databases = new DxArrayBag();
103:
104:            /**
105:             * Static method to find a database connection that has an associated
106:             * transaction that has been joined by the given thread. Used by proxy
107:             * constructors to determine its database. This method returns the first
108:             * database that was found.
109:             *
110:             *
111:             * @param _thread The thread for which to find the corresponding database.
112:             * @return The database for the given thread.
113:             */
114:            public static ExternalDatabase forThread(Thread _thread) {
115:                DxIterator it = databases.iterator();
116:                ExternalDatabase db;
117:                while ((db = (ExternalDatabase) it.next()) != null) {
118:                    DxSet threads = db.txTable.keySet();
119:                    if (threads.contains(_thread)) {
120:                        return db;
121:                    }
122:                }
123:                return null;
124:            }
125:
126:            // Constructors ***************************************
127:
128:            public ExternalDatabase() {
129:            }
130:
131:            // XAResource factory *********************************
132:
133:            /**
134:             * Return a new XAResource for this database connection.
135:             * @return new XAResource.
136:             */
137:            public final XAResource getXAResource() {
138:                if (xares == null) {
139:                    synchronized (this ) {
140:                        if (xares == null) {
141:                            xares = new OzoneXAResource(this );
142:                        }
143:                    }
144:                }
145:                return xares;
146:            }
147:
148:            // external transaction handling **********************
149:
150:            protected final AbstractTransaction txForThread(Thread thread) {
151:                return (AbstractTransaction) txTable.elementForKey(thread);
152:            }
153:
154:            /**
155:             * Create a new transaction. Before using this transaction it must be started.
156:             *
157:             * @return The newly created transaction.
158:             */
159:            public ExternalTransaction newTransaction() {
160:                return new ExternalTransaction(this );
161:            }
162:
163:            /**
164:             * Obtain the {@link ExternalTransaction} that is assocaited to the
165:             * caller's thread or null, if there is no such transaction. This does not
166:             * necessarily mean that there is no transaction associated to this
167:             * thread at all. For example there might be an XA transaction.
168:             *
169:             * @return The transaction that is associated to the caller's thread.
170:             * @see #currentTransaction()
171:             */
172:            public ExternalTransaction currentExternalTransaction() {
173:                AbstractTransaction atx = txForThread(Thread.currentThread());
174:
175:                if (atx instanceof  ExternalTransaction) {
176:                    return (ExternalTransaction) atx;
177:                } else {
178:                    return null;
179:                }
180:            }
181:
182:            /**
183:             * Obtain the transaction that is assocaited to the caller's thread or null,
184:             * if there is no such transaction. The transaction might be an instance
185:             * of any subclass of AbstractTransaction, which includes also non-user
186:             * transactions like {@link org.ozoneDB.xa.XATransaction}.
187:             *
188:             * @return The transaction that is associated to the caller's thread.
189:             * @see #currentExternalTransaction()
190:             */
191:            public AbstractTransaction currentTransaction() {
192:                return txForThread(Thread.currentThread());
193:            }
194:
195:            /**
196:             * This method is never directly called from the client code.
197:             */
198:            public void beginTX(AbstractTransaction tx) throws TransactionExc,
199:                    IOException {
200:
201:                // check if the transaction is already started
202:                if (tx.connection != null) {
203:                    throw new TransactionExc("Transaction already started.",
204:                            TransactionExc.STATE);
205:                }
206:
207:                synchronized (tx) {
208:                    try {
209:                        tx.connection = acquirePooledConnection();
210:                        joinTX(tx);
211:
212:                        // exceptions are catched and re-thrown be sendCommand()
213:                        TransactionID taID = (TransactionID) sendCommand(
214:                                new DbTransaction(DbTransaction.MODE_BEGIN),
215:                                true, tx.connection);
216:                    } catch (IOException e) {
217:                        throw e;
218:                    } catch (Exception e) {
219:                        throw new TransactionExc(e.toString(),
220:                                TransactionExc.UNEXPECTED);
221:                    }
222:                }
223:            }
224:
225:            /**
226:             * This method is never directly called from the client code.
227:             */
228:            public void joinTX(AbstractTransaction tx) throws TransactionExc {
229:                Thread thread = Thread.currentThread();
230:
231:                synchronized (txTable) {
232:                    // check if the current thread is already joined to a transaction
233:                    AbstractTransaction txOfThread = (AbstractTransaction) txTable
234:                            .elementForKey(thread);
235:                    if (txOfThread != null && txOfThread != tx) {
236:                        throw new TransactionExc(
237:                                "Thread is already joined to a transaction.",
238:                                TransactionExc.STATE);
239:                    }
240:                    txTable.addForKey(tx, thread);
241:                }
242:            }
243:
244:            /**
245:             * This method is never directly called from the client code.
246:             */
247:            public boolean leaveTX(AbstractTransaction tx) {
248:                return txTable.removeForKey(Thread.currentThread()) != null;
249:            }
250:
251:            /**
252:             * This method is never directly called from the client code.
253:             */
254:            public void checkpointTX(AbstractTransaction tx)
255:                    throws TransactionExc, IOException {
256:                commandTX(tx, new DbTransaction(DbTransaction.MODE_CHECKPOINT));
257:            }
258:
259:            /**
260:             * This method is never directly called from the client code.
261:             */
262:            public void prepareTX(AbstractTransaction tx)
263:                    throws TransactionExc, IOException {
264:                if (tx.connection == null) {
265:                    throw new TransactionExc("Illegal state.",
266:                            TransactionExc.STATE);
267:                }
268:                commandTX(tx, new DbTransaction(DbTransaction.MODE_PREPARE));
269:            }
270:
271:            /**
272:             * This method is never directly called from the client code.
273:             */
274:            public void commitTX(AbstractTransaction tx, boolean onePhase)
275:                    throws TransactionExc, IOException {
276:                synchronized (tx) {
277:                    if (tx.connection == null) {
278:                        throw new TransactionExc("Illegal state.",
279:                                TransactionExc.STATE);
280:                    }
281:
282:                    if (onePhase) {
283:                        commandTX(tx, new DbTransaction(
284:                                DbTransaction.MODE_COMMIT_ONEPHASE));
285:                    } else {
286:                        commandTX(tx, new DbTransaction(
287:                                DbTransaction.MODE_COMMIT_TWOPHASE));
288:                    }
289:                    releasePooledConnection(tx.connection);
290:                    tx.connection = null;
291:                }
292:
293:                synchronized (txTable) {
294:                    // disassociate all threads that have joined the transaction
295:                    DxIterator it = txTable.iterator();
296:                    AbstractTransaction cursorTX;
297:                    while ((cursorTX = (AbstractTransaction) it.next()) != null) {
298:                        if (cursorTX == tx) {
299:                            it.removeObject();
300:                        }
301:                    }
302:                }
303:            }
304:
305:            /**
306:             * This method is never directly called from the client code.
307:             */
308:            public void rollbackTX(AbstractTransaction tx)
309:                    throws TransactionExc, IOException {
310:                synchronized (tx) {
311:                    if (tx.connection == null) {
312:                        // don't throw an exception to allow subsequent calls
313:                        return;
314:                    }
315:                    commandTX(tx, new DbTransaction(DbTransaction.MODE_ABORT));
316:                    releasePooledConnection(tx.connection);
317:                    tx.connection = null;
318:                }
319:
320:                synchronized (txTable) {
321:                    // disassociate all threads that have joined the transaction
322:                    DxIterator it = txTable.iterator();
323:                    AbstractTransaction cursorTX;
324:                    while ((cursorTX = (AbstractTransaction) it.next()) != null) {
325:                        if (cursorTX == tx) {
326:                            it.removeObject();
327:                        }
328:                    }
329:                }
330:            }
331:
332:            /**
333:             * Obtain the _internal_ server status of this transaction.
334:             * @return Status of the transaction. Defined in
335:             * {@link org.ozoneDB.core.Transaction}.<p>
336:             *
337:             * This method is never directly called from the client code.
338:             */
339:            public final int getStatusTX(AbstractTransaction tx)
340:                    throws TransactionExc, IOException {
341:                if (tx.connection == null) {
342:                    return Transaction.STATUS_NONE;
343:                } else {
344:                    DbTransaction command = new DbTransaction(
345:                            DbTransaction.MODE_STATUS);
346:                    commandTX(tx, command);
347:                    return ((Integer) command.result).intValue();
348:                }
349:            }
350:
351:            /**
352:             * This method is never directly called from the client code.
353:             */
354:            protected final Object commandTX(AbstractTransaction tx,
355:                    DbTransaction command) throws TransactionExc, IOException {
356:                if (tx.connection == null) {
357:                    throw new TransactionExc(
358:                            "Thread has not yet joined a transaction.",
359:                            TransactionExc.STATE);
360:                }
361:
362:                try {
363:                    // exceptions are catched and re-thrown be sendCommand();
364:                    // use the connection of the transaction to allow non-joined
365:                    // transaction to complete the transaction
366:                    return sendCommand(command, true, tx.connection);
367:                } catch (IOException e) {
368:                    throw e;
369:                } catch (TransactionExc e) {
370:                    throw e;
371:                } catch (Exception e) {
372:                    throw new TransactionExc(e.toString(),
373:                            TransactionExc.UNEXPECTED);
374:                }
375:            }
376:
377:            // connection pooling *********************************
378:
379:            /**
380:             * The way for the actual database types to create a corresponding
381:             * connection.
382:             */
383:            protected abstract DbClient newConnection() throws Exception;
384:
385:            /**
386:             * Get a connection from the connection pool.<p>
387:             *
388:             * Earlier versions kept one connection for each client thread. That is,
389:             * client threads were directly mapped to server threads. Especially for
390:             * servlet environment this produces a lot of connections (server threads),
391:             * which in fact is not needed.<p>
392:             *
393:             * So we are using a pool of connections now. Connections are actually
394:             * created and added to the pool when the pool is empty. Currently connections
395:             * are never closed once they are added to the pool.
396:             *
397:             * @param DbClient A connection from the pool.
398:             */
399:            protected final DbClient acquirePooledConnection() throws Exception {
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(
410:                                    "Connection is already in use.");
411:                        }
412:                        return connection;
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(
430:                                    "Given connection is not element of the pool of used connections.");
431:                        }
432:                        apool.push(connection);
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:             * Send the specified command to the server. If there is a global
473:             * transaction, its connection is used. Else, if the current thread is joined
474:             * to a transaction the connection of the transaction is used. Otherwise a
475:             * connection from the pool is used.
476:             */
477:            protected final Object sendCommand(DbCommand command,
478:                    boolean waitForResult) throws Exception {
479:                if (!isOpen()) {
480:                    throw new IllegalStateException("Database is not open.");
481:                }
482:                Thread thread = Thread.currentThread();
483:
484:                AbstractTransaction txOfThread = (AbstractTransaction) txTable
485:                        .elementForKey(thread);
486:                if (txOfThread != null) {
487:                    DbClient connection = txOfThread.connection;
488:                    return sendCommand(command, waitForResult, connection);
489:                } else {
490:                    DbClient connection = null;
491:                    try {
492:                        connection = acquirePooledConnection();
493:                        return sendCommand(command, waitForResult, connection);
494:                    } finally {
495:                        releasePooledConnection(connection);
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 sendCommand(DbCommand command,
513:                    boolean waitForResult, DbClient connection)
514:                    throws Exception, ExceptionInOzoneObjectException {
515:
516:                Object result = null;
517:
518:                // this allows multiple thread to use one connection; this happens,
519:                // if a thread joines a thransaction instead of beginning it
520:                synchronized (connection) {
521:                    connection.send(command);
522:                    if (waitForResult) {
523:                        //read the result and set proxy links
524:                        result = connection.receive();
525:
526:                        if (result != null) {
527:                            // FIXME: It is not wise to overload the result with both a normal result and an exception.
528:                            if (result instanceof  RuntimeException) {
529:                                if (result instanceof  ExceptionInOzoneObjectException) {
530:                                    throw (ExceptionInOzoneObjectException) result;
531:                                } else {
532:                                    ((Exception) result).fillInStackTrace();
533:                                    throw (RuntimeException) result;
534:                                }
535:                            } else if (result instanceof  Exception) {
536:                                ((Exception) result).fillInStackTrace();
537:                                throw (Exception) result;
538:                            } else {
539:                                if (result instanceof  Error) {
540:                                    ((Error) result).fillInStackTrace();
541:                                    throw (Error) result;
542:                                }
543:                            }
544:                        }
545:                    }
546:                }
547:                return result;
548:            }
549:
550:            protected ExternalDatabase linkForProxy(OzoneProxy proxy) {
551:                ExternalDatabase link = wrapper != null ? wrapper : this ;
552:                // System.out.println ("*** linkForProxy(): " + link.getClass().getName());
553:                return link;
554:            }
555:
556:            protected synchronized void setWrapper(ExternalDatabase _wrapper) {
557:                wrapper = _wrapper;
558:            }
559:
560:            // OzoneInterface methods *****************************
561:
562:            public boolean isOpen() throws Exception {
563:                return txTable != null;
564:            }
565:
566:            /**
567:             * Open this database connection according to the specified properties.
568:             */
569:            protected void open(Hashtable _props) throws Exception {
570:                txTable = new DxHashMap();
571:                apool = new DxArrayDeque(32);
572:                upool = new DxHashSet(32);
573:
574:                databases.add(this );
575:            }
576:
577:            /**
578:             * Factory method that creates a new database object. The actual type of the
579:             * database object ({@link ExternalDatabase} or {@link LocalDatabase})
580:             * depends on the specified database URL. The returned database connection
581:             * is already open.
582:             */
583:            public static ExternalDatabase openDatabase(String _url,
584:                    String _username, String _passwd) throws Exception {
585:
586:                Hashtable props = createProps(_url);
587:                props.put(PROP_USER, _username);
588:                props.put(PROP_PASSWD, _passwd);
589:
590:                if (_url.startsWith("ozonedb:remote")) {
591:                    RemoteDatabase db = new RemoteDatabase();
592:                    db.open(props);
593:                    return db;
594:                } else if (_url.startsWith("ozonedb:local")) {
595:                    LocalDatabase db = new LocalDatabase();
596:                    db.open(props);
597:                    return db;
598:                } else {
599:                    throw new MalformedURLException(_url);
600:                }
601:            }
602:
603:            /**
604:             * Factory method that creates a new database object. The actual type of the
605:             * database object ({@link ExternalDatabase} or {@link LocalDatabase})
606:             * depends on the specified database URL. The returned database connection
607:             * is already open.
608:             */
609:            public static ExternalDatabase openDatabase(String _url)
610:                    throws Exception {
611:
612:                Hashtable props = createProps(_url);
613:                String userName = System.getProperty("org.ozoneDB.user.name");
614:
615:                if (userName == null) {
616:                    userName = System.getProperty("user.name");
617:                }
618:
619:                props.put(PROP_USER, userName);
620:                props.put(PROP_PASSWD, userName);
621:
622:                if (_url.startsWith("ozonedb:remote")) {
623:                    RemoteDatabase db = new RemoteDatabase();
624:                    db.open(props);
625:                    return db;
626:                } else if (_url.startsWith("ozonedb:local")) {
627:                    LocalDatabase db = new LocalDatabase();
628:                    db.open(props);
629:                    return db;
630:                } else {
631:                    throw new MalformedURLException(_url);
632:                }
633:            }
634:
635:            /**
636:             * @param _url The URL of the database (ozonedb:remote://host:port or
637:             * ozonedb:local://datadir)
638:             */
639:            protected static Hashtable createProps(String _url)
640:                    throws MalformedURLException {
641:                Hashtable props = new Hashtable();
642:
643:                StringTokenizer tkn = new StringTokenizer(_url, ":");
644:                String protocol = tkn.nextToken();
645:                if (!protocol.equals("ozonedb")) {
646:                    throw new MalformedURLException("protocol: " + protocol);
647:                }
648:
649:                String protocol2 = tkn.nextToken();
650:                if (protocol2.equals("local")) {
651:                    String filename = tkn.nextToken();
652:                    // on win the filename may contain ":"
653:                    if (tkn.hasMoreTokens()) {
654:                        filename = filename + ":" + tkn.nextToken();
655:                    }
656:                    props.put(PROP_DIR, filename);
657:                } else if (protocol2.equals("remote")) {
658:                    String hostname = tkn.nextToken();
659:                    if (!hostname.startsWith("//")) {
660:                        throw new MalformedURLException("hostname: " + hostname);
661:                    }
662:                    // skip the leading "//"
663:                    hostname = hostname.substring(2);
664:                    int port = Integer.parseInt(tkn.nextToken());
665:                    props.put(PROP_HOST, hostname);
666:                    props.put(PROP_PORT, new Integer(port));
667:                } else {
668:                    throw new MalformedURLException("protocol: " + protocol2);
669:                }
670:                return props;
671:            }
672:
673:            /**
674:             * Close this database.
675:             */
676:            public synchronized void close() throws Exception {
677:                if (isOpen()) {
678:                    databases.remove(this );
679:
680:                    // close all current database connections.
681:                    try {
682:                        apool.addAll(upool);
683:
684:                        DxIterator it = apool.iterator();
685:                        DbClient connection;
686:                        while ((connection = (DbClient) it.next()) != null) {
687:                            connection.send(new DbCloseConn());
688:                            Thread.sleep(1000);
689:                            connection.close();
690:                            it.removeObject();
691:                        }
692:                    } finally {
693:                        apool = null;
694:                        upool = null;
695:                        txTable = null;
696:                    }
697:                }
698:            }
699:
700:            protected void finalize() throws Throwable {
701:                close();
702:            }
703:
704:            public void reloadClasses() throws Exception {
705:                Integer result = (Integer) sendCommand(new DbReloadClasses(),
706:                        true);
707:            }
708:
709:            public OzoneProxy createObject(String className, int access,
710:                    String name, String sig, Object[] args)
711:                    throws RuntimeException, ExceptionInOzoneObjectException {
712:                try {
713:                    OzoneProxy proxy = (OzoneProxy) sendCommand(
714:                            new DbCreateObj(className, access, name, sig, args),
715:                            true);
716:
717:                    if (org.ozoneDB.core.Env.selfCheck) {
718:                        if (proxy == null) { // The proxy should never be null.
719:                            throw new Error("Found during createObject(\""
720:                                    + className + "\"," + access + "," + name
721:                                    + ",\"" + sig + "\"): returned proxy is "
722:                                    + proxy);
723:                        }
724:                    }
725:
726:                    return proxy;
727:                } catch (ExceptionInOzoneObjectException e) {
728:                    throw e;
729:                } catch (RuntimeException e) {
730:                    throw e;
731:                } catch (Exception e) {
732:                    // only supported from JDK1.4 on
733:                    //          throw new RuntimeException("Caught during createObject(\""+className+"\","+access+","+name+",\""+sig+"\")",e);
734:                    throw new RuntimeException("Caught during createObject(\""
735:                            + className + "\"," + access + "," + name + ",\""
736:                            + sig + "\"): " + e);
737:                }
738:            }
739:
740:            public void deleteObject(OzoneRemote obj) throws RuntimeException,
741:                    ExceptionInOzoneObjectException {
742:                try {
743:                    sendCommand(new DbDeleteObj((OzoneProxy) obj), true);
744:                } catch (ExceptionInOzoneObjectException e) {
745:                    throw e;
746:                } catch (Exception e) {
747:                    // only supported from JDK1.4 on
748:                    //          throw new RuntimeException("Caught during deleteObject()",e);
749:                    throw new RuntimeException("Caught during deleteObject(): "
750:                            + e);
751:                }
752:            }
753:
754:            public OzoneProxy copyObject(OzoneRemote obj) throws Exception {
755:                return (OzoneProxy) sendCommand(
756:                        new DbCopyObj((OzoneProxy) obj), true);
757:            }
758:
759:            public void nameObject(OzoneRemote obj, String name)
760:                    throws Exception {
761:                sendCommand(new DbNameObj((OzoneProxy) obj, name), true);
762:            }
763:
764:            public OzoneProxy objectForName(String name) throws Exception {
765:                return (OzoneProxy) sendCommand(new DbObjForName(name), true);
766:            }
767:
768:            public OzoneProxy objectForHandle(String handle) throws Exception {
769:                return (OzoneProxy) sendCommand(new DbObjForHandle(handle),
770:                        true);
771:            }
772:
773:            public OzoneProxy[] objectsOfClass(String name) throws Exception {
774:                throw new RuntimeException("Method not implemented.");
775:            }
776:
777:            public Object invoke(OzoneProxy rObj, String methodName,
778:                    String sig, Object[] args, int lockLevel) throws Exception {
779:                // Kommando verschicken
780:                Object result = sendCommand(new DbInvoke(rObj, methodName, sig,
781:                        args, lockLevel), true);
782:                return result;
783:            }
784:
785:            public Object invoke(OzoneProxy rObj, int methodIndex,
786:                    Object[] args, int lockLevel) throws Exception {
787:                // Kommando verschicken
788:                Object result = sendCommand(new DbInvoke(rObj, methodIndex,
789:                        args, lockLevel), true);
790:                return result;
791:            }
792:
793:            public OzoneCompatible fetch(OzoneProxy rObj, int lockLevel)
794:                    throws Exception {
795:                return null;
796:            }
797:
798:            public Node xmlForObject(OzoneRemote rObj, Document domFactory)
799:                    throws Exception {
800:                byte[] bytes = (byte[]) sendCommand(new DbXMLForObj(
801:                        (OzoneProxy) rObj), true);
802:
803:                SAXChunkConsumer consumer = new SAXChunkConsumer(domFactory,
804:                        null);
805:                consumer.processChunk(bytes);
806:
807:                return consumer.getResultNode();
808:            }
809:
810:            public void xmlForObject(OzoneRemote rObj, ContentHandler ch)
811:                    throws Exception {
812:                byte[] bytes = (byte[]) sendCommand(new DbXMLForObj(
813:                        (OzoneProxy) rObj), true);
814:
815:                SAXChunkConsumer consumer = new SAXChunkConsumer(ch);
816:                consumer.processChunk(bytes);
817:            }
818:
819:            /**
820:             * Return the administration object for this database.
821:             *
822:             * @return The admin object for this database;
823:             */
824:            public Admin admin() throws Exception {
825:                Admin admin = (Admin) objectForName(AdminImpl.OBJECT_NAME);
826:                return admin;
827:            }
828:
829:            /**
830:            	Internal method. This method is called by {@link OzoneProxy}s when they are dying (during finalize()). This
831:            	is required, as the database may track the references the database client has to objects within the database
832:            	in order to properly support garbage collection. If this method is called from anyone else than from the
833:            	{@link OzoneProxy}.finalize()-Method, data loss may occur!
834:
835:            	@param proxy the OzoneProxy object which is dying. It may call this method exaclty once.
836:             */
837:            public void notifyProxyDeath(OzoneProxy proxy) {
838:                try {
839:                    sendCommand(new DbProxyDeath(proxy), false);
840:                } catch (Exception e) {
841:                    // only supported from JDK1.4 on
842:                    //          throw new RuntimeException("Caught during notifyProxyDeath()",e);
843:                    throw new RuntimeException(
844:                            "Caught during notifyProxyDeath(): " + e);
845:                }
846:            }
847:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.