Source Code Cross Referenced for DatabaseManager.java in  » Database-DBMS » hsql » org » hsqldb » 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 » hsql » org.hsqldb 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright (c) 2001-2005, The HSQL Development Group
002:         * All rights reserved.
003:         *
004:         * Redistribution and use in source and binary forms, with or without
005:         * modification, are permitted provided that the following conditions are met:
006:         *
007:         * Redistributions of source code must retain the above copyright notice, this
008:         * list of conditions and the following disclaimer.
009:         *
010:         * Redistributions in binary form must reproduce the above copyright notice,
011:         * this list of conditions and the following disclaimer in the documentation
012:         * and/or other materials provided with the distribution.
013:         *
014:         * Neither the name of the HSQL Development Group nor the names of its
015:         * contributors may be used to endorse or promote products derived from this
016:         * software without specific prior written permission.
017:         *
018:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021:         * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
022:         * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025:         * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
026:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027:         * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029:         */
030:
031:        package org.hsqldb;
032:
033:        import java.util.Vector;
034:
035:        import org.hsqldb.lib.FileUtil;
036:        import org.hsqldb.lib.HashMap;
037:        import org.hsqldb.lib.HashSet;
038:        import org.hsqldb.lib.HsqlTimer;
039:        import org.hsqldb.lib.IntKeyHashMap;
040:        import org.hsqldb.lib.Iterator;
041:        import org.hsqldb.persist.HsqlProperties;
042:        import org.hsqldb.store.ValuePool;
043:
044:        /**
045:         * Handles initial attempts to connect to HSQLDB databases within the JVM
046:         * (or a classloader within the JVM). Opens the database if it is not open
047:         * or connects to it if it is already open. This allows the same database to
048:         * be used by different instances of Server and by direct connections.<p>
049:         *
050:         * Maintains a map of Server instances and notifies each server when its
051:         * database has shut down.<p>
052:         *
053:         * Maintains a reference to the timer used for file locks and logging.<p>
054:         *
055:         * @author fredt@users
056:         * @version 1.8.0
057:         * @since 1.7.2
058:         */
059:        public class DatabaseManager {
060:
061:            // Database and Server registry
062:
063:            /** provides unique ID's for the Databases currently in registry */
064:            private static int dbIDCounter;
065:
066:            /** name to Database mapping for mem: databases */
067:            static final HashMap memDatabaseMap = new HashMap();
068:
069:            /** File to Database mapping for file: databases */
070:            static final HashMap fileDatabaseMap = new HashMap();
071:
072:            /** File to Database mapping for res: databases */
073:            static final HashMap resDatabaseMap = new HashMap();
074:
075:            /** id number to Database for Databases currently in registry */
076:            static final IntKeyHashMap databaseIDMap = new IntKeyHashMap();
077:
078:            /**
079:             * Returns a vector containing the URI (type + path) for all the databases.
080:             */
081:            public static Vector getDatabaseURIs() {
082:
083:                Vector v = new Vector();
084:                Iterator it = databaseIDMap.values().iterator();
085:
086:                while (it.hasNext()) {
087:                    Database db = (Database) it.next();
088:
089:                    v.addElement(db.getURI());
090:                }
091:
092:                return v;
093:            }
094:
095:            /**
096:             * Closes all the databases using the given mode.<p>
097:             *
098:             * CLOSEMODE_IMMEDIATELY = -1;
099:             * CLOSEMODE_NORMAL      = 0;
100:             * CLOSEMODE_COMPACT     = 1;
101:             * CLOSEMODE_SCRIPT      = 2;
102:             */
103:            public static void closeDatabases(int mode) {
104:
105:                Iterator it = databaseIDMap.values().iterator();
106:
107:                while (it.hasNext()) {
108:                    Database db = (Database) it.next();
109:
110:                    try {
111:                        db.close(mode);
112:                    } catch (HsqlException e) {
113:                    }
114:                }
115:            }
116:
117:            /**
118:             * Used by server to open a new session
119:             */
120:            static Session newSession(int dbID, String user, String password)
121:                    throws HsqlException {
122:
123:                Database db = (Database) databaseIDMap.get(dbID);
124:
125:                return db == null ? null : db.connect(user, password);
126:            }
127:
128:            /**
129:             * Used by in-process connections and by Servlet
130:             */
131:
132:            // loosecannon1@users 1.7.2 patch properties on the JDBC URL
133:            public static Session newSession(String type, String path,
134:                    String user, String password, HsqlProperties props)
135:                    throws HsqlException {
136:
137:                Database db = getDatabase(type, path, props);
138:
139:                return db == null ? null : db.connect(user, password);
140:            }
141:
142:            /**
143:             * Returns an existing session. Used with repeat HTTP connections
144:             * belonging to the same JDBC Conenction / HSQL Session pair.
145:             */
146:            static Session getSession(int dbId, int sessionId) {
147:
148:                Database db = (Database) databaseIDMap.get(dbId);
149:
150:                return db == null ? null : db.sessionManager
151:                        .getSession(sessionId);
152:            }
153:
154:            /**
155:             * Used by server to open or create a database
156:             */
157:
158:            // loosecannon1@users 1.7.2 patch properties on the JDBC URL
159:            static int getDatabase(String type, String path, Server server,
160:                    HsqlProperties props) throws HsqlException {
161:
162:                Database db = getDatabase(type, path, props);
163:
164:                registerServer(server, db);
165:
166:                return db.databaseID;
167:            }
168:
169:            /**
170:             * This has to be improved once a threading model is in place.
171:             * Current behaviour:
172:             *
173:             * Attempts to connect to different databases do not block. Two db's can
174:             * open simultaneously.
175:             *
176:             * Attempts to connect to a db while it is opening or closing will block
177:             * until the db is open or closed. At this point the db state is either
178:             * DATABASE_ONLINE (after db.open() has returned) which allows a new
179:             * connection to be made, or the state is DATABASE_SHUTDOWN which means
180:             * the db can be reopened for the new connection).
181:             *
182:             */
183:
184:            // loosecannon1@users 1.7.2 patch properties on the JDBC URL
185:            static Database getDatabase(String type, String path,
186:                    HsqlProperties props) throws HsqlException {
187:
188:                // If the (type, path) pair does not correspond to a registered
189:                // instance, then getDatabaseObject() returns a newly constructed
190:                // and registered Database instance.
191:                // The database state will be DATABASE_SHUTDOWN,
192:                // which means that the switch below will attempt to
193:                // open the database instance.
194:                Database db = getDatabaseObject(type, path, props);
195:
196:                synchronized (db) {
197:                    switch (db.getState()) {
198:
199:                    case Database.DATABASE_ONLINE:
200:                        break;
201:
202:                    case Database.DATABASE_SHUTDOWN:
203:
204:                        // if the database was shutdown while this attempt
205:                        // was waiting, add the database back to the registry
206:                        if (lookupDatabaseObject(type, path) == null) {
207:                            addDatabaseObject(type, path, db);
208:                        }
209:
210:                        db.open();
211:                        break;
212:
213:                    // This state will currently not be reached as Database.Close() is
214:                    // called while a lock is held on the database.
215:                    // If we remove the lock from this method and a database is
216:                    // being shutdown by a thread and in the meantime another thread
217:                    // attempts to connect to the db. The threads could belong to
218:                    // different server instances or be in-process.
219:                    case Database.DATABASE_CLOSING:
220:
221:                        // this case will not be reached as the state is set and
222:                        // cleared within the db.open() call above, which is called
223:                        // from this synchronized block
224:                        // it is here simply as a placeholder for future development
225:                    case Database.DATABASE_OPENING:
226:                        throw Trace.error(Trace.DATABASE_ALREADY_IN_USE,
227:                                Trace.DatabaseManager_getDatabase);
228:                    }
229:                }
230:
231:                return db;
232:            }
233:
234:            // loosecannon1@users 1.7.2 patch properties on the JDBC URL
235:            private static synchronized Database getDatabaseObject(String type,
236:                    String path, HsqlProperties props) throws HsqlException {
237:
238:                Database db;
239:                String key = path;
240:                HashMap databaseMap;
241:
242:                if (type == DatabaseURL.S_FILE) {
243:                    databaseMap = fileDatabaseMap;
244:                    key = filePathToKey(path);
245:                } else if (type == DatabaseURL.S_RES) {
246:                    databaseMap = resDatabaseMap;
247:                } else if (type == DatabaseURL.S_MEM) {
248:                    databaseMap = memDatabaseMap;
249:                } else {
250:                    throw Trace.runtimeError(
251:                            Trace.UNSUPPORTED_INTERNAL_OPERATION,
252:                            "DatabaseManager.getDatabaseObject");
253:                }
254:
255:                db = (Database) databaseMap.get(key);
256:
257:                if (db == null) {
258:                    db = new Database(type, path, type + key, props);
259:                    db.databaseID = dbIDCounter;
260:
261:                    databaseIDMap.put(dbIDCounter, db);
262:
263:                    dbIDCounter++;
264:
265:                    databaseMap.put(key, db);
266:                }
267:
268:                return db;
269:            }
270:
271:            /**
272:             * Looks up database of a given type and path in the registry. Returns
273:             * null if there is none.
274:             */
275:            private static synchronized Database lookupDatabaseObject(
276:                    String type, String path) throws HsqlException {
277:
278:                Object key = path;
279:                HashMap databaseMap;
280:
281:                if (type == DatabaseURL.S_FILE) {
282:                    databaseMap = fileDatabaseMap;
283:                    key = filePathToKey(path);
284:                } else if (type == DatabaseURL.S_RES) {
285:                    databaseMap = resDatabaseMap;
286:                } else if (type == DatabaseURL.S_MEM) {
287:                    databaseMap = memDatabaseMap;
288:                } else {
289:                    throw (Trace.runtimeError(
290:                            Trace.UNSUPPORTED_INTERNAL_OPERATION,
291:                            "DatabaseManager.lookupDatabaseObject()"));
292:                }
293:
294:                return (Database) databaseMap.get(key);
295:            }
296:
297:            /**
298:             * Adds a database to the registry. Returns
299:             * null if there is none.
300:             */
301:            private static synchronized void addDatabaseObject(String type,
302:                    String path, Database db) throws HsqlException {
303:
304:                Object key = path;
305:                HashMap databaseMap;
306:
307:                if (type == DatabaseURL.S_FILE) {
308:                    databaseMap = fileDatabaseMap;
309:                    key = filePathToKey(path);
310:                } else if (type == DatabaseURL.S_RES) {
311:                    databaseMap = resDatabaseMap;
312:                } else if (type == DatabaseURL.S_MEM) {
313:                    databaseMap = memDatabaseMap;
314:                } else {
315:                    throw Trace.runtimeError(
316:                            Trace.UNSUPPORTED_INTERNAL_OPERATION,
317:                            "DatabaseManager.addDatabaseObject()");
318:                }
319:
320:                databaseIDMap.put(db.databaseID, db);
321:                databaseMap.put(key, db);
322:            }
323:
324:            /**
325:             * Removes the database from registry.
326:             */
327:            static void removeDatabase(Database database) {
328:
329:                int dbID = database.databaseID;
330:                String type = database.getType();
331:                String path = database.getPath();
332:                Object key = path;
333:                HashMap databaseMap;
334:
335:                notifyServers(database);
336:
337:                if (type == DatabaseURL.S_FILE) {
338:                    databaseMap = fileDatabaseMap;
339:
340:                    // boucherb@users 20040124 - patch 1.7.2
341:                    // Under the current contract, it's essentially impossible for an
342:                    // exception to get thrown here, because the database could not
343:                    // have been registered successfully before hand using the same
344:                    // path
345:                    //
346:                    // Eventually, we might think about storing the key with the
347:                    // database instance so as to avoid this unnecessary additional
348:                    // conversion and highly unlikely corner case handling.
349:                    try {
350:                        key = filePathToKey(path);
351:                    } catch (HsqlException e) {
352:                        Iterator it = databaseMap.keySet().iterator();
353:                        Object foundKey = null;
354:
355:                        while (it.hasNext()) {
356:                            Object currentKey = it.next();
357:
358:                            if (databaseMap.get(currentKey) == database) {
359:                                foundKey = currentKey;
360:
361:                                break;
362:                            }
363:                        }
364:
365:                        if (foundKey == null) {
366:
367:                            // ??? return;
368:                        } else {
369:                            key = foundKey;
370:                        }
371:                    }
372:                } else if (type == DatabaseURL.S_RES) {
373:                    databaseMap = resDatabaseMap;
374:                } else if (type == DatabaseURL.S_MEM) {
375:                    databaseMap = memDatabaseMap;
376:                } else {
377:                    throw (Trace.runtimeError(
378:                            Trace.UNSUPPORTED_INTERNAL_OPERATION,
379:                            "DatabaseManager.lookupDatabaseObject()"));
380:                }
381:
382:                databaseIDMap.remove(dbID);
383:                databaseMap.remove(key);
384:
385:                if (databaseIDMap.isEmpty()) {
386:                    ValuePool.resetPool();
387:                }
388:            }
389:
390:            /**
391:             * Maintains a map of servers to sets of databases.
392:             * Servers register each of their databases.
393:             * When a database is shutdown, all the servers accessing it are notified.
394:             * The database is then removed form the sets for all servers and the
395:             * servers that have no other database are removed from the map.
396:             */
397:            static HashMap serverMap = new HashMap();
398:
399:            /**
400:             * Deregisters a server completely.
401:             */
402:            static void deRegisterServer(Server server) {
403:                serverMap.remove(server);
404:            }
405:
406:            /**
407:             * Deregisters a server as serving a given database. Not yet used.
408:             */
409:            private static void deRegisterServer(Server server, Database db) {
410:
411:                Iterator it = serverMap.values().iterator();
412:
413:                for (; it.hasNext();) {
414:                    HashSet databases = (HashSet) it.next();
415:
416:                    databases.remove(db);
417:
418:                    if (databases.isEmpty()) {
419:                        it.remove();
420:                    }
421:                }
422:            }
423:
424:            /**
425:             * Registers a server as serving a given database.
426:             */
427:            private static void registerServer(Server server, Database db) {
428:
429:                if (!serverMap.containsKey(server)) {
430:                    serverMap.put(server, new HashSet());
431:                }
432:
433:                HashSet databases = (HashSet) serverMap.get(server);
434:
435:                databases.add(db);
436:            }
437:
438:            /**
439:             * Notifies all servers that serve the database that the database has been
440:             * shutdown.
441:             */
442:            private static void notifyServers(Database db) {
443:
444:                Iterator it = serverMap.keySet().iterator();
445:
446:                for (; it.hasNext();) {
447:                    Server server = (Server) it.next();
448:                    HashSet databases = (HashSet) serverMap.get(server);
449:
450:                    if (databases.contains(db)) {
451:                        server.notify(ServerConstants.SC_DATABASE_SHUTDOWN,
452:                                db.databaseID);
453:                    }
454:                }
455:            }
456:
457:            static boolean isServerDB(Database db) {
458:
459:                Iterator it = serverMap.keySet().iterator();
460:
461:                for (; it.hasNext();) {
462:                    Server server = (Server) it.next();
463:                    HashSet databases = (HashSet) serverMap.get(server);
464:
465:                    if (databases.contains(db)) {
466:                        return true;
467:                    }
468:                }
469:
470:                return false;
471:            }
472:
473:            // Timer
474:            private static final HsqlTimer timer = new HsqlTimer();
475:
476:            public static HsqlTimer getTimer() {
477:                return timer;
478:            }
479:
480:            // converts file path to database lookup key, converting any
481:            // thrown exception to an HsqlException in the process
482:            private static String filePathToKey(String path)
483:                    throws HsqlException {
484:
485:                try {
486:                    return FileUtil.canonicalPath(path);
487:                } catch (Exception e) {
488:                    throw Trace.error(Trace.FILE_IO_ERROR, e.toString());
489:                }
490:            }
491:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.