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


0001:        /*
0002:         *
0003:         *
0004:         * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
0005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0006:         * 
0007:         * This program is free software; you can redistribute it and/or
0008:         * modify it under the terms of the GNU General Public License version
0009:         * 2 only, as published by the Free Software Foundation.
0010:         * 
0011:         * This program is distributed in the hope that it will be useful, but
0012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014:         * General Public License version 2 for more details (a copy is
0015:         * included at /legal/license.txt).
0016:         * 
0017:         * You should have received a copy of the GNU General Public License
0018:         * version 2 along with this work; if not, write to the Free Software
0019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020:         * 02110-1301 USA
0021:         * 
0022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0023:         * Clara, CA 95054 or visit www.sun.com if you need additional
0024:         * information or have any questions.
0025:         */
0026:
0027:        package javax.microedition.rms;
0028:
0029:        import com.sun.midp.midlet.MIDletSuite;
0030:        import com.sun.midp.midlet.MIDletStateHandler;
0031:
0032:        import com.sun.midp.midletsuite.MIDletSuiteStorage;
0033:
0034:        import com.sun.midp.rms.RecordStoreImpl;
0035:
0036:        import com.sun.midp.security.SecurityInitializer;
0037:        import com.sun.midp.security.SecurityToken;
0038:        import com.sun.midp.security.ImplicitlyTrustedClass;
0039:
0040:        import com.sun.midp.log.Logging;
0041:        import com.sun.midp.log.LogChannels;
0042:
0043:        /**
0044:         * A class representing a record store. A record store consists of a
0045:         * collection of records which will remain persistent across multiple
0046:         * invocations of the MIDlet. The platform is responsible for
0047:         * making its best effort to maintain the integrity of the
0048:         * MIDlet's record stores throughout the normal use of the
0049:         * platform, including reboots, battery changes, etc.
0050:         *
0051:         * <p>Record stores are created in platform-dependent locations, which
0052:         * are not exposed to the MIDlets. The naming space for record stores
0053:         * is controlled at the MIDlet suite granularity. MIDlets within a
0054:         * MIDlet suite are allowed to create multiple record stores, as long
0055:         * as they are each given different names. When a MIDlet suite is
0056:         * removed from a platform all the record stores associated with its
0057:         * MIDlets will also be removed. MIDlets within a MIDlet suite can
0058:         * access each other's record stores directly. New APIs in MIDP
0059:         * allow for the explicit sharing of record stores if the MIDlet
0060:         * creating the RecordStore chooses to give such permission.</p>
0061:         *
0062:         * <p> Sharing is accomplished through the ability to name a
0063:         * RecordStore created by another MIDlet suite.</p>
0064:         *
0065:         * <P> RecordStores are uniquely named using the unique name of the
0066:         * MIDlet suite plus the name of the RecordStore. MIDlet suites are
0067:         * identified by the MIDlet-Vendor and MIDlet-Name attributes from the
0068:         * application descriptor.</p>
0069:         *
0070:         * <p> Access controls are defined when RecordStores to be shared are
0071:         * created. Access controls are enforced when RecordStores are
0072:         * opened. The access modes allow private use or shareable
0073:         * with any other MIDlet suite.</p>
0074:         *
0075:         * <p>Record store names are case sensitive and may consist of any
0076:         * combination of between one and 32 Unicode characters
0077:         * inclusive. Record store names must be unique within the scope of a
0078:         * given MIDlet suite. In other words, MIDlets within a MIDlet suite
0079:         * are not allowed to create more than one record store with the same
0080:         * name, however a MIDlet in one MIDlet suite is allowed to have a
0081:         * record store with the same name as a MIDlet in another MIDlet
0082:         * suite. In that case, the record stores are still distinct and
0083:         * separate.</p>
0084:         *
0085:         * <p>No locking operations are provided in this API. Record store
0086:         * implementations ensure that all individual record store operations
0087:         * are atomic, synchronous, and serialized, so no corruption will
0088:         * occur with multiple accesses. However, if a MIDlet uses multiple
0089:         * threads to access a record store, it is the MIDlet's responsibility
0090:         * to coordinate this access or unintended consequences may result.
0091:         * Similarly, if a platform performs transparent synchronization of a
0092:         * record store, it is the platform's responsibility to enforce
0093:         * exclusive access to the record store between the MIDlet and
0094:         * synchronization engine.</p>
0095:         *
0096:         * <p>Records are uniquely identified within a given record store by
0097:         * their recordId, which is an integer value. This recordId is used as
0098:         * the primary key for the records. The first record created in a
0099:         * record store will have recordId equal to one (1). Each subsequent
0100:         * record added to a RecordStore will be assigned a recordId one
0101:         * greater than the record added before it. That is, if two records
0102:         * are added to a record store, and the first has a recordId of 'n',
0103:         * the next will have a recordId of 'n + 1'. MIDlets can create other
0104:         * sequences of the records in the RecordStore by using the
0105:         * <code>RecordEnumeration</code> class.</p>
0106:         *
0107:         * <p>This record store uses long integers for time/date stamps, in
0108:         * the format used by System.currentTimeMillis(). The record store is
0109:         * time stamped with the last time it was modified. The record store
0110:         * also maintains a <em>version</em> number, which is an integer that
0111:         * is incremented for each operation that modifies the contents of the
0112:         * RecordStore.  These are useful for synchronization engines as well
0113:         * as other things.</p>
0114:         *
0115:         * @since MIDP 1.0
0116:         */
0117:
0118:        public class RecordStore {
0119:
0120:            /** cache of open RecordStore instances */
0121:            private static java.util.Vector openRecordStores = new java.util.Vector(
0122:                    3);
0123:
0124:            /** The peer that performs the real functionallity. */
0125:            private RecordStoreImpl peer;
0126:
0127:            /** name of this record store */
0128:            private String recordStoreName;
0129:
0130:            /** unique id for suite that owns this record store */
0131:            private int suiteId;
0132:
0133:            /** number of open instances of this record store */
0134:            private int opencount;
0135:
0136:            /** recordListeners of this record store */
0137:            private java.util.Vector recordListener;
0138:
0139:            /**
0140:             * Inner class to request security token from SecurityInitializer.
0141:             * SecurityInitializer should be able to check this inner class name.
0142:             */
0143:            static private class SecurityTrusted implements 
0144:                    ImplicitlyTrustedClass {
0145:            };
0146:
0147:            /**
0148:             * The security token necessary to use RecordStoreImpl.
0149:             * This is initialized in a static initialization block.
0150:             */
0151:            private static SecurityToken classSecurityToken = SecurityInitializer
0152:                    .requestToken(new SecurityTrusted());
0153:
0154:            /*
0155:             * RecordStore Constructors
0156:             */
0157:
0158:            /**
0159:             * MIDlets must use <code>openRecordStore()</code> to get
0160:             * a <code>RecordStore</code> object. If this constructor
0161:             * is not declared (as private scope), Javadoc (and Java)
0162:             * will assume a public constructor.
0163:             *
0164:             * @param suiteId the ID of the suite that owns this record store
0165:             * @param recordStoreName the MIDlet suite unique name for the
0166:             *          record store, consisting of between one and 32 Unicode
0167:             *          characters inclusive.
0168:             */
0169:            private RecordStore(int suiteId, String recordStoreName) {
0170:                this .suiteId = suiteId;
0171:                this .recordStoreName = recordStoreName;
0172:                recordListener = new java.util.Vector(3);
0173:            }
0174:
0175:            /**
0176:             * Deletes the named record store. MIDlet suites are only allowed
0177:             * to delete their own record stores. If the named record store is
0178:             * open (by a MIDlet in this suite or a MIDlet in a different
0179:             * MIDlet suite) when this method is called, a
0180:             * RecordStoreException will be thrown.  If the named record store
0181:             * does not exist a RecordStoreNotFoundException will be
0182:             * thrown. Calling this method does NOT result in recordDeleted
0183:             * calls to any registered listeners of this RecordStore.
0184:             *
0185:             * @param recordStoreName the MIDlet suite unique record store to
0186:             *          delete
0187:             *
0188:             * @exception RecordStoreException if a record store-related
0189:             *          exception occurred
0190:             * @exception RecordStoreNotFoundException if the record store
0191:             *          could not be found
0192:             */
0193:            public static void deleteRecordStore(String recordStoreName)
0194:                    throws RecordStoreException, RecordStoreNotFoundException {
0195:                int id = MIDletStateHandler.getMidletStateHandler()
0196:                        .getMIDletSuite().getID();
0197:
0198:                if (recordStoreName == null || recordStoreName.length() == 0) {
0199:                    throw new RecordStoreNotFoundException();
0200:                }
0201:
0202:                // Check the record store cache for a db with the same name
0203:                synchronized (openRecordStores) {
0204:                    RecordStore db;
0205:                    int size = openRecordStores.size();
0206:                    for (int n = 0; n < size; n++) {
0207:                        db = (RecordStore) openRecordStores.elementAt(n);
0208:                        if (db.suiteId == id
0209:                                && db.recordStoreName.equals(recordStoreName)) {
0210:                            // cannot delete an open record store
0211:                            throw new RecordStoreException(
0212:                                    "deleteRecordStore error:"
0213:                                            + " record store is"
0214:                                            + " still open");
0215:                        }
0216:                    }
0217:
0218:                    // this record store is not currently open
0219:                    RecordStoreImpl.deleteRecordStore(classSecurityToken, id,
0220:                            recordStoreName);
0221:                }
0222:            }
0223:
0224:            /**
0225:             * Open (and possibly create) a record store associated with the
0226:             * given MIDlet suite. If this method is called by a MIDlet when
0227:             * the record store is already open by a MIDlet in the MIDlet suite,
0228:             * this method returns a reference to the same RecordStore object.
0229:             *
0230:             * @param recordStoreName the MIDlet suite unique name for the
0231:             *          record store, consisting of between one and 32 Unicode
0232:             *          characters inclusive.
0233:             * @param createIfNecessary if true, the record store will be
0234:             *          created if necessary
0235:             *
0236:             * @return <code>RecordStore</code> object for the record store
0237:             *
0238:             * @exception RecordStoreException if a record store-related
0239:             *          exception occurred
0240:             * @exception RecordStoreNotFoundException if the record store
0241:             *          could not be found
0242:             * @exception RecordStoreFullException if the operation cannot be
0243:             *          completed because the record store is full
0244:             * @exception IllegalArgumentException if
0245:             *          recordStoreName is invalid
0246:             */
0247:            public static RecordStore openRecordStore(String recordStoreName,
0248:                    boolean createIfNecessary) throws RecordStoreException,
0249:                    RecordStoreFullException, RecordStoreNotFoundException {
0250:
0251:                int id = MIDletStateHandler.getMidletStateHandler()
0252:                        .getMIDletSuite().getID();
0253:
0254:                return doOpen(id, recordStoreName, createIfNecessary);
0255:            }
0256:
0257:            /**
0258:             * Open (and possibly create) a record store that can be shared
0259:             * with other MIDlet suites. The RecordStore is owned by the
0260:             * current MIDlet suite. The authorization mode is set when the
0261:             * record store is created, as follows:
0262:             *
0263:             * <ul>
0264:             * <li><code>AUTHMODE_PRIVATE</code> - Only allows the MIDlet
0265:             *          suite that created the RecordStore to access it. This
0266:             *          case behaves identically to
0267:             *          <code>openRecordStore(recordStoreName,
0268:             *          createIfNecessary)</code>.</li>
0269:             * <li><code>AUTHMODE_ANY</code> - Allows any MIDlet to access the
0270:             *          RecordStore. Note that this makes your recordStore
0271:             *          accessible by any other MIDlet on the device. This
0272:             *          could have privacy and security issues depending on
0273:             *          the data being shared. Please use carefully.</li>
0274:             * </ul>
0275:             *
0276:             * <p>The owning MIDlet suite may always access the RecordStore and
0277:             * always has access to write and update the store.</p>
0278:             *
0279:             * <p> If this method is called by a MIDlet when the record store
0280:             * is already open by a MIDlet in the MIDlet suite, this method
0281:             * returns a reference to the same RecordStore object.</p>
0282:             *
0283:             * @param recordStoreName the MIDlet suite unique name for the
0284:             *          record store, consisting of between one and 32 Unicode
0285:             *          characters inclusive.
0286:             * @param createIfNecessary if true, the record store will be
0287:             *          created if necessary
0288:             * @param authmode the mode under which to check or create access.
0289:             *          Must be one of AUTHMODE_PRIVATE or AUTHMODE_ANY.
0290:             *          This argument is ignored if the RecordStore exists.
0291:             * @param writable true if the RecordStore is to be writable by
0292:             *          other MIDlet suites that are granted access.
0293:             *          This argument is ignored if the RecordStore exists.
0294:             *
0295:             * @return <code>RecordStore</code> object for the record store
0296:             *
0297:             * @exception RecordStoreException if a record store-related
0298:             *          exception occurred
0299:             * @exception RecordStoreNotFoundException if the record store
0300:             *          could not be found
0301:             * @exception RecordStoreFullException if the operation
0302:             *          cannot be completed because the record store is full
0303:             * @exception IllegalArgumentException if authmode or
0304:             *          recordStoreName is invalid
0305:             */
0306:            public static RecordStore openRecordStore(String recordStoreName,
0307:                    boolean createIfNecessary, int authmode, boolean writable)
0308:                    throws RecordStoreException, RecordStoreFullException,
0309:                    RecordStoreNotFoundException {
0310:                RecordStore recordStore;
0311:                boolean isExistingStorage = false;
0312:
0313:                /*
0314:                 * First, we have to check if the record store already exists or not.
0315:                 * If we open an existing record store, "authmode" must be ignored!
0316:                 *
0317:                 */
0318:                try {
0319:                    recordStore = openRecordStore(recordStoreName, false);
0320:                    isExistingStorage = true;
0321:                } catch (RecordStoreNotFoundException ex) {
0322:                    recordStore = openRecordStore(recordStoreName,
0323:                            createIfNecessary);
0324:                }
0325:
0326:                if (!isExistingStorage) {
0327:                    try {
0328:                        recordStore.peer.setMode(authmode, writable);
0329:                    } catch (Exception e) {
0330:                        try {
0331:                            recordStore.closeRecordStore();
0332:                        } catch (Exception ex) {
0333:                            // do not overthrow the real exception
0334:                        }
0335:
0336:                        try {
0337:                            int id = MIDletStateHandler.getMidletStateHandler()
0338:                                    .getMIDletSuite().getID();
0339:                            RecordStoreImpl.deleteRecordStore(
0340:                                    classSecurityToken, id, recordStoreName);
0341:                        } catch (Exception ex) {
0342:                            // do not overthrow the real exception
0343:                        }
0344:
0345:                        if (e instanceof  RecordStoreException) {
0346:                            throw (RecordStoreException) e;
0347:                        }
0348:
0349:                        throw (RuntimeException) e;
0350:                    }
0351:                }
0352:
0353:                return recordStore;
0354:            }
0355:
0356:            /**
0357:             * Open a record store associated with the named MIDlet suite.
0358:             * The MIDlet suite is identified by MIDlet vendor and MIDlet
0359:             * name.  Access is granted only if the authorization mode of the
0360:             * RecordStore allows access by the current MIDlet suite.  Access
0361:             * is limited by the authorization mode set when the record store
0362:             * was created:
0363:             *
0364:             * <ul>
0365:             * <li><code>AUTHMODE_PRIVATE</code> - Succeeds only if vendorName
0366:             *          and suiteName identify the current MIDlet suite; this
0367:             *          case behaves identically to
0368:             *          <code>openRecordStore(recordStoreName,
0369:             *          createIfNecessary)</code>.</li>
0370:             * <li><code>AUTHMODE_ANY</code> - Always succeeds.
0371:             *          Note that this makes your recordStore
0372:             *          accessible by any other MIDlet on the device. This
0373:             *          could have privacy and security issues depending on
0374:             *          the data being shared. Please use carefully.
0375:             *          Untrusted MIDlet suites are allowed to share data but
0376:             *          this is not recommended. The authenticity of the
0377:             *          origin of untrusted MIDlet suites cannot be verified
0378:             *          so shared data may be used unscrupulously.</li>
0379:             * </ul>
0380:             *
0381:             * <p> If this method is called by a MIDlet when the record store
0382:             * is already open by a MIDlet in the MIDlet suite, this method
0383:             * returns a reference to the same RecordStore object.</p>
0384:             *
0385:             * <p> If a MIDlet calls this method to open a record store from
0386:             * its own suite, the behavior is identical to calling:
0387:             * <code>{@link #openRecordStore(String, boolean)
0388:             * openRecordStore(recordStoreName, false)}</code></p>
0389:             *
0390:             * @param recordStoreName the MIDlet suite unique name for the
0391:             *          record store, consisting of between one and 32 Unicode
0392:             *          characters inclusive.
0393:             * @param vendorName the vendor of the owning MIDlet suite
0394:             * @param suiteName the name of the MIDlet suite
0395:             *
0396:             * @return <code>RecordStore</code> object for the record store
0397:             *
0398:             * @exception RecordStoreException if a record store-related
0399:             *          exception occurred
0400:             * @exception RecordStoreNotFoundException if the record store
0401:             *          could not be found
0402:             * @exception SecurityException if this MIDlet Suite is not
0403:             *          allowed to open the specified RecordStore.
0404:             * @exception IllegalArgumentException if recordStoreName is
0405:             *          invalid
0406:             */
0407:            public static RecordStore openRecordStore(String recordStoreName,
0408:                    String vendorName, String suiteName)
0409:                    throws RecordStoreException, RecordStoreNotFoundException {
0410:
0411:                int currentID = MIDletStateHandler.getMidletStateHandler()
0412:                        .getMIDletSuite().getID();
0413:                int id;
0414:                RecordStore recordStore;
0415:
0416:                if (vendorName == null || suiteName == null) {
0417:                    throw new IllegalArgumentException("vendorName and "
0418:                            + "suiteName must be " + "non null");
0419:                }
0420:
0421:                if (recordStoreName.length() > 32
0422:                        || recordStoreName.length() == 0) {
0423:                    throw new IllegalArgumentException();
0424:                }
0425:
0426:                id = MIDletSuiteStorage.getSuiteID(vendorName, suiteName);
0427:
0428:                if (id == MIDletSuite.UNUSED_SUITE_ID) {
0429:                    throw new RecordStoreNotFoundException();
0430:                }
0431:
0432:                recordStore = doOpen(id, recordStoreName, false);
0433:                if ((currentID != id)
0434:                        && (recordStore.peer.getAuthMode() == AUTHMODE_PRIVATE)) {
0435:                    recordStore.closeRecordStore();
0436:                    throw new SecurityException();
0437:                }
0438:
0439:                return recordStore;
0440:            }
0441:
0442:            /**
0443:             * Authorization to allow access only to the current MIDlet
0444:             * suite. AUTHMODE_PRIVATE has a value of 0.
0445:             */
0446:            public final static int AUTHMODE_PRIVATE = 0;
0447:
0448:            /**
0449:             * Authorization to allow access to any MIDlet
0450:             * suites. AUTHMODE_ANY has a value of 1.
0451:             */
0452:            public final static int AUTHMODE_ANY = 1;
0453:
0454:            /**
0455:             * Changes the access mode for this RecordStore. The authorization
0456:             * mode choices are:
0457:             *
0458:             * <ul>
0459:             * <li><code>AUTHMODE_PRIVATE</code> - Only allows the MIDlet
0460:             *          suite that created the RecordStore to access it. This
0461:             *          case behaves identically to
0462:             *          <code>openRecordStore(recordStoreName,
0463:             *          createIfNecessary)</code>.</li>
0464:             * <li><code>AUTHMODE_ANY</code> - Allows any MIDlet to access the
0465:             *          RecordStore. Note that this makes your recordStore
0466:             *          accessible by any other MIDlet on the device. This
0467:             *          could have privacy and security issues depending on
0468:             *          the data being shared. Please use carefully.</li>
0469:             * </ul>
0470:             *
0471:             * <p>The owning MIDlet suite may always access the RecordStore and
0472:             * always has access to write and update the store. Only the
0473:             * owning MIDlet suite can change the mode of a RecordStore.</p>
0474:             *
0475:             * @param authmode the mode under which to check or create access.
0476:             *          Must be one of AUTHMODE_PRIVATE or AUTHMODE_ANY.
0477:             * @param writable true if the RecordStore is to be writable by
0478:             *          other MIDlet suites that are granted access
0479:             *
0480:             * @exception RecordStoreException if a record store-related
0481:             *          exception occurred
0482:             * @exception SecurityException if this MIDlet Suite is not
0483:             *          allowed to change the mode of the RecordStore
0484:             * @exception IllegalArgumentException if authmode is invalid
0485:             */
0486:            public void setMode(int authmode, boolean writable)
0487:                    throws RecordStoreException {
0488:                checkOpen();
0489:                if (!isRecordStoreOwner()) {
0490:                    throw new SecurityException("not the owner");
0491:                } else if (authmode != AUTHMODE_PRIVATE
0492:                        && authmode != AUTHMODE_ANY) {
0493:                    throw new IllegalArgumentException();
0494:                }
0495:
0496:                peer.setMode(authmode, writable);
0497:            }
0498:
0499:            /**
0500:             * This method is called when the MIDlet requests to have the
0501:             * record store closed. Note that the record store will not
0502:             * actually be closed until closeRecordStore() is called as many
0503:             * times as openRecordStore() was called. In other words, the
0504:             * MIDlet needs to make a balanced number of close calls as open
0505:             * calls before the record store is closed.
0506:             *
0507:             * <p>When the record store is closed, all listeners are removed
0508:             * and all RecordEnumerations associated with it become invalid.
0509:             * If the MIDlet attempts to perform
0510:             * operations on the RecordStore object after it has been closed,
0511:             * the methods will throw a RecordStoreNotOpenException.
0512:             *
0513:             * @exception RecordStoreNotOpenException if the record store is
0514:             *          not open
0515:             * @exception RecordStoreException if a different record
0516:             *          store-related exception occurred
0517:             */
0518:            public void closeRecordStore() throws RecordStoreNotOpenException,
0519:                    RecordStoreException {
0520:
0521:                checkOpen();
0522:                synchronized (openRecordStores) {
0523:
0524:                    if (--opencount <= 0) { // free stuff - final close
0525:                        openRecordStores.removeElement(this );
0526:                        peer.closeRecordStore();
0527:
0528:                        // mark this RecordStore as closed
0529:                        peer = null;
0530:                    }
0531:                }
0532:            }
0533:
0534:            /**
0535:             * Returns an array of the names of record stores owned by the
0536:             * MIDlet suite. Note that if the MIDlet suite does not
0537:             * have any record stores, this function will return null.
0538:             *
0539:             * The order of RecordStore names returned is implementation
0540:             * dependent.
0541:             *
0542:             * @return array of the names of record stores owned by the
0543:             * MIDlet suite. Note that if the MIDlet suite does not
0544:             * have any record stores, this function will return null.
0545:             */
0546:            public static String[] listRecordStores() {
0547:                MIDletSuite currentSuite = MIDletStateHandler
0548:                        .getMidletStateHandler().getMIDletSuite();
0549:
0550:                if (currentSuite == null) {
0551:                    return null;
0552:                }
0553:
0554:                // static calls synchronize on openRecordStores
0555:                synchronized (openRecordStores) {
0556:                    return RecordStoreImpl.listRecordStores(classSecurityToken,
0557:                            currentSuite.getID());
0558:                }
0559:            }
0560:
0561:            /**
0562:             * Returns the name of this RecordStore.
0563:             *
0564:             * @return the name of this RecordStore
0565:             *
0566:             * @exception RecordStoreNotOpenException if the record store is not open
0567:             */
0568:            public String getName() throws RecordStoreNotOpenException {
0569:                checkOpen();
0570:                return recordStoreName;
0571:            }
0572:
0573:            /**
0574:             * Each time a record store is modified (by
0575:             * <code>addRecord</code>, <code>setRecord</code>, or
0576:             * <code>deleteRecord</code> methods) its <em>version</em> is
0577:             * incremented. This can be used by MIDlets to quickly tell if
0578:             * anything has been modified.
0579:             *
0580:             * The initial version number is implementation dependent.
0581:             * The increment is a positive integer greater than 0.
0582:             * The version number increases only when the RecordStore is updated.
0583:             *
0584:             * The increment value need not be constant and may vary with each
0585:             * update.
0586:             *
0587:             * @return the current record store version
0588:             *
0589:             * @exception RecordStoreNotOpenException if the record store is
0590:             *            not open
0591:             */
0592:            public int getVersion() throws RecordStoreNotOpenException {
0593:                checkOpen();
0594:                return peer.getVersion();
0595:            }
0596:
0597:            /**
0598:             * Returns the number of records currently in the record store.
0599:             *
0600:             * @return the number of records currently in the record store
0601:             *
0602:             * @exception RecordStoreNotOpenException if the record store is
0603:             *          not open
0604:             */
0605:            public int getNumRecords() throws RecordStoreNotOpenException {
0606:                checkOpen();
0607:                return peer.getNumRecords();
0608:            }
0609:
0610:            /**
0611:             * Returns the amount of space, in bytes, that the record store
0612:             * occupies. The size returned includes any overhead associated
0613:             * with the implementation, such as the data structures
0614:             * used to hold the state of the record store, etc.
0615:             *
0616:             * @exception RecordStoreNotOpenException if the record store is
0617:             *          not open
0618:             *
0619:             * @return the size of the record store in bytes
0620:             */
0621:            public int getSize() throws RecordStoreNotOpenException {
0622:                checkOpen();
0623:                return peer.getSize();
0624:            }
0625:
0626:            /**
0627:             * Returns the amount of additional room (in bytes) available for
0628:             * this record store to grow. Note that this is not necessarily
0629:             * the amount of extra MIDlet-level data which can be stored,
0630:             * as implementations may store additional data structures with
0631:             * each record to support integration with native applications,
0632:             * synchronization, etc.
0633:             *
0634:             * @exception RecordStoreNotOpenException if the record store is
0635:             *          not open
0636:             *
0637:             * @return the amount of additional room (in bytes) available for
0638:             *          this record store to grow
0639:             */
0640:            public int getSizeAvailable() throws RecordStoreNotOpenException {
0641:                checkOpen();
0642:                int sizeAvailable = peer.getSizeAvailable();
0643:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0644:                    Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
0645:                            "getSizeAvailable() = " + sizeAvailable);
0646:                }
0647:                return sizeAvailable;
0648:            }
0649:
0650:            /**
0651:             * Returns the last time the record store was modified, in the
0652:             * format used by System.currentTimeMillis().
0653:             *
0654:             * @return the last time the record store was modified, in the
0655:             *          format used by System.currentTimeMillis()
0656:             *
0657:             * @exception RecordStoreNotOpenException if the record store is
0658:             *          not open
0659:             */
0660:            public long getLastModified() throws RecordStoreNotOpenException {
0661:                checkOpen();
0662:                return peer.getLastModified();
0663:            }
0664:
0665:            /**
0666:             * Adds the specified RecordListener. If the specified listener
0667:             * is already registered, it will not be added a second time.
0668:             * When a record store is closed, all listeners are removed.
0669:             *
0670:             * @param listener the RecordChangedListener
0671:             * @see #removeRecordListener
0672:             */
0673:            public void addRecordListener(RecordListener listener) {
0674:                synchronized (recordListener) {
0675:                    if (!recordListener.contains(listener)) {
0676:                        recordListener.addElement(listener);
0677:                    }
0678:                }
0679:            }
0680:
0681:            /**
0682:             * Removes the specified RecordListener. If the specified listener
0683:             * is not registered, this method does nothing.
0684:             *
0685:             * @param listener the RecordChangedListener
0686:             * @see #addRecordListener
0687:             */
0688:            public void removeRecordListener(RecordListener listener) {
0689:                synchronized (recordListener) {
0690:                    recordListener.removeElement(listener);
0691:                }
0692:            }
0693:
0694:            /**
0695:             * Returns the recordId of the next record to be added to the
0696:             * record store. This can be useful for setting up pseudo-relational
0697:             * relationships. That is, if you have two or more
0698:             * record stores whose records need to refer to one another, you can
0699:             * predetermine the recordIds of the records that will be created
0700:             * in one record store, before populating the fields and allocating
0701:             * the record in another record store. Note that the recordId returned
0702:             * is only valid while the record store remains open and until a call
0703:             * to <code>addRecord()</code>.
0704:             *
0705:             * @return the recordId of the next record to be added to the
0706:             *          record store
0707:             *
0708:             * @exception RecordStoreNotOpenException if the record store is
0709:             *          not open
0710:             * @exception RecordStoreException if a different record
0711:             *          store-related exception occurred
0712:             */
0713:            public int getNextRecordID() throws RecordStoreNotOpenException,
0714:                    RecordStoreException {
0715:
0716:                checkOpen();
0717:                return peer.getNextRecordID();
0718:            }
0719:
0720:            /**
0721:             * Adds a new record to the record store. The recordId for this
0722:             * new record is returned. This is a blocking atomic operation.
0723:             * The record is written to persistent storage before the
0724:             * method returns.
0725:             *
0726:             * @param data the data to be stored in this record. If the record
0727:             *          is to have zero-length data (no data), this parameter may be
0728:             *          null.
0729:             * @param offset the index into the data buffer of the first
0730:             *          relevant byte for this record
0731:             * @param numBytes the number of bytes of the data buffer to use
0732:             *          for this record (may be zero)
0733:             *
0734:             * @return the recordId for the new record
0735:             *
0736:             * @exception RecordStoreNotOpenException if the record store is
0737:             *          not open
0738:             * @exception RecordStoreException if a different record
0739:             *          store-related exception occurred
0740:             * @exception RecordStoreFullException if the operation cannot be
0741:             *          completed because the record store has no more room
0742:             * @exception SecurityException if the MIDlet has read-only access
0743:             *          to the RecordStore
0744:             */
0745:            public int addRecord(byte[] data, int offset, int numBytes)
0746:                    throws RecordStoreNotOpenException, RecordStoreException,
0747:                    RecordStoreFullException {
0748:                checkOpen();
0749:                checkWritable();
0750:
0751:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0752:                    Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
0753:                            "addRecord(data=" + data + ", offset=" + offset
0754:                                    + ", numBytes=" + numBytes + ")");
0755:                }
0756:
0757:                // validate parameters
0758:                if ((data == null) && (numBytes > 0)) {
0759:                    throw new NullPointerException("illegal arguments: null "
0760:                            + "data,  numBytes > 0");
0761:                }
0762:                if ((offset < 0)
0763:                        || (numBytes < 0)
0764:                        || ((data != null) && (offset + numBytes > data.length))) {
0765:                    throw new ArrayIndexOutOfBoundsException();
0766:                }
0767:
0768:                int recordId = peer.addRecord(data, offset, numBytes);
0769:
0770:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0771:                    Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
0772:                            "recordId = " + recordId);
0773:                }
0774:
0775:                // tell listeners a record has been added
0776:                notifyRecordAddedListeners(recordId);
0777:
0778:                return recordId;
0779:            }
0780:
0781:            /**
0782:             * The record is deleted from the record store. The recordId for
0783:             * this record is NOT reused.
0784:             *
0785:             * @param recordId the ID of the record to delete
0786:             *
0787:             * @exception RecordStoreNotOpenException if the record store is
0788:             *          not open
0789:             * @exception InvalidRecordIDException if the recordId is invalid
0790:             * @exception RecordStoreException if a general record store
0791:             *          exception occurs
0792:             * @exception SecurityException if the MIDlet has read-only access
0793:             *          to the RecordStore
0794:             */
0795:            public void deleteRecord(int recordId)
0796:                    throws RecordStoreNotOpenException,
0797:                    InvalidRecordIDException, RecordStoreException {
0798:
0799:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0800:                    Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
0801:                            "deleteRecord(" + recordId + ")");
0802:                }
0803:                checkOpen();
0804:                checkWritable();
0805:                peer.deleteRecord(recordId);
0806:
0807:                // tell listeners a record has been deleted
0808:                notifyRecordDeletedListeners(recordId);
0809:            }
0810:
0811:            /**
0812:             * Returns the size (in bytes) of the MIDlet data available
0813:             * in the given record.
0814:             *
0815:             * @param recordId the ID of the record to use in this operation
0816:             *
0817:             * @return the size (in bytes) of the MIDlet data available
0818:             *          in the given record
0819:             *
0820:             * @exception RecordStoreNotOpenException if the record store is
0821:             *          not open
0822:             * @exception InvalidRecordIDException if the recordId is invalid
0823:             * @exception RecordStoreException if a general record store
0824:             *          exception occurs
0825:             */
0826:            public int getRecordSize(int recordId)
0827:                    throws RecordStoreNotOpenException,
0828:                    InvalidRecordIDException, RecordStoreException {
0829:                checkOpen();
0830:                int size = peer.getRecordSize(recordId);
0831:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0832:                    Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
0833:                            "getSize(" + recordId + ") = " + size);
0834:                }
0835:                return size;
0836:            }
0837:
0838:            /**
0839:             * Returns the data stored in the given record.
0840:             *
0841:             * @param recordId the ID of the record to use in this operation
0842:             * @param buffer the byte array in which to copy the data
0843:             * @param offset the index into the buffer in which to start copying
0844:             *
0845:             * @exception RecordStoreNotOpenException if the record store is
0846:             *          not open
0847:             * @exception InvalidRecordIDException if the recordId is invalid
0848:             * @exception RecordStoreException if a general record store
0849:             *          exception occurs
0850:             * @exception ArrayIndexOutOfBoundsException if the record is
0851:             *          larger than the buffer supplied
0852:             *
0853:             * @return the number of bytes copied into the buffer, starting at
0854:             *          index <code>offset</code>
0855:             * @see #setRecord
0856:             */
0857:            public int getRecord(int recordId, byte[] buffer, int offset)
0858:                    throws RecordStoreNotOpenException,
0859:                    InvalidRecordIDException, RecordStoreException {
0860:                checkOpen();
0861:                return peer.getRecord(recordId, buffer, offset);
0862:            }
0863:
0864:            /**
0865:             * Returns a copy of the data stored in the given record.
0866:             *
0867:             * @param recordId the ID of the record to use in this operation
0868:             *
0869:             * @exception RecordStoreNotOpenException if the record store is
0870:             *          not open
0871:             * @exception InvalidRecordIDException if the recordId is invalid
0872:             * @exception RecordStoreException if a general record store
0873:             *          exception occurs
0874:             *
0875:             * @return the data stored in the given record. Note that if the
0876:             *          record has no data, this method will return null.
0877:             * @see #setRecord
0878:             */
0879:            public byte[] getRecord(int recordId)
0880:                    throws RecordStoreNotOpenException,
0881:                    InvalidRecordIDException, RecordStoreException {
0882:                checkOpen();
0883:                return peer.getRecord(recordId);
0884:            }
0885:
0886:            /**
0887:             * Sets the data in the given record to that passed in. After
0888:             * this method returns, a call to <code>getRecord(int recordId)</code>
0889:             * will return an array of numBytes size containing the data
0890:             * supplied here.
0891:             *
0892:             * @param recordId the ID of the record to use in this operation
0893:             * @param newData the new data to store in the record
0894:             * @param offset the index into the data buffer of the first
0895:             *          relevant byte for this record
0896:             * @param numBytes the number of bytes of the data buffer to use
0897:             *          for this record
0898:             *
0899:             * @exception RecordStoreNotOpenException if the record store is
0900:             *          not open
0901:             * @exception InvalidRecordIDException if the recordId is invalid
0902:             * @exception RecordStoreException if a general record store
0903:             *          exception occurs
0904:             * @exception RecordStoreFullException if the operation cannot be
0905:             *          completed because the record store has no more room
0906:             * @exception SecurityException if the MIDlet has read-only access
0907:             *          to the RecordStore
0908:             * @see #getRecord
0909:             */
0910:            public void setRecord(int recordId, byte[] newData, int offset,
0911:                    int numBytes) throws RecordStoreNotOpenException,
0912:                    InvalidRecordIDException, RecordStoreException,
0913:                    RecordStoreFullException {
0914:
0915:                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
0916:                    Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
0917:                            "setRecord(" + recordId + ")");
0918:                }
0919:
0920:                // validate parameters
0921:                if ((newData == null) && (numBytes > 0)) {
0922:                    throw new NullPointerException("illegal arguments: null "
0923:                            + "data,  numBytes > 0");
0924:                }
0925:                if ((offset < 0)
0926:                        || (numBytes < 0)
0927:                        || ((newData != null) && (offset + numBytes > newData.length))) {
0928:                    throw new ArrayIndexOutOfBoundsException();
0929:                }
0930:
0931:                checkOpen();
0932:                checkWritable();
0933:
0934:                peer.setRecord(recordId, newData, offset, numBytes);
0935:
0936:                // update database header info and sync to file
0937:                notifyRecordChangedListeners(recordId);
0938:            }
0939:
0940:            /**
0941:             * Returns an enumeration for traversing a set of records in the
0942:             * record store in an optionally specified order.<p>
0943:             *
0944:             * The filter, if non-null, will be used to determine what
0945:             * subset of the record store records will be used.<p>
0946:             *
0947:             * The comparator, if non-null, will be used to determine the
0948:             * order in which the records are returned.<p>
0949:             *
0950:             * If both the filter and comparator is null, the enumeration
0951:             * will traverse all records in the record store in an undefined
0952:             * order. This is the most efficient way to traverse all of the
0953:             * records in a record store.  If a filter is used with a null
0954:             * comparator, the enumeration will traverse the filtered records
0955:             * in an undefined order.
0956:             *
0957:             * The first call to <code>RecordEnumeration.nextRecord()</code>
0958:             * returns the record data from the first record in the sequence.
0959:             * Subsequent calls to <code>RecordEnumeration.nextRecord()</code>
0960:             * return the next consecutive record's data. To return the record
0961:             * data from the previous consecutive from any
0962:             * given point in the enumeration, call <code>previousRecord()</code>.
0963:             * On the other hand, if after creation the first call is to
0964:             * <code>previousRecord()</code>, the record data of the last element
0965:             * of the enumeration will be returned. Each subsequent call to
0966:             * <code>previousRecord()</code> will step backwards through the
0967:             * sequence.
0968:             *
0969:             * @param filter if non-null, will be used to determine what
0970:             *          subset of the record store records will be used
0971:             * @param comparator if non-null, will be used to determine the
0972:             *          order in which the records are returned
0973:             * @param keepUpdated if true, the enumerator will keep its enumeration
0974:             *          current with any changes in the records of the record
0975:             *          store. Use with caution as there are possible
0976:             *          performance consequences. If false the enumeration
0977:             *          will not be kept current and may return recordIds for
0978:             *          records that have been deleted or miss records that
0979:             *          are added later. It may also return records out of
0980:             *          order that have been modified after the enumeration
0981:             *          was built. Note that any changes to records in the
0982:             *          record store are accurately reflected when the record
0983:             *          is later retrieved, either directly or through the
0984:             *          enumeration. The thing that is risked by setting this
0985:             *          parameter false is the filtering and sorting order of
0986:             *          the enumeration when records are modified, added, or
0987:             *          deleted.
0988:             *
0989:             * @exception RecordStoreNotOpenException if the record store is
0990:             *          not open
0991:             *
0992:             * @see RecordEnumeration#rebuild
0993:             *
0994:             * @return an enumeration for traversing a set of records in the
0995:             *          record store in an optionally specified order
0996:             */
0997:            public RecordEnumeration enumerateRecords(RecordFilter filter,
0998:                    RecordComparator comparator, boolean keepUpdated)
0999:                    throws RecordStoreNotOpenException {
1000:
1001:                checkOpen();
1002:                return new RecordEnumerationImpl(this , filter, comparator,
1003:                        keepUpdated);
1004:            }
1005:
1006:            /**
1007:             * Get the open status of this record store.  (Package accessible
1008:             * for use by record enumeration objects.)
1009:             *
1010:             * @return true if record store is open, false otherwise.
1011:             */
1012:            boolean isOpen() {
1013:                synchronized (openRecordStores) {
1014:                    return (peer != null);
1015:                }
1016:            }
1017:
1018:            /**
1019:             * Returns all of the recordId's currently in the record store.
1020:             *
1021:             * @return an array of the recordId's currently in the record store
1022:             *         or null if the record store is closed.
1023:             */
1024:            int[] getRecordIDs() {
1025:                return peer.getRecordIDs();
1026:            }
1027:
1028:            /**
1029:             * Throws a RecordStoreNotOpenException if the RecordStore
1030:             * is closed.  (A RecordStore is closed if the RecordStoreFile
1031:             * instance variable <code>dbraf</code> is null.
1032:             *
1033:             * @exception RecordStoreNotOpenException if RecordStore is closed
1034:             */
1035:            private void checkOpen() throws RecordStoreNotOpenException {
1036:                if (!isOpen()) {
1037:                    throw new RecordStoreNotOpenException();
1038:                }
1039:            }
1040:
1041:            /**
1042:             * Internal method to determine if writing to this record store
1043:             * is allowed for the calling MIDlet.  Returns <code>true</code>
1044:             * if <code>isRecordStoreOwner()</code> returns <code>true</code> or
1045:             * <code>dbAuthMode</code> == 1 when <code>isRecordStoreOwner()</code>
1046:             * returns <code>false</code>.
1047:             *
1048:             * @exception SecurityException if the MIDlet has read-only access
1049:             *          to the RecordStore
1050:             */
1051:            private void checkWritable() {
1052:                if (isRecordStoreOwner()) {
1053:                    return;
1054:                } else {
1055:                    if (peer.getAuthMode() == AUTHMODE_ANY) { // Read-Write mode
1056:                        return;
1057:                    }
1058:                }
1059:
1060:                throw new SecurityException("no write access");
1061:            }
1062:
1063:            /**
1064:             * Internal method to check record store owner vs. the vendor and suite
1065:             * of the currently running midlet
1066:             *
1067:             * @return <code>true</code> if vendor and suite name both match,
1068:             * <code>false</code> otherwise
1069:             */
1070:            private boolean isRecordStoreOwner() {
1071:                int currentId = MIDletStateHandler.getMidletStateHandler()
1072:                        .getMIDletSuite().getID();
1073:
1074:                return (suiteId == currentId);
1075:            }
1076:
1077:            /**
1078:             * Notifies all registered listeners that a record changed.
1079:             *
1080:             * @param recordId the record id of the changed record.
1081:             */
1082:            private void notifyRecordChangedListeners(int recordId) {
1083:                synchronized (recordListener) {
1084:
1085:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
1086:                        Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
1087:                                "notify Change # listener = "
1088:                                        + recordListener.size());
1089:                    }
1090:                    int numListeners = recordListener.size();
1091:                    for (int i = 0; i < numListeners; i++) {
1092:                        RecordListener rl = (RecordListener) recordListener
1093:                                .elementAt(i);
1094:                        rl.recordChanged(this , recordId);
1095:                    }
1096:                }
1097:            }
1098:
1099:            /**
1100:             * Notifies all registered listeners that a record was added.
1101:             *
1102:             * @param recordId the record id of the added record.
1103:             */
1104:            private void notifyRecordAddedListeners(int recordId) {
1105:                synchronized (recordListener) {
1106:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
1107:                        Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
1108:                                "notify Add # listener = "
1109:                                        + recordListener.size());
1110:                    }
1111:                    int numListeners = recordListener.size();
1112:                    for (int i = 0; i < numListeners; i++) {
1113:                        RecordListener rl = (RecordListener) recordListener
1114:                                .elementAt(i);
1115:                        rl.recordAdded(this , recordId);
1116:                    }
1117:                }
1118:            }
1119:
1120:            /**
1121:             * Notifies all registered listeners that a record was deleted.
1122:             *
1123:             * @param recordId the record id of the changed record.
1124:             */
1125:            private void notifyRecordDeletedListeners(int recordId) {
1126:                synchronized (recordListener) {
1127:                    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
1128:                        Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
1129:                                "notify Delete # listener = "
1130:                                        + recordListener.size());
1131:                    }
1132:                    int numListeners = recordListener.size();
1133:                    for (int i = 0; i < numListeners; i++) {
1134:                        RecordListener rl = (RecordListener) recordListener
1135:                                .elementAt(i);
1136:                        rl.recordDeleted(this , recordId);
1137:                    }
1138:                }
1139:            }
1140:
1141:            /**
1142:             * Internal method to open (and possibly create) a record store associated
1143:             * with the given MIDlet suite. If this method is called by a MIDlet when
1144:             * the record store is already open by a MIDlet in the MIDlet suite,
1145:             * this method returns a reference to the same RecordStoreImpl object.
1146:             *
1147:             * @param suiteId ID of the MIDlet suite that owns the record store
1148:             * @param recordStoreName the MIDlet suite unique name for the
1149:             *          record store, consisting of between one and 32 Unicode
1150:             *          characters inclusive.
1151:             * @param createIfNecessary if true, the record store will be
1152:             *          created if necessary
1153:             *
1154:             * @return <code>RecordStore</code> object for the record store
1155:             *
1156:             * @exception RecordStoreException if a record store-related
1157:             *          exception occurred
1158:             * @exception RecordStoreNotFoundException if the record store
1159:             *          could not be found
1160:             * @exception RecordStoreFullException if the operation cannot be
1161:             *          completed because the record store is full
1162:             * @exception IllegalArgumentException if
1163:             *          recordStoreName is invalid
1164:             */
1165:            private static RecordStore doOpen(int suiteId,
1166:                    String recordStoreName, boolean createIfNecessary)
1167:                    throws RecordStoreException, RecordStoreFullException,
1168:                    RecordStoreNotFoundException {
1169:
1170:                RecordStore recordStore;
1171:
1172:                if (recordStoreName.length() > 32
1173:                        || recordStoreName.length() == 0) {
1174:                    throw new IllegalArgumentException();
1175:                }
1176:
1177:                synchronized (openRecordStores) {
1178:                    // Save record store instances and ensure that there is only
1179:                    // one record store object in memory for any given record
1180:                    // store file. This is good for memory use. This is NOT safe
1181:                    // in the situation where multiple VM's may be executing code
1182:                    // concurrently. In that case, you have to sync things through
1183:                    // file locking or something similar.
1184:
1185:                    // Check the record store instance list for a db with the same name
1186:                    int size = openRecordStores.size();
1187:                    for (int n = 0; n < size; n++) {
1188:                        recordStore = (RecordStore) openRecordStores
1189:                                .elementAt(n);
1190:                        if (recordStore.suiteId == suiteId
1191:                                && recordStore.recordStoreName
1192:                                        .equals(recordStoreName)) {
1193:                            recordStore.opencount++; // increment the open count
1194:                            return recordStore; // return ref to cached record store
1195:                        }
1196:                    }
1197:
1198:                    /*
1199:                     * Record store not found in cache, so create it.
1200:                     * If createIfNecessary is FALSE and the RecordStore
1201:                     * does not exists, a RecordStoreNotFoundException is
1202:                     * thrown.
1203:                     */
1204:                    recordStore = new RecordStore(suiteId, recordStoreName);
1205:                    recordStore.peer = RecordStoreImpl.openRecordStore(
1206:                            classSecurityToken, suiteId, recordStoreName,
1207:                            createIfNecessary);
1208:
1209:                    /*
1210:                     * Now add the new record store to the cache
1211:                     */
1212:                    recordStore.opencount = 1;
1213:                    openRecordStores.addElement(recordStore);
1214:                }
1215:
1216:                return recordStore;
1217:            }
1218:
1219:            /**
1220:             * Internal method to open a record store for lock testing. When
1221:             * lock testing the record store will be obtained from the cache or
1222:             * put in the cache, this allows testing of lower level locking without
1223:             * the need to run multiple Isolates.
1224:             *
1225:             * @param recordStoreName the MIDlet suite unique name for the
1226:             *          record store, consisting of between one and 32 Unicode
1227:             *          characters inclusive.
1228:             *
1229:             * @return <code>RecordStore</code> object for the record store
1230:             *
1231:             * @exception RecordStoreException if a record store-related
1232:             *          exception occurred
1233:             * @exception RecordStoreNotFoundException if the record store
1234:             *          could not be found
1235:             * @exception RecordStoreFullException if the operation cannot be
1236:             *          completed because the record store is full
1237:             * @exception IllegalArgumentException if
1238:             *          recordStoreName is invalid
1239:             */
1240:            static RecordStore openForLockTesting(String recordStoreName)
1241:                    throws RecordStoreException, RecordStoreFullException,
1242:                    RecordStoreNotFoundException {
1243:
1244:                RecordStore recordStore;
1245:                int suiteId = MIDletStateHandler.getMidletStateHandler()
1246:                        .getMIDletSuite().getID();
1247:
1248:                recordStore = new RecordStore(suiteId, recordStoreName);
1249:                recordStore.peer = RecordStoreImpl.openRecordStore(
1250:                        classSecurityToken, suiteId, recordStoreName, false);
1251:                recordStore.opencount = 1;
1252:                return recordStore;
1253:            }
1254:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.