Source Code Cross Referenced for RecordStoreImpl.java in  » 6.0-JDK-Modules » j2me » com » sun » midp » rms » 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 » 6.0 JDK Modules » j2me » com.sun.midp.rms 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *
0003:         *
0004:         * Portions Copyright  2000-2007 Sun Microsystems, Inc. All Rights
0005:         * Reserved.  Use is subject to license terms.
0006:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0007:         * 
0008:         * This program is free software; you can redistribute it and/or
0009:         * modify it under the terms of the GNU General Public License version
0010:         * 2 only, as published by the Free Software Foundation.
0011:         * 
0012:         * This program is distributed in the hope that it will be useful, but
0013:         * WITHOUT ANY WARRANTY; without even the implied warranty of
0014:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0015:         * General Public License version 2 for more details (a copy is
0016:         * included at /legal/license.txt).
0017:         * 
0018:         * You should have received a copy of the GNU General Public License
0019:         * version 2 along with this work; if not, write to the Free Software
0020:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0021:         * 02110-1301 USA
0022:         * 
0023:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0024:         * Clara, CA 95054 or visit www.sun.com if you need additional
0025:         * information or have any questions.
0026:         *
0027:         * Copyright 2000 Motorola, Inc. All Rights Reserved.
0028:         * This notice does not imply publication.
0029:         */
0030:
0031:        package com.sun.midp.rms;
0032:
0033:        import java.io.IOException;
0034:        import javax.microedition.rms.*;
0035:
0036:        import com.sun.midp.security.Permissions;
0037:        import com.sun.midp.security.SecurityToken;
0038:        import com.sun.midp.log.Logging;
0039:        import com.sun.midp.log.LogChannels;
0040:
0041:        /**
0042:         * A class implementing a MIDP a record store.
0043:         */
0044:
0045:        public class RecordStoreImpl implements  AbstractRecordStoreImpl {
0046:            /** used to compact the records of the record store */
0047:            private byte[] compactBuffer = new byte[COMPACT_BUFFER_SIZE];
0048:
0049:            /**
0050:             * Internal indicator for AUTHMODE_ANY with read only access
0051:             * AUTHMODE_ANY_RO has a value of 2.
0052:             */
0053:            final static int AUTHMODE_ANY_RO = 2;
0054:
0055:            /** unique id for suite that owns this record store */
0056:            int suiteId;
0057:
0058:            /** lock used to synchronize this record store */
0059:            Object rsLock;
0060:
0061:            /** data block header stored here */
0062:            byte[] dbHeader;
0063:
0064:            /** record store index */
0065:            private RecordStoreIndex dbIndex;
0066:
0067:            /** record store data */
0068:            private RecordStoreFile dbFile;
0069:
0070:            /**
0071:             * Deletes the named record store. MIDlet suites are only allowed
0072:             * to delete their own record stores. If the named record store is
0073:             * open (by a MIDlet in this suite or a MIDlet in a different
0074:             * MIDlet suite) when this method is called, a
0075:             * RecordStoreException will be thrown.  If the named record store
0076:             * does not exist a RecordStoreNotFoundException will be
0077:             * thrown. Calling this method does NOT result in recordDeleted
0078:             * calls to any registered listeners of this RecordStore.
0079:             *
0080:             * @param token security token for authorization
0081:             * @param suiteId ID of the MIDlet suite that owns the record store
0082:             * @param recordStoreName the MIDlet suite unique record store to
0083:             *          delete
0084:             *
0085:             * @exception RecordStoreException if a record store-related
0086:             *          exception occurred
0087:             * @exception RecordStoreNotFoundException if the record store
0088:             *          could not be found
0089:             */
0090:            public static void deleteRecordStore(SecurityToken token,
0091:                    int suiteId, String recordStoreName)
0092:                    throws RecordStoreException, RecordStoreNotFoundException {
0093:
0094:                token.checkIfPermissionAllowed(Permissions.MIDP);
0095:
0096:                // check if file exists and delete it
0097:                if (RecordStoreUtil.exists(suiteId, recordStoreName,
0098:                        RecordStoreFile.DB_EXTENSION)) {
0099:                    boolean success = RecordStoreIndex.deleteIndex(suiteId,
0100:                            recordStoreName);
0101:                    RecordStoreUtil.deleteFile(suiteId, recordStoreName,
0102:                            RecordStoreFile.DB_EXTENSION);
0103:
0104:                    if (!success) {
0105:                        throw new RecordStoreException("deleteRecordStore "
0106:                                + "failed");
0107:                    }
0108:                } else {
0109:                    throw new RecordStoreNotFoundException("deleteRecordStore "
0110:                            + "error: file " + "not found");
0111:                }
0112:            }
0113:
0114:            /**
0115:             * Open (and possibly create) a record store associated with the
0116:             * given MIDlet suite. If this method is called by a MIDlet when
0117:             * the record store is already open by a MIDlet in the MIDlet suite,
0118:             * this method returns a reference to the same RecordStoreImpl object.
0119:             *
0120:             * @param token security token for authorization
0121:             * @param suiteId ID of the MIDlet suite that owns the record store
0122:             * @param recordStoreName the MIDlet suite unique name for the
0123:             *          record store, consisting of between one and 32 Unicode
0124:             *          characters inclusive.
0125:             * @param createIfNecessary if true, the record store will be
0126:             *          created if necessary
0127:             *
0128:             * @return <code>RecordStore</code> object for the record store
0129:             *
0130:             * @exception RecordStoreException if a record store-related
0131:             *          exception occurred
0132:             * @exception RecordStoreNotFoundException if the record store
0133:             *          could not be found
0134:             * @exception RecordStoreFullException if the operation cannot be
0135:             *          completed because the record store is full
0136:             * @exception IllegalArgumentException if
0137:             *          recordStoreName is invalid
0138:             */
0139:            public static RecordStoreImpl openRecordStore(SecurityToken token,
0140:                    int suiteId, String recordStoreName,
0141:                    boolean createIfNecessary) throws RecordStoreException,
0142:                    RecordStoreFullException, RecordStoreNotFoundException {
0143:
0144:                token.checkIfPermissionAllowed(Permissions.MIDP);
0145:
0146:                return new RecordStoreImpl(suiteId, recordStoreName,
0147:                        createIfNecessary);
0148:            }
0149:
0150:            /**
0151:             * Changes the access mode for this RecordStore. The authorization
0152:             * mode choices are:
0153:             *
0154:             * <ul>
0155:             * <li><code>AUTHMODE_PRIVATE</code> - Only allows the MIDlet
0156:             *          suite that created the RecordStore to access it. This
0157:             *          case behaves identically to
0158:             *          <code>openRecordStore(recordStoreName,
0159:             *          createIfNecessary)</code>.</li>
0160:             * <li><code>AUTHMODE_ANY</code> - Allows any MIDlet to access the
0161:             *          RecordStore. Note that this makes your recordStore
0162:             *          accessible by any other MIDlet on the device. This
0163:             *          could have privacy and security issues depending on
0164:             *          the data being shared. Please use carefully.</li>
0165:             * </ul>
0166:             *
0167:             * <p>The owning MIDlet suite may always access the RecordStore and
0168:             * always has access to write and update the store. Only the
0169:             * owning MIDlet suite can change the mode of a RecordStore.</p>
0170:             *
0171:             * @param authmode the mode under which to check or create access.
0172:             *          Must be one of AUTHMODE_PRIVATE or AUTHMODE_ANY.
0173:             * @param writable true if the RecordStore is to be writable by
0174:             *          other MIDlet suites that are granted access
0175:             *
0176:             * @exception RecordStoreException if a record store-related
0177:             *          exception occurred
0178:             * @exception SecurityException if this MIDlet Suite is not
0179:             *          allowed to change the mode of the RecordStore
0180:             * @exception IllegalArgumentException if authmode is invalid
0181:             */
0182:            public void setMode(int authmode, boolean writable)
0183:                    throws RecordStoreException {
0184:
0185:                synchronized (rsLock) {
0186:                    int newAuthMode = authmode;
0187:                    if ((authmode == RecordStore.AUTHMODE_ANY)
0188:                            && (writable == false)) {
0189:                        newAuthMode = AUTHMODE_ANY_RO;
0190:                    }
0191:
0192:                    RecordStoreUtil.putInt(newAuthMode, dbHeader, RS1_AUTHMODE);
0193:
0194:                    try {
0195:                        // write out the changes to the db header
0196:                        dbFile.seek(RS1_AUTHMODE);
0197:                        dbFile.write(dbHeader, RS1_AUTHMODE, 4);
0198:                        // dbFile.commitWrite();
0199:                    } catch (java.io.IOException ioe) {
0200:                        throw new RecordStoreException("error writing record "
0201:                                + "store attributes");
0202:                    }
0203:                }
0204:            }
0205:
0206:            /**
0207:             * This method is called when the MIDlet requests to have the
0208:             * record store closed. Note that the record store will not
0209:             * actually be closed until closeRecordStore() is called as many
0210:             * times as openRecordStore() was called. In other words, the
0211:             * MIDlet needs to make a balanced number of close calls as open
0212:             * calls before the record store is closed.
0213:             *
0214:             * <p>When the record store is closed, all listeners are removed
0215:             * and all RecordEnumerations associated with it become invalid.
0216:             * If the MIDlet attempts to perform
0217:             * operations on the RecordStore object after it has been closed,
0218:             * the methods will throw a RecordStoreNotOpenException.
0219:             *
0220:             * @exception RecordStoreNotOpenException if the record store is
0221:             *          not open
0222:             * @exception RecordStoreException if a different record
0223:             *          store-related exception occurred
0224:             */
0225:            public void closeRecordStore() throws RecordStoreNotOpenException,
0226:                    RecordStoreException {
0227:
0228:                synchronized (rsLock) {
0229:                    try {
0230:                        // close native fd
0231:                        compactRecords(); // compact before close
0232:
0233:                        dbFile.close();
0234:
0235:                        dbIndex.close();
0236:                    } catch (java.io.IOException ioe) {
0237:                        throw new RecordStoreException(
0238:                                "error closing .db file. " + ioe);
0239:                    } finally {
0240:                        dbFile = null;
0241:                    }
0242:                }
0243:            }
0244:
0245:            /**
0246:             * Returns an array of the names of record stores owned by the
0247:             * MIDlet suite. Note that if the MIDlet suite does not
0248:             * have any record stores, this function will return null.
0249:             *
0250:             * The order of RecordStore names returned is implementation
0251:             * dependent.
0252:             *
0253:             * @param token security token for authorization
0254:             * @param suiteId ID of the MIDlet suite that owns the record store
0255:             *
0256:             * @return array of the names of record stores owned by the
0257:             * MIDlet suite. Note that if the MIDlet suite does not
0258:             * have any record stores, this function will return null.
0259:             */
0260:            public static String[] listRecordStores(SecurityToken token,
0261:                    int suiteId) {
0262:                token.checkIfPermissionAllowed(Permissions.MIDP);
0263:
0264:                return RecordStoreFile.listRecordStores(suiteId);
0265:            }
0266:
0267:            /**
0268:             * Get the authorization mode for this record store.
0269:             *
0270:             * @return authorization mode
0271:             */
0272:            public int getAuthMode() {
0273:                return RecordStoreUtil.getInt(dbHeader, RS1_AUTHMODE);
0274:            }
0275:
0276:            /**
0277:             * Each time a record store is modified (by
0278:             * <code>addRecord</code>, <code>setRecord</code>, or
0279:             * <code>deleteRecord</code> methods) its <em>version</em> is
0280:             * incremented. This can be used by MIDlets to quickly tell if
0281:             * anything has been modified.
0282:             *
0283:             * The initial version number is implementation dependent.
0284:             * The increment is a positive integer greater than 0.
0285:             * The version number increases only when the RecordStore is updated.
0286:             *
0287:             * The increment value need not be constant and may vary with each
0288:             * update.
0289:             *
0290:             * @return the current record store version
0291:             */
0292:            public int getVersion() throws RecordStoreNotOpenException {
0293:                return RecordStoreUtil.getInt(dbHeader, RS4_VERSION);
0294:            }
0295:
0296:            /**
0297:             * Returns the number of records currently in the record store.
0298:             *
0299:             * @return the number of records currently in the record store
0300:             */
0301:            public int getNumRecords() {
0302:                return RecordStoreUtil.getInt(dbHeader, RS3_NUM_LIVE);
0303:            }
0304:
0305:            /**
0306:             * Returns the amount of space, in bytes, that the record store
0307:             * occupies. The size returned includes any overhead associated
0308:             * with the implementation, such as the data structures
0309:             * used to hold the state of the record store, etc.
0310:             *
0311:             * @return the size of the record store in bytes
0312:             */
0313:            public int getSize() {
0314:                return DB_HEADER_SIZE
0315:                        + RecordStoreUtil.getInt(dbHeader, RS6_DATA_SIZE);
0316:            }
0317:
0318:            /**
0319:             * Returns the amount of additional room (in bytes) available for
0320:             * this record store to grow. Note that this is not necessarily
0321:             * the amount of extra MIDlet-level data which can be stored,
0322:             * as implementations may store additional data structures with
0323:             * each record to support integration with native applications,
0324:             * synchronization, etc.
0325:             *
0326:             * @return the amount of additional room (in bytes) available for
0327:             *          this record store to grow
0328:             */
0329:            public int getSizeAvailable() {
0330:                int fileSpace = dbFile.spaceAvailable(suiteId)
0331:                        - BLOCK_HEADER_SIZE - DB_HEADER_SIZE;
0332:                int limitSpace = RMSConfig.STORAGE_SUITE_LIMIT
0333:                        - RecordStoreUtil.getInt(dbHeader, RS6_DATA_SIZE)
0334:                        - BLOCK_HEADER_SIZE - DB_HEADER_SIZE;
0335:
0336:                int rv = (fileSpace < limitSpace) ? fileSpace : limitSpace;
0337:                return (rv < 0) ? 0 : rv;
0338:            }
0339:
0340:            /**
0341:             * Returns the last time the record store was modified, in the
0342:             * format used by System.currentTimeMillis().
0343:             *
0344:             * @return the last time the record store was modified, in the
0345:             *          format used by System.currentTimeMillis()
0346:             */
0347:            public long getLastModified() {
0348:                return RecordStoreUtil.getLong(dbHeader, RS5_LAST_MODIFIED);
0349:            }
0350:
0351:            /**
0352:             * Returns the recordId of the next record to be added to the
0353:             * record store. This can be useful for setting up pseudo-relational
0354:             * relationships. That is, if you have two or more
0355:             * record stores whose records need to refer to one another, you can
0356:             * predetermine the recordIds of the records that will be created
0357:             * in one record store, before populating the fields and allocating
0358:             * the record in another record store. Note that the recordId returned
0359:             * is only valid while the record store remains open and until a call
0360:             * to <code>addRecord()</code>.
0361:             *
0362:             * @return the recordId of the next record to be added to the
0363:             *          record store
0364:             */
0365:            public int getNextRecordID() {
0366:                return RecordStoreUtil.getInt(dbHeader, RS2_NEXT_ID);
0367:            }
0368:
0369:            /**
0370:             * Adds a new record to the record store. The recordId for this
0371:             * new record is returned. This is a blocking atomic operation.
0372:             * The record is written to persistent storage before the
0373:             * method returns.
0374:             *
0375:             * @param data the data to be stored in this record. If the record
0376:             *          is to have zero-length data (no data), this parameter may be
0377:             *          null.
0378:             * @param offset the index into the data buffer of the first
0379:             *          relevant byte for this record
0380:             * @param numBytes the number of bytes of the data buffer to use
0381:             *          for this record (may be zero)
0382:             *
0383:             * @return the recordId for the new record
0384:             *
0385:             * @exception RecordStoreNotOpenException if the record store is
0386:             *          not open
0387:             * @exception RecordStoreException if a different record
0388:             *          store-related exception occurred
0389:             * @exception RecordStoreFullException if the operation cannot be
0390:             *          completed because the record store has no more room
0391:             * @exception SecurityException if the MIDlet has read-only access
0392:             *          to the RecordStore
0393:             */
0394:            public int addRecord(byte[] data, int offset, int numBytes)
0395:                    throws RecordStoreNotOpenException, RecordStoreException,
0396:                    RecordStoreFullException {
0397:
0398:                synchronized (rsLock) {
0399:                    int recordId = getNextRecordID();
0400:
0401:                    try {
0402:                        // add a block for this record
0403:                        addBlock(recordId, data, offset, numBytes);
0404:
0405:                        // update the db header
0406:                        RecordStoreUtil.putInt(recordId + 1, dbHeader,
0407:                                RS2_NEXT_ID);
0408:                        RecordStoreUtil.putInt(getNumRecords() + 1, dbHeader,
0409:                                RS3_NUM_LIVE);
0410:                        RecordStoreUtil.putInt(getVersion() + 1, dbHeader,
0411:                                RS4_VERSION);
0412:                        RecordStoreUtil.putLong(System.currentTimeMillis(),
0413:                                dbHeader, RS5_LAST_MODIFIED);
0414:
0415:                        // write out the changes to the db header
0416:                        dbFile.seek(RS2_NEXT_ID);
0417:                        dbFile.write(dbHeader, RS2_NEXT_ID, 3 * 4 + 8);
0418:                        // dbFile.commitWrite();
0419:                    } catch (java.io.IOException ioe) {
0420:                        throw new RecordStoreException(
0421:                                "error writing new record " + "data");
0422:                    }
0423:
0424:                    // Return the new record id
0425:                    return recordId;
0426:                }
0427:            }
0428:
0429:            /**
0430:             * The record is deleted from the record store. The recordId for
0431:             * this record is NOT reused.
0432:             *
0433:             * @param recordId the ID of the record to delete
0434:             *
0435:             * @exception RecordStoreNotOpenException if the record store is
0436:             *          not open
0437:             * @exception InvalidRecordIDException if the recordId is invalid
0438:             * @exception RecordStoreException if a general record store
0439:             *          exception occurs
0440:             * @exception SecurityException if the MIDlet has read-only access
0441:             *          to the RecordStore
0442:             */
0443:            public void deleteRecord(int recordId)
0444:                    throws RecordStoreNotOpenException,
0445:                    InvalidRecordIDException, RecordStoreException {
0446:                synchronized (rsLock) {
0447:                    try {
0448:                        byte[] header = new byte[BLOCK_HEADER_SIZE];
0449:                        int blockOffset = dbIndex.getRecordHeader(recordId,
0450:                                header);
0451:
0452:                        // free the block
0453:                        freeBlock(blockOffset, header);
0454:
0455:                        // update the db index
0456:                        dbIndex.deleteRecordIndex(recordId);
0457:
0458:                        // update the db header
0459:                        RecordStoreUtil.putInt(getNumRecords() - 1, dbHeader,
0460:                                RS3_NUM_LIVE);
0461:                        RecordStoreUtil.putInt(getVersion() + 1, dbHeader,
0462:                                RS4_VERSION);
0463:                        RecordStoreUtil.putLong(System.currentTimeMillis(),
0464:                                dbHeader, RS5_LAST_MODIFIED);
0465:
0466:                        // save the updated db header
0467:                        dbFile.seek(RS3_NUM_LIVE);
0468:                        dbFile.write(dbHeader, RS3_NUM_LIVE, 2 * 4 + 8);
0469:                        // dbFile.commitWrite();
0470:
0471:                    } catch (java.io.IOException ioe) {
0472:                        throw new RecordStoreException(
0473:                                "error updating file after"
0474:                                        + " record deletion");
0475:                    }
0476:                }
0477:            }
0478:
0479:            /**
0480:             * Returns the size (in bytes) of the MIDlet data available
0481:             * in the given record.
0482:             *
0483:             * @param recordId the ID of the record to use in this operation
0484:             *
0485:             * @return the size (in bytes) of the MIDlet data available
0486:             *          in the given record
0487:             *
0488:             * @exception RecordStoreNotOpenException if the record store is
0489:             *          not open
0490:             * @exception InvalidRecordIDException if the recordId is invalid
0491:             * @exception RecordStoreException if a general record store
0492:             *          exception occurs
0493:             */
0494:            public int getRecordSize(int recordId)
0495:                    throws RecordStoreNotOpenException,
0496:                    InvalidRecordIDException, RecordStoreException {
0497:                synchronized (rsLock) {
0498:                    byte[] header = new byte[BLOCK_HEADER_SIZE];
0499:
0500:                    try {
0501:                        dbIndex.getRecordHeader(recordId, header);
0502:                    } catch (java.io.IOException ioe) {
0503:                        throw new RecordStoreException(
0504:                                "error reading record data");
0505:                    }
0506:
0507:                    return RecordStoreUtil.getInt(header, 4);
0508:                }
0509:            }
0510:
0511:            /**
0512:             * Returns the data stored in the given record.
0513:             *
0514:             * @param recordId the ID of the record to use in this operation
0515:             * @param buffer the byte array in which to copy the data
0516:             * @param offset the index into the buffer in which to start copying
0517:             *
0518:             * @exception RecordStoreNotOpenException if the record store is
0519:             *          not open
0520:             * @exception InvalidRecordIDException if the recordId is invalid
0521:             * @exception RecordStoreException if a general record store
0522:             *          exception occurs
0523:             * @exception ArrayIndexOutOfBoundsException if the record is
0524:             *          larger than the buffer supplied
0525:             *
0526:             * @return the number of bytes copied into the buffer, starting at
0527:             *          index <code>offset</code>
0528:             * @see #setRecord
0529:             */
0530:            public int getRecord(int recordId, byte[] buffer, int offset)
0531:                    throws RecordStoreNotOpenException,
0532:                    InvalidRecordIDException, RecordStoreException {
0533:                synchronized (rsLock) {
0534:                    try {
0535:                        byte[] header = new byte[BLOCK_HEADER_SIZE];
0536:                        int blockOffset = dbIndex.getRecordHeader(recordId,
0537:                                header);
0538:
0539:                        int dataSize = RecordStoreUtil.getInt(header, 4);
0540:
0541:                        dbFile.seek(blockOffset + BLOCK_HEADER_SIZE);
0542:                        return dbFile.read(buffer, offset, dataSize);
0543:                    } catch (java.io.IOException ioe) {
0544:                        throw new RecordStoreException(
0545:                                "error reading record data");
0546:                    }
0547:                }
0548:            }
0549:
0550:            /**
0551:             * Returns a copy of the data stored in the given record.
0552:             *
0553:             * @param recordId the ID of the record to use in this operation
0554:             *
0555:             * @exception RecordStoreNotOpenException if the record store is
0556:             *          not open
0557:             * @exception InvalidRecordIDException if the recordId is invalid
0558:             * @exception RecordStoreException if a general record store
0559:             *          exception occurs
0560:             *
0561:             * @return the data stored in the given record. Note that if the
0562:             *          record has no data, this method will return null.
0563:             * @see #setRecord
0564:             */
0565:            public byte[] getRecord(int recordId)
0566:                    throws RecordStoreNotOpenException,
0567:                    InvalidRecordIDException, RecordStoreException {
0568:                synchronized (rsLock) {
0569:                    try {
0570:                        byte[] header = new byte[BLOCK_HEADER_SIZE];
0571:                        int blockOffset = dbIndex.getRecordHeader(recordId,
0572:                                header);
0573:
0574:                        int dataSize = RecordStoreUtil.getInt(header, 4);
0575:                        if (dataSize == 0) {
0576:                            return null;
0577:                        }
0578:
0579:                        byte[] buffer = new byte[dataSize];
0580:
0581:                        dbFile.seek(blockOffset + BLOCK_HEADER_SIZE);
0582:                        dbFile.read(buffer);
0583:
0584:                        return buffer;
0585:                    } catch (java.io.IOException ioe) {
0586:                        throw new RecordStoreException(
0587:                                "error reading record data");
0588:                    }
0589:                }
0590:            }
0591:
0592:            /**
0593:             * Sets the data in the given record to that passed in. After
0594:             * this method returns, a call to <code>getRecord(int recordId)</code>
0595:             * will return an array of numBytes size containing the data
0596:             * supplied here.
0597:             *
0598:             * @param recordId the ID of the record to use in this operation
0599:             * @param newData the new data to store in the record
0600:             * @param offset the index into the data buffer of the first
0601:             *          relevant byte for this record
0602:             * @param numBytes the number of bytes of the data buffer to use
0603:             *          for this record
0604:             *
0605:             * @exception RecordStoreNotOpenException if the record store is
0606:             *          not open
0607:             * @exception InvalidRecordIDException if the recordId is invalid
0608:             * @exception RecordStoreException if a general record store
0609:             *          exception occurs
0610:             * @exception RecordStoreFullException if the operation cannot be
0611:             *          completed because the record store has no more room
0612:             * @exception SecurityException if the MIDlet has read-only access
0613:             *          to the RecordStore
0614:             * @see #getRecord
0615:             */
0616:            public void setRecord(int recordId, byte[] newData, int offset,
0617:                    int numBytes) throws RecordStoreNotOpenException,
0618:                    InvalidRecordIDException, RecordStoreException,
0619:                    RecordStoreFullException {
0620:
0621:                synchronized (rsLock) {
0622:                    try {
0623:                        byte[] header = new byte[BLOCK_HEADER_SIZE];
0624:                        int blockOffset = dbIndex.getRecordHeader(recordId,
0625:                                header);
0626:
0627:                        int oldBlockSize = RecordStoreUtil
0628:                                .calculateBlockSize(RecordStoreUtil.getInt(
0629:                                        header, 4));
0630:                        int newBlockSize = RecordStoreUtil
0631:                                .calculateBlockSize(numBytes);
0632:                        if (newBlockSize <= oldBlockSize) {
0633:                            // reuse the old block
0634:                            splitBlock(blockOffset, header, newData, offset,
0635:                                    numBytes);
0636:                        } else {
0637:                            // free the old record data
0638:                            freeBlock(blockOffset, header);
0639:
0640:                            // add a block that contains the new record data
0641:                            addBlock(recordId, newData, offset, numBytes);
0642:                        }
0643:
0644:                        // update the db header
0645:                        RecordStoreUtil.putInt(getVersion() + 1, dbHeader,
0646:                                RS4_VERSION);
0647:                        RecordStoreUtil.putLong(System.currentTimeMillis(),
0648:                                dbHeader, RS5_LAST_MODIFIED);
0649:
0650:                        // write out the changes to the db header
0651:                        dbFile.seek(RS4_VERSION);
0652:                        dbFile.write(dbHeader, RS4_VERSION, 4 + 8);
0653:                        // dbFile.commitWrite();
0654:                    } catch (java.io.IOException ioe) {
0655:                        throw new RecordStoreException(
0656:                                "error setting record data");
0657:                    }
0658:                }
0659:            }
0660:
0661:            /**
0662:             * Returns all of the recordId's currently in the record store.
0663:             *
0664:             * @return an array of the recordId's currently in the record store
0665:             *         or null if the record store is closed.
0666:             */
0667:            public int[] getRecordIDs() {
0668:                synchronized (rsLock) {
0669:                    return dbIndex.getRecordIDs();
0670:                }
0671:            }
0672:
0673:            /**
0674:             * Returns data base file associated with this record store
0675:             *
0676:             * @return data base file
0677:             */
0678:            public AbstractRecordStoreFile getDbFile() {
0679:                return dbFile;
0680:            }
0681:
0682:            /**
0683:             * Creates data base index file associated with this record store
0684:             *
0685:             * @param suiteId unique ID of the suite that owns the store
0686:             * @param name a string to name the index file
0687:             * @return data base index file
0688:             * @exception IOException if failed to create a file
0689:             */
0690:            public AbstractRecordStoreFile createIndexFile(int suiteId,
0691:                    String name) throws IOException {
0692:                return new RecordStoreFile(suiteId, name,
0693:                        AbstractRecordStoreFile.IDX_EXTENSION);
0694:            }
0695:
0696:            /**
0697:             * Remove free blocks from the record store and compact records
0698:             * with data into as small a space in <code>dbFile</code> as
0699:             * possible.  Operates from smallest to greatest offset in
0700:             * <code>dbFile</code>, copying data in chunks towards the
0701:             * beginning of the file, and updating record store meta-data
0702:             * as it progresses.
0703:             *
0704:             * Warning: This is a slow operation that scales linearly
0705:             * with dbFile size.
0706:             *
0707:             * @exception RecordStoreNotOpenException if this record store
0708:             *            is closed
0709:             * @exception RecordStoreException if an error occurs during record
0710:             *            store compaction
0711:             */
0712:            private void compactRecords() throws IOException {
0713:
0714:                // check if the db can be compacted
0715:                if (RecordStoreUtil.getInt(dbHeader, RS7_FREE_SIZE) == 0) {
0716:                    // no free space to compact
0717:                    return;
0718:                }
0719:
0720:                byte[] header = new byte[BLOCK_HEADER_SIZE];
0721:                int currentId = 0;
0722:                int currentOffset = RecordStoreImpl.DB_HEADER_SIZE;
0723:                int currentSize = 0;
0724:                int moveUpNumBytes = 0;
0725:
0726:                // search through the data blocks for a free block that is large enough
0727:                while (currentOffset < getSize()) {
0728:                    // seek to the next offset
0729:                    dbFile.seek(currentOffset);
0730:
0731:                    // read the block header
0732:                    if (dbFile.read(header) != RecordStoreImpl.BLOCK_HEADER_SIZE) {
0733:                        // could not read the block
0734:                        throw new IOException();
0735:                    }
0736:
0737:                    currentId = RecordStoreUtil.getInt(header, 0);
0738:                    currentSize = RecordStoreUtil
0739:                            .calculateBlockSize(RecordStoreUtil.getInt(header,
0740:                                    4));
0741:
0742:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0743:                        Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
0744:                                "currentId = " + currentId + " currentSize = "
0745:                                        + currentSize);
0746:                    }
0747:
0748:                    // check if this is a free block or a record
0749:                    if (currentId < 0) {
0750:                        if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0751:                            Logging.report(Logging.INFORMATION,
0752:                                    LogChannels.LC_RMS,
0753:                                    "found free block at offset "
0754:                                            + currentOffset);
0755:                        }
0756:
0757:                        // a free block, add to the moveUpNumBytes
0758:                        moveUpNumBytes += currentSize;
0759:
0760:                        // remove from the index
0761:                        dbIndex.removeBlock(currentOffset, header);
0762:                    } else {
0763:                        if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0764:                            Logging.report(Logging.INFORMATION,
0765:                                    LogChannels.LC_RMS,
0766:                                    "found record block at offset "
0767:                                            + currentOffset);
0768:                        }
0769:
0770:                        // a record data block, check if it needs to be moved up
0771:                        if (moveUpNumBytes > 0) {
0772:
0773:                            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0774:                                Logging.report(Logging.INFORMATION,
0775:                                        LogChannels.LC_RMS, "moveUpNumBytes = "
0776:                                                + currentOffset);
0777:                            }
0778:
0779:                            int numMoved = 0;
0780:                            while (numMoved < currentSize) {
0781:                                int curRead = currentSize - numMoved;
0782:                                if (curRead > COMPACT_BUFFER_SIZE) {
0783:                                    curRead = COMPACT_BUFFER_SIZE;
0784:                                }
0785:
0786:                                dbFile.seek(currentOffset + numMoved);
0787:                                curRead = dbFile
0788:                                        .read(compactBuffer, 0, curRead);
0789:                                if (curRead == -1) {
0790:                                    throw new IOException();
0791:                                }
0792:
0793:                                dbFile.seek(currentOffset + numMoved
0794:                                        - moveUpNumBytes);
0795:                                dbFile.write(compactBuffer, 0, curRead);
0796:                                // dbFile.commitWrite();
0797:                                numMoved += curRead;
0798:                            }
0799:
0800:                            dbIndex.updateBlock(currentOffset - moveUpNumBytes,
0801:                                    header);
0802:                        }
0803:                    }
0804:
0805:                    // added the block size to the currentOffset
0806:                    currentOffset += currentSize;
0807:                }
0808:
0809:                // check if the db file can be truncated
0810:                if (moveUpNumBytes > 0) {
0811:                    RecordStoreUtil.putInt(RecordStoreUtil.getInt(dbHeader,
0812:                            RS6_DATA_SIZE)
0813:                            - moveUpNumBytes, dbHeader, RS6_DATA_SIZE);
0814:                    RecordStoreUtil.putInt(0, dbHeader, RS7_FREE_SIZE);
0815:                    dbFile.seek(RS6_DATA_SIZE);
0816:                    dbFile.write(dbHeader, RS6_DATA_SIZE, 4 + 4);
0817:                    // dbFile.commitWrite();
0818:
0819:                    dbFile.truncate(getSize());
0820:
0821:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0822:                        Logging
0823:                                .report(Logging.INFORMATION,
0824:                                        LogChannels.LC_RMS,
0825:                                        "compactRecords, truncate to size "
0826:                                                + getSize());
0827:                    }
0828:                }
0829:            }
0830:
0831:            /**
0832:             * Set the record in the block to the data passed in and adds any remaining
0833:             * space to the free list.
0834:             *
0835:             * @param blockOffset the offset in db file to the block to split
0836:             * @param header the header of the block to split
0837:             * @param newData the new data to store in the record
0838:             * @param offset the index into the data buffer of the first
0839:             *          relevant byte for this record
0840:             * @param numBytes the number of bytes of the data buffer to use
0841:             *          for this record
0842:             *
0843:             * @exception IOException if there is an error accessing the db file
0844:             */
0845:            private void splitBlock(int blockOffset, byte[] header,
0846:                    byte[] newData, int offset, int numBytes)
0847:                    throws IOException {
0848:
0849:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0850:                    Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
0851:                            "splitBlock(" + RecordStoreUtil.getInt(header, 0)
0852:                                    + ") old numBytes = "
0853:                                    + RecordStoreUtil.getInt(header, 4)
0854:                                    + " new numBytes=" + numBytes);
0855:                }
0856:
0857:                // calculate the size of the block
0858:                int oldBlockSize = RecordStoreUtil
0859:                        .calculateBlockSize(RecordStoreUtil.getInt(header, 4));
0860:
0861:                // calculate the size of the block
0862:                int newBlockSize = RecordStoreUtil.calculateBlockSize(numBytes);
0863:
0864:                // update the block header
0865:                RecordStoreUtil.putInt(numBytes, header, 4);
0866:
0867:                // seek to the location and write the block and header
0868:                writeBlock(blockOffset, header, newData, offset, numBytes);
0869:
0870:                // check if there is any left over free space
0871:                int freeSize = oldBlockSize - newBlockSize - BLOCK_HEADER_SIZE;
0872:                if (freeSize >= 0) {
0873:                    // update the block header and free block of extra space
0874:                    RecordStoreUtil.putInt(freeSize, header, 4);
0875:                    freeBlock(blockOffset + newBlockSize, header);
0876:                }
0877:            }
0878:
0879:            /**
0880:             * Adds a block for the record and data or sets an existing block to
0881:             * the data.  Splits an exiting block if needed.
0882:             *
0883:             * @param recordId the ID of the record to use in this operation
0884:             * @param data the new data to store in the record
0885:             * @param offset the index into the data buffer of the first
0886:             *          relevant byte for this record
0887:             * @param numBytes the number of bytes of the data buffer to use
0888:             *          for this record
0889:             *
0890:             * @exception RecordStoreFullException if the operation cannot be
0891:             *          completed because the record store has no more room
0892:             * @exception IOException if there is an error accessing the db file
0893:             * @exception RecordStoreException if the new consumption is gong to
0894:             *            exceed the resource limit
0895:             *
0896:             * @return the offset in the db file of the block added
0897:             */
0898:            private int addBlock(int recordId, byte[] data, int offset,
0899:                    int numBytes) throws IOException, RecordStoreFullException,
0900:                    RecordStoreException {
0901:
0902:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0903:                    Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
0904:                            "addBlock(" + recordId + ") numBytes=" + numBytes);
0905:                }
0906:
0907:                // calculate the size of the block needed
0908:                int blockSize = RecordStoreUtil.calculateBlockSize(numBytes);
0909:                int blockOffset = 0;
0910:                int freeBlocksSize = RecordStoreUtil.getInt(dbHeader,
0911:                        RS7_FREE_SIZE);
0912:
0913:                // initialize the block header
0914:                byte[] header = new byte[BLOCK_HEADER_SIZE];
0915:
0916:                // check if there is the potential for a large enough free block
0917:                if (freeBlocksSize >= blockSize) {
0918:
0919:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0920:                        Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
0921:                                "blockSize = " + blockSize + "free size = "
0922:                                        + freeBlocksSize);
0923:                    }
0924:
0925:                    // initialize the number of bytes and search for an
0926:                    // available free block
0927:                    RecordStoreUtil.putInt(numBytes, header, 4);
0928:                    blockOffset = dbIndex.getFreeBlock(header);
0929:                }
0930:
0931:                // set the recordId in to the block header
0932:                RecordStoreUtil.putInt(recordId, header, 0);
0933:
0934:                if (blockOffset > 0) {
0935:                    // search found a block, use it
0936:                    splitBlock(blockOffset, header, data, offset, numBytes);
0937:                } else {
0938:                    // search failed, add a new block to the end of the db file
0939:                    int spaceAvailable = getSizeAvailable();
0940:                    /**
0941:                     * spaceAvailable returns the smaller number of total space
0942:                     * available and the storage limit per suite. If it is less than
0943:                     * the block size to be added, RecordStoreFullException is thrown
0944:                     */
0945:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0946:                        Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
0947:                                "spaceAvailable = " + spaceAvailable);
0948:                    }
0949:
0950:                    // Is there room to grow the file?
0951:                    if (spaceAvailable < blockSize) {
0952:                        // Is there enough room totally: in storage and free blocks?
0953:                        if (spaceAvailable + freeBlocksSize < blockSize) {
0954:                            throw new RecordStoreFullException();
0955:                        }
0956:                        compactRecords();
0957:                    }
0958:
0959:                    blockOffset = getSize();
0960:
0961:                    // seek to the location and write the block and header
0962:                    RecordStoreUtil.putInt(numBytes, header, 4);
0963:                    writeBlock(blockOffset, header, data, offset, numBytes);
0964:
0965:                    // update the db data size
0966:                    RecordStoreUtil.putInt(RecordStoreUtil.getInt(dbHeader,
0967:                            RS6_DATA_SIZE)
0968:                            + blockSize, dbHeader, RS6_DATA_SIZE);
0969:                    dbFile.seek(RS6_DATA_SIZE);
0970:                    dbFile.write(dbHeader, RS6_DATA_SIZE, 4);
0971:                    // dbFile.commitWrite();
0972:
0973:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0974:                        Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
0975:                                "blockOffset = " + blockOffset);
0976:                    }
0977:                }
0978:
0979:                return blockOffset;
0980:            }
0981:
0982:            /**
0983:             * Mark the block at the given offset in db file as free.
0984:             *
0985:             * @param blockOffset the offset in db file to the block to free
0986:             * @param header the header of the block to free
0987:             *
0988:             * @exception IOException if there is an error accessing the db file
0989:             */
0990:            private void freeBlock(int blockOffset, byte[] header)
0991:                    throws IOException {
0992:                int dataSize = RecordStoreUtil.getInt(header, 4);
0993:
0994:                // calculate the size of the block
0995:                int blockSize = RecordStoreUtil.calculateBlockSize(dataSize);
0996:
0997:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0998:                    Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
0999:                            "freeBlock(" + blockOffset + ") size = "
1000:                                    + blockSize);
1001:                }
1002:
1003:                // mark the block as free
1004:                RecordStoreUtil.putInt(-1, header, 0);
1005:                RecordStoreUtil
1006:                        .putInt(blockSize - BLOCK_HEADER_SIZE, header, 4);
1007:
1008:                // save the updated block header
1009:                writeBlock(blockOffset, header, null, 0, 0);
1010:
1011:                // add to the db free size
1012:                RecordStoreUtil.putInt(RecordStoreUtil.getInt(dbHeader,
1013:                        RS7_FREE_SIZE)
1014:                        + blockSize, dbHeader, RS7_FREE_SIZE);
1015:                dbFile.seek(RS7_FREE_SIZE);
1016:                dbFile.write(dbHeader, RS7_FREE_SIZE, 4);
1017:                // dbFile.commitWrite();
1018:            }
1019:
1020:            /**
1021:             * Writes a block to the db file at the given offset.
1022:             *
1023:             * @param blockOffset the offset in db file to write the block
1024:             * @param header the header of the block to write
1025:             * @param data the new data to store in the record
1026:             * @param offset the index into the data buffer of the first
1027:             *          relevant byte for this record
1028:             * @param numBytes the number of bytes of the data buffer to use
1029:             *          for this record
1030:             *
1031:             * @exception IOException if there is an error accessing the db file
1032:             */
1033:            private void writeBlock(int blockOffset, byte[] header,
1034:                    byte[] data, int offset, int numBytes) throws IOException {
1035:
1036:                int remainder;
1037:                dbFile.seek(blockOffset);
1038:                dbFile.write(header);
1039:                if (data != null && numBytes > 0) {
1040:                    dbFile.write(data, offset, numBytes);
1041:                    remainder = numBytes % BLOCK_HEADER_SIZE;
1042:                    if (remainder != 0) {
1043:                        // DB_SIGNATURE used here as meaningless pad bytes
1044:                        dbFile.write(DB_SIGNATURE, 0, BLOCK_HEADER_SIZE
1045:                                - remainder);
1046:                    }
1047:                }
1048:                // flush the writes
1049:                // dbFile.commitWrite();
1050:                // update the index
1051:                dbIndex.updateBlock(blockOffset, header);
1052:            }
1053:
1054:            /**
1055:             * Creates a RecordStoreImpl instance; for internal use only.
1056:             * Callers from outside must use <code>openRecordStore()</code>.
1057:             *
1058:             * @param suiteId unique ID of the suite that owns the store
1059:             * @param recordStoreName a string to name the record store
1060:             * @param create if true, create the record store if it doesn't exist
1061:             *
1062:             * @exception RecordStoreException if something goes wrong setting up
1063:             *            the new RecordStore.
1064:             * @exception RecordStoreNotFoundException if can't find the record store
1065:             *            and create is set to false.
1066:             * @exception RecordStoreFullException if there is no room in storage
1067:             *            to create a new record store
1068:             */
1069:            private RecordStoreImpl(int suiteId, String recordStoreName,
1070:                    boolean create) throws RecordStoreException,
1071:                    RecordStoreNotFoundException {
1072:
1073:                this .suiteId = suiteId;
1074:                rsLock = new Object();
1075:
1076:                boolean exists = RecordStoreUtil.exists(suiteId,
1077:                        recordStoreName, RecordStoreFile.DB_EXTENSION);
1078:
1079:                // Check for errors between app and record store existance.
1080:                if (!create && !exists) {
1081:                    throw new RecordStoreNotFoundException(
1082:                            "cannot find record " + "store file");
1083:                }
1084:
1085:                /*
1086:                 * If a new RecordStoreImpl will be created in storage,
1087:                 * check to see if the space required is available.
1088:                 */
1089:                if (create && !exists) {
1090:                    int space = RecordStoreFile
1091:                            .spaceAvailableNewRecordStore(suiteId);
1092:                    if (space - DB_HEADER_SIZE < 0) {
1093:                        throw new RecordStoreFullException();
1094:                    }
1095:                }
1096:
1097:                // Create a RecordStoreFile for storing the record store.
1098:                try {
1099:                    dbFile = new RecordStoreFile(suiteId, recordStoreName,
1100:                            RecordStoreFile.DB_EXTENSION);
1101:
1102:                    // allocate a new header
1103:                    dbHeader = new byte[DB_HEADER_SIZE];
1104:
1105:                    if (exists) {
1106:                        // load header
1107:                        dbFile.read(dbHeader);
1108:
1109:                        /*
1110:                         * Verify that the file is actually a record store
1111:                         * by verifying the record store "signature."
1112:                         */
1113:                        for (int i = 0; i < DB_SIGNATURE.length; i++) {
1114:                            if (dbHeader[i] != DB_SIGNATURE[i]) {
1115:                                throw new RecordStoreException(
1116:                                        "invalid record " + "store contents");
1117:                            }
1118:                        }
1119:                    } else {
1120:                        // initialize the header
1121:                        for (int i = 0; i < DB_SIGNATURE.length; i++) {
1122:                            dbHeader[i] = DB_SIGNATURE[i];
1123:                        }
1124:
1125:                        RecordStoreUtil.putInt(1, dbHeader, RS2_NEXT_ID);
1126:                        RecordStoreUtil.putLong(System.currentTimeMillis(),
1127:                                dbHeader, RS5_LAST_MODIFIED);
1128:
1129:                        // write the header to the file
1130:                        dbFile.write(dbHeader);
1131:                        dbFile.commitWrite();
1132:                    }
1133:
1134:                    // create the index object
1135:                    dbIndex = new RecordStoreIndex(this , suiteId,
1136:                            recordStoreName);
1137:
1138:                } catch (java.io.IOException ioe) {
1139:                    try {
1140:                        if (dbFile != null) {
1141:                            dbFile.close();
1142:                        }
1143:                    } catch (java.io.IOException ioe2) {
1144:                        // ignore exception within exception block
1145:                    }
1146:
1147:                    if (!exists) {
1148:                        // avoid preserving just created damaged files
1149:                        RecordStoreUtil.quietDeleteFile(suiteId,
1150:                                recordStoreName, RecordStoreFile.DB_EXTENSION);
1151:                        RecordStoreIndex.deleteIndex(suiteId, recordStoreName);
1152:                    }
1153:
1154:                    dbFile = null;
1155:                    throw new RecordStoreException(
1156:                            "error opening record store " + "file");
1157:                }
1158:            }
1159:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.