Source Code Cross Referenced for DBEnvironment.java in  » Net » Terracotta » com » tc » objectserver » persistence » sleepycat » 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 » Net » Terracotta » com.tc.objectserver.persistence.sleepycat 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003:         * notice. All rights reserved.
004:         */
005:        package com.tc.objectserver.persistence.sleepycat;
006:
007:        import org.apache.commons.io.FileUtils;
008:
009:        import com.sleepycat.bind.serial.ClassCatalog;
010:        import com.sleepycat.bind.serial.StoredClassCatalog;
011:        import com.sleepycat.je.Database;
012:        import com.sleepycat.je.DatabaseConfig;
013:        import com.sleepycat.je.DatabaseEntry;
014:        import com.sleepycat.je.DatabaseException;
015:        import com.sleepycat.je.Environment;
016:        import com.sleepycat.je.EnvironmentConfig;
017:        import com.sleepycat.je.LockMode;
018:        import com.sleepycat.je.OperationStatus;
019:        import com.sleepycat.je.Transaction;
020:        import com.tc.logging.CustomerLogging;
021:        import com.tc.logging.TCLogger;
022:        import com.tc.logging.TCLogging;
023:        import com.tc.util.concurrent.ThreadUtil;
024:
025:        import java.io.File;
026:        import java.io.IOException;
027:        import java.util.ArrayList;
028:        import java.util.HashMap;
029:        import java.util.Iterator;
030:        import java.util.LinkedList;
031:        import java.util.List;
032:        import java.util.Map;
033:        import java.util.Properties;
034:
035:        public class DBEnvironment {
036:
037:            private static final TCLogger clogger = CustomerLogging
038:                    .getDSOGenericLogger();
039:            private static final TCLogger logger = TCLogging
040:                    .getLogger(DBEnvironment.class);
041:
042:            private static final String OBJECTID_SEQUENCE_NAME = "objectids";
043:            private static final String ROOT_DB_NAME = "roots";
044:            private static final String OBJECT_DB_NAME = "objects";
045:            private static final String OID_DB_NAME = "oids";
046:
047:            private static final String CLIENTID_SEQUENCE_NAME = "clientids";
048:            private static final String CLIENT_STATE_DB_NAME = "clientstates";
049:            private static final String TRANSACTION_DB_NAME = "transactions";
050:            private static final String TRANSACTION_SEQUENCE_DB_NAME = "transactionsequence";
051:            private static final String STRING_INDEX_DB_NAME = "stringindex";
052:            private static final String CLASS_DB_NAME = "classdefinitions";
053:            private static final String MAP_DB_NAME = "mapsdatabase";
054:            private static final String CLUSTER_STATE_STORE = "clusterstatestore";
055:
056:            private static final Object CONTROL_LOCK = new Object();
057:
058:            private static final DBEnvironmentStatus STATUS_INIT = new DBEnvironmentStatus(
059:                    "INIT");
060:            private static final DBEnvironmentStatus STATUS_ERROR = new DBEnvironmentStatus(
061:                    "ERROR");
062:            private static final DBEnvironmentStatus STATUS_OPENING = new DBEnvironmentStatus(
063:                    "OPENING");
064:            private static final DBEnvironmentStatus STATUS_OPEN = new DBEnvironmentStatus(
065:                    "OPEN");
066:            private static final DBEnvironmentStatus STATUS_CLOSING = new DBEnvironmentStatus(
067:                    "CLOSING");
068:            private static final DBEnvironmentStatus STATUS_CLOSED = new DBEnvironmentStatus(
069:                    "CLOSED");
070:
071:            private static final DatabaseEntry CLEAN_FLAG_KEY = new DatabaseEntry(
072:                    new byte[] { 1 });
073:            private static final byte IS_CLEAN = 1;
074:            private static final byte IS_DIRTY = 2;
075:            private static final long SLEEP_TIME_ON_STARTUP_ERROR = 500;
076:            private static final int STARTUP_RETRY_COUNT = 5;
077:
078:            private final List createdDatabases;
079:            private final Map databasesByName;
080:            private final File envHome;
081:            private EnvironmentConfig ecfg;
082:            private DatabaseConfig dbcfg;
083:            private ClassCatalogWrapper catalog;
084:
085:            private Environment env;
086:            private Database controlDB;
087:            private DBEnvironmentStatus status = STATUS_INIT;
088:            private DatabaseOpenResult openResult = null;
089:
090:            private final boolean paranoid;
091:
092:            public DBEnvironment(boolean paranoid, File envHome)
093:                    throws IOException {
094:                this (paranoid, envHome, new Properties());
095:            }
096:
097:            public DBEnvironment(boolean paranoid, File envHome,
098:                    Properties jeProperties) throws IOException {
099:                this (new HashMap(), new LinkedList(), paranoid, envHome);
100:                this .ecfg = new EnvironmentConfig(jeProperties);
101:                this .ecfg.setTransactional(true);
102:                this .ecfg.setAllowCreate(true);
103:                this .ecfg.setReadOnly(false);
104:                //    this.ecfg.setTxnWriteNoSync(!paranoid);
105:                this .ecfg.setTxnNoSync(!paranoid);
106:                this .dbcfg = new DatabaseConfig();
107:                this .dbcfg.setAllowCreate(true);
108:                this .dbcfg.setTransactional(true);
109:
110:                logger.info("Env config = " + this .ecfg + " DB Config = "
111:                        + this .dbcfg + " JE Properties = " + jeProperties);
112:            }
113:
114:            // For tests
115:            DBEnvironment(boolean paranoid, File envHome,
116:                    EnvironmentConfig ecfg, DatabaseConfig dbcfg)
117:                    throws IOException {
118:                this (new HashMap(), new LinkedList(), paranoid, envHome, ecfg,
119:                        dbcfg);
120:            }
121:
122:            // For tests
123:            DBEnvironment(Map databasesByName, List createdDatabases,
124:                    boolean paranoid, File envHome, EnvironmentConfig ecfg,
125:                    DatabaseConfig dbcfg) throws IOException {
126:                this (databasesByName, createdDatabases, paranoid, envHome);
127:                this .ecfg = ecfg;
128:                this .dbcfg = dbcfg;
129:            }
130:
131:            /**
132:             * Note: it is not currently safe to create more than one of these instances in the same process. Sleepycat is
133:             * supposed to keep more than one process from opening a writable handle to the same database, but it allows you to
134:             * create more than one writable handle within the same process. So, don't do that.
135:             */
136:            private DBEnvironment(Map databasesByName, List createdDatabases,
137:                    boolean paranoid, File envHome) throws IOException {
138:                this .databasesByName = databasesByName;
139:                this .createdDatabases = createdDatabases;
140:                this .paranoid = paranoid;
141:                this .envHome = envHome;
142:                FileUtils.forceMkdir(this .envHome);
143:            }
144:
145:            public boolean isParanoidMode() {
146:                return paranoid;
147:            }
148:
149:            public synchronized DatabaseOpenResult open()
150:                    throws TCDatabaseException {
151:                assertInit();
152:                status = STATUS_OPENING;
153:                try {
154:                    env = openEnvironment();
155:                    synchronized (CONTROL_LOCK) {
156:                        // XXX: Note: this doesn't guard against multiple instances in different
157:                        // classloaders...
158:                        controlDB = env.openDatabase(null, "control",
159:                                this .dbcfg);
160:                        openResult = new DatabaseOpenResult(isClean());
161:                        if (!openResult.isClean()) {
162:                            this .status = STATUS_INIT;
163:                            forceClose();
164:                            return openResult;
165:                        }
166:                    }
167:                    if (!this .paranoid)
168:                        setDirty();
169:                    this .catalog = new ClassCatalogWrapper(env, dbcfg);
170:                    newDatabase(env, OBJECTID_SEQUENCE_NAME);
171:                    newDatabase(env, OBJECT_DB_NAME);
172:                    newDatabase(env, OID_DB_NAME);
173:                    newDatabase(env, ROOT_DB_NAME);
174:
175:                    newDatabase(env, CLIENTID_SEQUENCE_NAME);
176:                    newDatabase(env, CLIENT_STATE_DB_NAME);
177:                    newDatabase(env, TRANSACTION_DB_NAME);
178:                    newDatabase(env, TRANSACTION_SEQUENCE_DB_NAME);
179:                    newDatabase(env, STRING_INDEX_DB_NAME);
180:                    newDatabase(env, CLASS_DB_NAME);
181:                    newDatabase(env, MAP_DB_NAME);
182:                    newDatabase(env, CLUSTER_STATE_STORE);
183:                } catch (DatabaseException e) {
184:                    this .status = STATUS_ERROR;
185:                    forceClose();
186:                    throw new TCDatabaseException(e);
187:                } catch (Error e) {
188:                    this .status = STATUS_ERROR;
189:                    forceClose();
190:                    throw e;
191:                } catch (RuntimeException e) {
192:                    this .status = STATUS_ERROR;
193:                    forceClose();
194:                    throw e;
195:                }
196:
197:                this .status = STATUS_OPEN;
198:                return openResult;
199:            }
200:
201:            private void cinfo(Object message) {
202:                clogger.info("DB Environment: " + message);
203:            }
204:
205:            public synchronized void close() throws TCDatabaseException {
206:                assertOpen();
207:                status = STATUS_CLOSING;
208:                cinfo("Closing...");
209:
210:                try {
211:                    for (Iterator i = createdDatabases.iterator(); i.hasNext();) {
212:                        Database db = (Database) i.next();
213:                        cinfo("Closing database: " + db.getDatabaseName()
214:                                + "...");
215:                        db.close();
216:                    }
217:                    cinfo("Closing class catalog...");
218:                    this .catalog.close();
219:                    setClean();
220:                    if (this .controlDB != null) {
221:                        cinfo("Closing control database...");
222:                        this .controlDB.close();
223:                    }
224:                    if (this .env != null) {
225:                        cinfo("Closing environment...");
226:                        this .env.close();
227:                    }
228:                } catch (DatabaseException de) {
229:                    throw new TCDatabaseException(de);
230:                }
231:                this .controlDB = null;
232:                this .env = null;
233:
234:                status = STATUS_CLOSED;
235:                cinfo("Closed.");
236:            }
237:
238:            public synchronized boolean isOpen() {
239:                return STATUS_OPEN.equals(status);
240:            }
241:
242:            // This is for testing and cleanup on error.
243:            synchronized void forceClose() {
244:                List toClose = new ArrayList(createdDatabases);
245:                toClose.add(controlDB);
246:                for (Iterator i = toClose.iterator(); i.hasNext();) {
247:                    try {
248:                        Database db = (Database) i.next();
249:                        if (db != null)
250:                            db.close();
251:                    } catch (DatabaseException e) {
252:                        e.printStackTrace();
253:                    }
254:                }
255:
256:                try {
257:                    if (this .catalog != null)
258:                        this .catalog.close();
259:                } catch (DatabaseException e) {
260:                    e.printStackTrace();
261:                }
262:
263:                try {
264:                    if (env != null)
265:                        env.close();
266:                } catch (DatabaseException e) {
267:                    e.printStackTrace();
268:                }
269:            }
270:
271:            public File getEnvironmentHome() {
272:                return envHome;
273:            }
274:
275:            public synchronized Environment getEnvironment()
276:                    throws TCDatabaseException {
277:                assertOpen();
278:                return env;
279:            }
280:
281:            public synchronized Database getObjectDatabase()
282:                    throws TCDatabaseException {
283:                assertOpen();
284:                return (Database) databasesByName.get(OBJECT_DB_NAME);
285:            }
286:
287:            public synchronized Database getOidDatabase()
288:                    throws TCDatabaseException {
289:                assertOpen();
290:                return (Database) databasesByName.get(OID_DB_NAME);
291:            }
292:
293:            public synchronized ClassCatalogWrapper getClassCatalogWrapper()
294:                    throws TCDatabaseException {
295:                assertOpen();
296:                return catalog;
297:            }
298:
299:            public synchronized Database getRootDatabase()
300:                    throws TCDatabaseException {
301:                assertOpen();
302:                return (Database) databasesByName.get(ROOT_DB_NAME);
303:            }
304:
305:            public synchronized Database getObjectIDDB()
306:                    throws TCDatabaseException {
307:                assertOpen();
308:                return (Database) databasesByName.get(OBJECTID_SEQUENCE_NAME);
309:            }
310:
311:            public Database getClientStateDatabase() throws TCDatabaseException {
312:                assertOpen();
313:                return (Database) databasesByName.get(CLIENT_STATE_DB_NAME);
314:            }
315:
316:            public Database getClientIDDatabase() throws TCDatabaseException {
317:                assertOpen();
318:                return (Database) databasesByName.get(CLIENTID_SEQUENCE_NAME);
319:            }
320:
321:            public Database getTransactionDatabase() throws TCDatabaseException {
322:                assertOpen();
323:                return (Database) databasesByName.get(TRANSACTION_DB_NAME);
324:            }
325:
326:            public Database getTransactionSequenceDatabase()
327:                    throws TCDatabaseException {
328:                assertOpen();
329:                return (Database) databasesByName
330:                        .get(TRANSACTION_SEQUENCE_DB_NAME);
331:            }
332:
333:            public Database getClassDatabase() throws TCDatabaseException {
334:                assertOpen();
335:                return (Database) databasesByName.get(CLASS_DB_NAME);
336:            }
337:
338:            public Database getMapsDatabase() throws TCDatabaseException {
339:                assertOpen();
340:                return (Database) databasesByName.get(MAP_DB_NAME);
341:            }
342:
343:            public Database getStringIndexDatabase() throws TCDatabaseException {
344:                assertOpen();
345:                return (Database) databasesByName.get(STRING_INDEX_DB_NAME);
346:            }
347:
348:            public Database getClusterStateStoreDatabase()
349:                    throws TCDatabaseException {
350:                assertOpen();
351:                return (Database) databasesByName.get(CLUSTER_STATE_STORE);
352:            }
353:
354:            private void assertNotError() throws TCDatabaseException {
355:                if (STATUS_ERROR == status)
356:                    throw new TCDatabaseException(
357:                            "Attempt to operate on an environment in an error state.");
358:            }
359:
360:            private void assertInit() throws TCDatabaseException {
361:                if (STATUS_INIT != status)
362:                    throw new DatabaseOpenException(
363:                            "Database environment isn't in INIT state.");
364:            }
365:
366:            private void assertOpening() {
367:                if (STATUS_OPENING != status)
368:                    throw new AssertionError(
369:                            "Database environment should be opening but isn't");
370:            }
371:
372:            private void assertOpen() throws TCDatabaseException {
373:                assertNotError();
374:                if (STATUS_OPEN != status)
375:                    throw new DatabaseNotOpenException(
376:                            "Database environment should be open but isn't.");
377:            }
378:
379:            private void assertClosing() {
380:                if (STATUS_CLOSING != status)
381:                    throw new AssertionError(
382:                            "Database environment should be closing but isn't");
383:            }
384:
385:            private boolean isClean() throws TCDatabaseException {
386:                assertOpening();
387:                DatabaseEntry value = new DatabaseEntry(new byte[] { 0 });
388:                Transaction tx = newTransaction();
389:                OperationStatus stat;
390:                try {
391:                    stat = controlDB.get(tx, CLEAN_FLAG_KEY, value,
392:                            LockMode.DEFAULT);
393:                    tx.commit();
394:                } catch (DatabaseException e) {
395:                    throw new TCDatabaseException(e);
396:                }
397:                return OperationStatus.NOTFOUND.equals(stat)
398:                        || (OperationStatus.SUCCESS.equals(stat) && value
399:                                .getData()[0] == IS_CLEAN);
400:            }
401:
402:            private void setDirty() throws TCDatabaseException {
403:                assertOpening();
404:                DatabaseEntry value = new DatabaseEntry(new byte[] { IS_DIRTY });
405:                Transaction tx = newTransaction();
406:                OperationStatus stat;
407:                try {
408:                    stat = controlDB.put(tx, CLEAN_FLAG_KEY, value);
409:                } catch (DatabaseException e) {
410:                    throw new TCDatabaseException(e);
411:                }
412:                if (!OperationStatus.SUCCESS.equals(stat))
413:                    throw new TCDatabaseException(
414:                            "Unexpected operation status "
415:                                    + "trying to unset clean flag: " + stat);
416:                try {
417:                    tx.commitSync();
418:                } catch (DatabaseException e) {
419:                    throw new TCDatabaseException(e);
420:                }
421:            }
422:
423:            private Transaction newTransaction() throws TCDatabaseException {
424:                try {
425:                    Transaction tx = env.beginTransaction(null, null);
426:                    return tx;
427:                } catch (DatabaseException de) {
428:                    throw new TCDatabaseException(de);
429:                }
430:            }
431:
432:            private void setClean() throws TCDatabaseException {
433:                assertClosing();
434:                DatabaseEntry value = new DatabaseEntry(new byte[] { IS_CLEAN });
435:                Transaction tx = newTransaction();
436:                OperationStatus stat;
437:                try {
438:                    stat = controlDB.put(tx, CLEAN_FLAG_KEY, value);
439:                } catch (DatabaseException e) {
440:                    throw new TCDatabaseException(e);
441:                }
442:                if (!OperationStatus.SUCCESS.equals(stat))
443:                    throw new TCDatabaseException(
444:                            "Unexpected operation status "
445:                                    + "trying to set clean flag: " + stat);
446:                try {
447:                    tx.commitSync();
448:                } catch (DatabaseException e) {
449:                    throw new TCDatabaseException(e);
450:                }
451:            }
452:
453:            private void newDatabase(Environment e, String name)
454:                    throws TCDatabaseException {
455:                try {
456:                    Database db = e.openDatabase(null, name, dbcfg);
457:                    createdDatabases.add(db);
458:                    databasesByName.put(name, db);
459:                } catch (DatabaseException de) {
460:                    throw new TCDatabaseException(de);
461:                }
462:            }
463:
464:            private Environment openEnvironment() throws TCDatabaseException {
465:                int count = 0;
466:                while (true) {
467:                    try {
468:                        return new Environment(envHome, ecfg);
469:                    } catch (DatabaseException dbe) {
470:                        if (++count <= STARTUP_RETRY_COUNT) {
471:                            logger.warn("Unable to open DB environment. "
472:                                    + dbe.getMessage() + " Retrying after "
473:                                    + SLEEP_TIME_ON_STARTUP_ERROR + " ms");
474:                            ThreadUtil.reallySleep(SLEEP_TIME_ON_STARTUP_ERROR);
475:                        } else {
476:                            throw new TCDatabaseException(dbe);
477:                        }
478:                    }
479:                }
480:            }
481:
482:            private static final class DBEnvironmentStatus {
483:                private final String description;
484:
485:                DBEnvironmentStatus(String desc) {
486:                    this .description = desc;
487:                }
488:
489:                public String toString() {
490:                    return this .description;
491:                }
492:            }
493:
494:            public static final class ClassCatalogWrapper {
495:
496:                private final StoredClassCatalog catalog;
497:                private boolean closed = false;
498:
499:                private ClassCatalogWrapper(Environment env, DatabaseConfig cfg)
500:                        throws DatabaseException {
501:                    catalog = new StoredClassCatalog(env.openDatabase(null,
502:                            "java_class_catalog", cfg));
503:                }
504:
505:                public final ClassCatalog getClassCatalog() {
506:                    return this .catalog;
507:                }
508:
509:                synchronized void close() throws DatabaseException {
510:                    if (closed)
511:                        throw new IllegalStateException("Already closed.");
512:                    this .catalog.close();
513:                    closed = true;
514:                }
515:            }
516:
517:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.