FileDocCategorySizeDatePackage
RecordStore.javaAPI DocphoneME MR2 API (J2ME)49326Wed May 02 18:00:12 BST 2007javax.microedition.rms

RecordStore

public class RecordStore extends Object
A class representing a record store. A record store consists of a collection of records which will remain persistent across multiple invocations of the MIDlet. The platform is responsible for making its best effort to maintain the integrity of the MIDlet's record stores throughout the normal use of the platform, including reboots, battery changes, etc.

Record stores are created in platform-dependent locations, which are not exposed to the MIDlets. The naming space for record stores is controlled at the MIDlet suite granularity. MIDlets within a MIDlet suite are allowed to create multiple record stores, as long as they are each given different names. When a MIDlet suite is removed from a platform all the record stores associated with its MIDlets will also be removed. MIDlets within a MIDlet suite can access each other's record stores directly. New APIs in MIDP allow for the explicit sharing of record stores if the MIDlet creating the RecordStore chooses to give such permission.

Sharing is accomplished through the ability to name a RecordStore created by another MIDlet suite.

RecordStores are uniquely named using the unique name of the MIDlet suite plus the name of the RecordStore. MIDlet suites are identified by the MIDlet-Vendor and MIDlet-Name attributes from the application descriptor.

Access controls are defined when RecordStores to be shared are created. Access controls are enforced when RecordStores are opened. The access modes allow private use or shareable with any other MIDlet suite.

Record store names are case sensitive and may consist of any combination of between one and 32 Unicode characters inclusive. Record store names must be unique within the scope of a given MIDlet suite. In other words, MIDlets within a MIDlet suite are not allowed to create more than one record store with the same name, however a MIDlet in one MIDlet suite is allowed to have a record store with the same name as a MIDlet in another MIDlet suite. In that case, the record stores are still distinct and separate.

No locking operations are provided in this API. Record store implementations ensure that all individual record store operations are atomic, synchronous, and serialized, so no corruption will occur with multiple accesses. However, if a MIDlet uses multiple threads to access a record store, it is the MIDlet's responsibility to coordinate this access or unintended consequences may result. Similarly, if a platform performs transparent synchronization of a record store, it is the platform's responsibility to enforce exclusive access to the record store between the MIDlet and synchronization engine.

Records are uniquely identified within a given record store by their recordId, which is an integer value. This recordId is used as the primary key for the records. The first record created in a record store will have recordId equal to one (1). Each subsequent record added to a RecordStore will be assigned a recordId one greater than the record added before it. That is, if two records are added to a record store, and the first has a recordId of 'n', the next will have a recordId of 'n + 1'. MIDlets can create other sequences of the records in the RecordStore by using the RecordEnumeration class.

This record store uses long integers for time/date stamps, in the format used by System.currentTimeMillis(). The record store is time stamped with the last time it was modified. The record store also maintains a version number, which is an integer that is incremented for each operation that modifies the contents of the RecordStore. These are useful for synchronization engines as well as other things.

since
MIDP 1.0

Fields Summary
private static Vector
openRecordStores
cache of open RecordStore instances
private com.sun.midp.rms.RecordStoreImpl
peer
The peer that performs the real functionallity.
private String
recordStoreName
name of this record store
private int
suiteId
unique id for suite that owns this record store
private int
opencount
number of open instances of this record store
private Vector
recordListener
recordListeners of this record store
private static com.sun.midp.security.SecurityToken
classSecurityToken
The security token necessary to use RecordStoreImpl. This is initialized in a static initialization block.
public static final int
AUTHMODE_PRIVATE
Authorization to allow access only to the current MIDlet suite. AUTHMODE_PRIVATE has a value of 0.
public static final int
AUTHMODE_ANY
Authorization to allow access to any MIDlet suites. AUTHMODE_ANY has a value of 1.
Constructors Summary
private RecordStore(int suiteId, String recordStoreName)
MIDlets must use openRecordStore() to get a RecordStore object. If this constructor is not declared (as private scope), Javadoc (and Java) will assume a public constructor.

param
suiteId the ID of the suite that owns this record store
param
recordStoreName the MIDlet suite unique name for the record store, consisting of between one and 32 Unicode characters inclusive.


    /*
     * RecordStore Constructors
     */

                                                                                     
         
	this.suiteId = suiteId;
	this.recordStoreName = recordStoreName;
        recordListener = new java.util.Vector(3);
    
Methods Summary
public intaddRecord(byte[] data, int offset, int numBytes)
Adds a new record to the record store. The recordId for this new record is returned. This is a blocking atomic operation. The record is written to persistent storage before the method returns.

param
data the data to be stored in this record. If the record is to have zero-length data (no data), this parameter may be null.
param
offset the index into the data buffer of the first relevant byte for this record
param
numBytes the number of bytes of the data buffer to use for this record (may be zero)
return
the recordId for the new record
exception
RecordStoreNotOpenException if the record store is not open
exception
RecordStoreException if a different record store-related exception occurred
exception
RecordStoreFullException if the operation cannot be completed because the record store has no more room
exception
SecurityException if the MIDlet has read-only access to the RecordStore

	checkOpen();
        checkWritable();

	if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
	    Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
			   "addRecord(data=" + data +
			   ", offset=" + offset +
			   ", numBytes=" + numBytes + ")");
	}

	// validate parameters
	if ((data == null) && (numBytes > 0)) {
	    throw new NullPointerException("illegal arguments: null " +
					   "data,  numBytes > 0");
	}
	if ((offset < 0) || (numBytes < 0) ||
	    ((data != null) && (offset + numBytes > data.length))) {
	    throw new ArrayIndexOutOfBoundsException();
	}

        int recordId = peer.addRecord(data, offset, numBytes);

	if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
	    Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
			   "recordId = " + recordId);
	}

	// tell listeners a record has been added
	notifyRecordAddedListeners(recordId);

	return recordId;
    
public voidaddRecordListener(RecordListener listener)
Adds the specified RecordListener. If the specified listener is already registered, it will not be added a second time. When a record store is closed, all listeners are removed.

param
listener the RecordChangedListener
see
#removeRecordListener

        synchronized (recordListener) {
	    if (!recordListener.contains(listener)) {
		recordListener.addElement(listener);
	    }
	}
    
private voidcheckOpen()
Throws a RecordStoreNotOpenException if the RecordStore is closed. (A RecordStore is closed if the RecordStoreFile instance variable dbraf is null.

exception
RecordStoreNotOpenException if RecordStore is closed

        if (! isOpen()) {
            throw new RecordStoreNotOpenException();
        }
    
private voidcheckWritable()
Internal method to determine if writing to this record store is allowed for the calling MIDlet. Returns true if isRecordStoreOwner() returns true or dbAuthMode == 1 when isRecordStoreOwner() returns false.

exception
SecurityException if the MIDlet has read-only access to the RecordStore

        if (isRecordStoreOwner()) {
            return;
        } else {
            if (peer.getAuthMode() == AUTHMODE_ANY) { // Read-Write mode
                return;
            }
        }

        throw new SecurityException("no write access");
    
public voidcloseRecordStore()
This method is called when the MIDlet requests to have the record store closed. Note that the record store will not actually be closed until closeRecordStore() is called as many times as openRecordStore() was called. In other words, the MIDlet needs to make a balanced number of close calls as open calls before the record store is closed.

When the record store is closed, all listeners are removed and all RecordEnumerations associated with it become invalid. If the MIDlet attempts to perform operations on the RecordStore object after it has been closed, the methods will throw a RecordStoreNotOpenException.

exception
RecordStoreNotOpenException if the record store is not open
exception
RecordStoreException if a different record store-related exception occurred


	checkOpen();
	synchronized (openRecordStores) {

	    if (--opencount <= 0) {  // free stuff - final close
		openRecordStores.removeElement(this);
		peer.closeRecordStore();

		// mark this RecordStore as closed
		peer = null;
	    }
	}
    
public voiddeleteRecord(int recordId)
The record is deleted from the record store. The recordId for this record is NOT reused.

param
recordId the ID of the record to delete
exception
RecordStoreNotOpenException if the record store is not open
exception
InvalidRecordIDException if the recordId is invalid
exception
RecordStoreException if a general record store exception occurs
exception
SecurityException if the MIDlet has read-only access to the RecordStore


	if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
	    Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
			   "deleteRecord(" + recordId + ")");
	}
	checkOpen();
        checkWritable();
        peer.deleteRecord(recordId);

	// tell listeners a record has been deleted
	notifyRecordDeletedListeners(recordId);
    
public static voiddeleteRecordStore(java.lang.String recordStoreName)
Deletes the named record store. MIDlet suites are only allowed to delete their own record stores. If the named record store is open (by a MIDlet in this suite or a MIDlet in a different MIDlet suite) when this method is called, a RecordStoreException will be thrown. If the named record store does not exist a RecordStoreNotFoundException will be thrown. Calling this method does NOT result in recordDeleted calls to any registered listeners of this RecordStore.

param
recordStoreName the MIDlet suite unique record store to delete
exception
RecordStoreException if a record store-related exception occurred
exception
RecordStoreNotFoundException if the record store could not be found

        int id = MIDletStateHandler.getMidletStateHandler().
            getMIDletSuite().getID();

        if (recordStoreName == null || recordStoreName.length() == 0) {
            throw new RecordStoreNotFoundException();
        }

        // Check the record store cache for a db with the same name
        synchronized (openRecordStores) {
            RecordStore db;
	    int size = openRecordStores.size();
	    for (int n = 0; n < size; n++) {
                db = (RecordStore)openRecordStores.elementAt(n);
                if (db.suiteId == id &&
                        db.recordStoreName.equals(recordStoreName)) {
                    // cannot delete an open record store
                    throw new RecordStoreException("deleteRecordStore error:"
                                                   + " record store is"
                                                   + " still open");
                }
            }

            // this record store is not currently open
	    RecordStoreImpl.deleteRecordStore(
                classSecurityToken, id, recordStoreName);
	}
    
private static javax.microedition.rms.RecordStoredoOpen(int suiteId, java.lang.String recordStoreName, boolean createIfNecessary)
Internal method to open (and possibly create) a record store associated with the given MIDlet suite. If this method is called by a MIDlet when the record store is already open by a MIDlet in the MIDlet suite, this method returns a reference to the same RecordStoreImpl object.

param
suiteId ID of the MIDlet suite that owns the record store
param
recordStoreName the MIDlet suite unique name for the record store, consisting of between one and 32 Unicode characters inclusive.
param
createIfNecessary if true, the record store will be created if necessary
return
RecordStore object for the record store
exception
RecordStoreException if a record store-related exception occurred
exception
RecordStoreNotFoundException if the record store could not be found
exception
RecordStoreFullException if the operation cannot be completed because the record store is full
exception
IllegalArgumentException if recordStoreName is invalid


        RecordStore recordStore;

        if (recordStoreName.length() > 32 || recordStoreName.length() == 0) {
            throw new IllegalArgumentException();
        }

        synchronized (openRecordStores) {
	    // Save record store instances and ensure that there is only
	    // one record store object in memory for any given record
	    // store file. This is good for memory use. This is NOT safe
	    // in the situation where multiple VM's may be executing code
	    // concurrently. In that case, you have to sync things through
	    // file locking or something similar.

	    // Check the record store instance list for a db with the same name
	    int size = openRecordStores.size();
	    for (int n = 0; n < size; n++) {
		recordStore = (RecordStore)openRecordStores.elementAt(n);
		if (recordStore.suiteId == suiteId &&
		    recordStore.recordStoreName.equals(recordStoreName)) {
		    recordStore.opencount++;  // increment the open count
		    return recordStore;  // return ref to cached record store
		}
	    }

	    /*
	     * Record store not found in cache, so create it.
	     * If createIfNecessary is FALSE and the RecordStore
	     * does not exists, a RecordStoreNotFoundException is
	     * thrown.
	     */
	    recordStore = new RecordStore(suiteId, recordStoreName);
	    recordStore.peer = RecordStoreImpl.openRecordStore(
                classSecurityToken, suiteId, recordStoreName,
                createIfNecessary);

	    /*
	     * Now add the new record store to the cache
	     */
	    recordStore.opencount = 1;
	    openRecordStores.addElement(recordStore);
	}

	return recordStore;
    
public RecordEnumerationenumerateRecords(RecordFilter filter, RecordComparator comparator, boolean keepUpdated)
Returns an enumeration for traversing a set of records in the record store in an optionally specified order.

The filter, if non-null, will be used to determine what subset of the record store records will be used.

The comparator, if non-null, will be used to determine the order in which the records are returned.

If both the filter and comparator is null, the enumeration will traverse all records in the record store in an undefined order. This is the most efficient way to traverse all of the records in a record store. If a filter is used with a null comparator, the enumeration will traverse the filtered records in an undefined order. The first call to RecordEnumeration.nextRecord() returns the record data from the first record in the sequence. Subsequent calls to RecordEnumeration.nextRecord() return the next consecutive record's data. To return the record data from the previous consecutive from any given point in the enumeration, call previousRecord(). On the other hand, if after creation the first call is to previousRecord(), the record data of the last element of the enumeration will be returned. Each subsequent call to previousRecord() will step backwards through the sequence.

param
filter if non-null, will be used to determine what subset of the record store records will be used
param
comparator if non-null, will be used to determine the order in which the records are returned
param
keepUpdated if true, the enumerator will keep its enumeration current with any changes in the records of the record store. Use with caution as there are possible performance consequences. If false the enumeration will not be kept current and may return recordIds for records that have been deleted or miss records that are added later. It may also return records out of order that have been modified after the enumeration was built. Note that any changes to records in the record store are accurately reflected when the record is later retrieved, either directly or through the enumeration. The thing that is risked by setting this parameter false is the filtering and sorting order of the enumeration when records are modified, added, or deleted.
exception
RecordStoreNotOpenException if the record store is not open
see
RecordEnumeration#rebuild
return
an enumeration for traversing a set of records in the record store in an optionally specified order


        checkOpen();
        return new RecordEnumerationImpl(this, filter,
          comparator, keepUpdated);
    
public longgetLastModified()
Returns the last time the record store was modified, in the format used by System.currentTimeMillis().

return
the last time the record store was modified, in the format used by System.currentTimeMillis()
exception
RecordStoreNotOpenException if the record store is not open

	checkOpen();
        return peer.getLastModified();
    
public java.lang.StringgetName()
Returns the name of this RecordStore.

return
the name of this RecordStore
exception
RecordStoreNotOpenException if the record store is not open

	checkOpen();
        return recordStoreName;
    
public intgetNextRecordID()
Returns the recordId of the next record to be added to the record store. This can be useful for setting up pseudo-relational relationships. That is, if you have two or more record stores whose records need to refer to one another, you can predetermine the recordIds of the records that will be created in one record store, before populating the fields and allocating the record in another record store. Note that the recordId returned is only valid while the record store remains open and until a call to addRecord().

return
the recordId of the next record to be added to the record store
exception
RecordStoreNotOpenException if the record store is not open
exception
RecordStoreException if a different record store-related exception occurred


	checkOpen();
        return peer.getNextRecordID();
    
public intgetNumRecords()
Returns the number of records currently in the record store.

return
the number of records currently in the record store
exception
RecordStoreNotOpenException if the record store is not open

	checkOpen();
        return peer.getNumRecords();
    
public intgetRecord(int recordId, byte[] buffer, int offset)
Returns the data stored in the given record.

param
recordId the ID of the record to use in this operation
param
buffer the byte array in which to copy the data
param
offset the index into the buffer in which to start copying
exception
RecordStoreNotOpenException if the record store is not open
exception
InvalidRecordIDException if the recordId is invalid
exception
RecordStoreException if a general record store exception occurs
exception
ArrayIndexOutOfBoundsException if the record is larger than the buffer supplied
return
the number of bytes copied into the buffer, starting at index offset
see
#setRecord

	checkOpen();
        return peer.getRecord(recordId, buffer, offset);
    
public byte[]getRecord(int recordId)
Returns a copy of the data stored in the given record.

param
recordId the ID of the record to use in this operation
exception
RecordStoreNotOpenException if the record store is not open
exception
InvalidRecordIDException if the recordId is invalid
exception
RecordStoreException if a general record store exception occurs
return
the data stored in the given record. Note that if the record has no data, this method will return null.
see
#setRecord

	checkOpen();
        return peer.getRecord(recordId);
    
int[]getRecordIDs()
Returns all of the recordId's currently in the record store.

return
an array of the recordId's currently in the record store or null if the record store is closed.

	return peer.getRecordIDs();
    
public intgetRecordSize(int recordId)
Returns the size (in bytes) of the MIDlet data available in the given record.

param
recordId the ID of the record to use in this operation
return
the size (in bytes) of the MIDlet data available in the given record
exception
RecordStoreNotOpenException if the record store is not open
exception
InvalidRecordIDException if the recordId is invalid
exception
RecordStoreException if a general record store exception occurs

	checkOpen();
	int size = peer.getRecordSize(recordId);
	if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
	    Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
			   "getSize(" + recordId + ") = " + size);
	}
        return size;
    
public intgetSize()
Returns the amount of space, in bytes, that the record store occupies. The size returned includes any overhead associated with the implementation, such as the data structures used to hold the state of the record store, etc.

exception
RecordStoreNotOpenException if the record store is not open
return
the size of the record store in bytes

	checkOpen();
        return peer.getSize();
    
public intgetSizeAvailable()
Returns the amount of additional room (in bytes) available for this record store to grow. Note that this is not necessarily the amount of extra MIDlet-level data which can be stored, as implementations may store additional data structures with each record to support integration with native applications, synchronization, etc.

exception
RecordStoreNotOpenException if the record store is not open
return
the amount of additional room (in bytes) available for this record store to grow

	checkOpen();
	int sizeAvailable = peer.getSizeAvailable();
	if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
	    Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
			   "getSizeAvailable() = " + sizeAvailable);
	}
        return sizeAvailable;
    
public intgetVersion()
Each time a record store is modified (by addRecord, setRecord, or deleteRecord methods) its version is incremented. This can be used by MIDlets to quickly tell if anything has been modified. The initial version number is implementation dependent. The increment is a positive integer greater than 0. The version number increases only when the RecordStore is updated. The increment value need not be constant and may vary with each update.

return
the current record store version
exception
RecordStoreNotOpenException if the record store is not open

	checkOpen();
        return peer.getVersion();
    
booleanisOpen()
Get the open status of this record store. (Package accessible for use by record enumeration objects.)

return
true if record store is open, false otherwise.

        synchronized (openRecordStores) {
            return (peer != null);
        }
    
private booleanisRecordStoreOwner()
Internal method to check record store owner vs. the vendor and suite of the currently running midlet

return
true if vendor and suite name both match, false otherwise

        int currentId = MIDletStateHandler.getMidletStateHandler().
            getMIDletSuite().getID();

        return (suiteId == currentId);
    
public static java.lang.String[]listRecordStores()
Returns an array of the names of record stores owned by the MIDlet suite. Note that if the MIDlet suite does not have any record stores, this function will return null. The order of RecordStore names returned is implementation dependent.

return
array of the names of record stores owned by the MIDlet suite. Note that if the MIDlet suite does not have any record stores, this function will return null.

        MIDletSuite currentSuite =
            MIDletStateHandler.getMidletStateHandler().getMIDletSuite();

        if (currentSuite == null) {
            return null;
        }

        // static calls synchronize on openRecordStores
        synchronized (openRecordStores) {
	    return RecordStoreImpl.listRecordStores(
                classSecurityToken, currentSuite.getID());
	}
    
private voidnotifyRecordAddedListeners(int recordId)
Notifies all registered listeners that a record was added.

param
recordId the record id of the added record.

        synchronized (recordListener) {
	    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
		Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
			       "notify Add # listener = " +
			       recordListener.size());
	    }
	    int numListeners = recordListener.size();
	    for (int i = 0; i < numListeners; i++) {
		RecordListener rl =
		    (RecordListener)recordListener.elementAt(i);
		rl.recordAdded(this, recordId);
	    }
	}
    
private voidnotifyRecordChangedListeners(int recordId)
Notifies all registered listeners that a record changed.

param
recordId the record id of the changed record.

        synchronized (recordListener) {

	    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
		Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
			       "notify Change # listener = " +
			       recordListener.size());
	    }
	    int numListeners = recordListener.size();
	    for (int i = 0; i < numListeners; i++) {
		RecordListener rl = (RecordListener)recordListener.elementAt(i);
		rl.recordChanged(this, recordId);
	    }
	}
    
private voidnotifyRecordDeletedListeners(int recordId)
Notifies all registered listeners that a record was deleted.

param
recordId the record id of the changed record.

        synchronized (recordListener) {
	    if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
		Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
			       "notify Delete # listener = " +
			       recordListener.size());
	    }
	    int numListeners = recordListener.size();
	    for (int i = 0; i < numListeners; i++) {
		RecordListener rl = (RecordListener)recordListener.elementAt(i);
		rl.recordDeleted(this, recordId);
	    }
	}
    
static javax.microedition.rms.RecordStoreopenForLockTesting(java.lang.String recordStoreName)
Internal method to open a record store for lock testing. When lock testing the record store will be obtained from the cache or put in the cache, this allows testing of lower level locking without the need to run multiple Isolates.

param
recordStoreName the MIDlet suite unique name for the record store, consisting of between one and 32 Unicode characters inclusive.
return
RecordStore object for the record store
exception
RecordStoreException if a record store-related exception occurred
exception
RecordStoreNotFoundException if the record store could not be found
exception
RecordStoreFullException if the operation cannot be completed because the record store is full
exception
IllegalArgumentException if recordStoreName is invalid


        RecordStore recordStore;
        int suiteId = MIDletStateHandler.getMidletStateHandler().
            getMIDletSuite().getID();

        recordStore = new RecordStore(suiteId, recordStoreName);
        recordStore.peer = RecordStoreImpl.openRecordStore(
                           classSecurityToken, suiteId, recordStoreName,
                           false);
        recordStore.opencount = 1;
        return recordStore;
    
public static javax.microedition.rms.RecordStoreopenRecordStore(java.lang.String recordStoreName, boolean createIfNecessary)
Open (and possibly create) a record store associated with the given MIDlet suite. If this method is called by a MIDlet when the record store is already open by a MIDlet in the MIDlet suite, this method returns a reference to the same RecordStore object.

param
recordStoreName the MIDlet suite unique name for the record store, consisting of between one and 32 Unicode characters inclusive.
param
createIfNecessary if true, the record store will be created if necessary
return
RecordStore object for the record store
exception
RecordStoreException if a record store-related exception occurred
exception
RecordStoreNotFoundException if the record store could not be found
exception
RecordStoreFullException if the operation cannot be completed because the record store is full
exception
IllegalArgumentException if recordStoreName is invalid


        int id = MIDletStateHandler.getMidletStateHandler().
            getMIDletSuite().getID();

	return doOpen(id, recordStoreName, createIfNecessary);
    
public static javax.microedition.rms.RecordStoreopenRecordStore(java.lang.String recordStoreName, boolean createIfNecessary, int authmode, boolean writable)
Open (and possibly create) a record store that can be shared with other MIDlet suites. The RecordStore is owned by the current MIDlet suite. The authorization mode is set when the record store is created, as follows:
  • AUTHMODE_PRIVATE - Only allows the MIDlet suite that created the RecordStore to access it. This case behaves identically to openRecordStore(recordStoreName, createIfNecessary).
  • AUTHMODE_ANY - Allows any MIDlet to access the RecordStore. Note that this makes your recordStore accessible by any other MIDlet on the device. This could have privacy and security issues depending on the data being shared. Please use carefully.

The owning MIDlet suite may always access the RecordStore and always has access to write and update the store.

If this method is called by a MIDlet when the record store is already open by a MIDlet in the MIDlet suite, this method returns a reference to the same RecordStore object.

param
recordStoreName the MIDlet suite unique name for the record store, consisting of between one and 32 Unicode characters inclusive.
param
createIfNecessary if true, the record store will be created if necessary
param
authmode the mode under which to check or create access. Must be one of AUTHMODE_PRIVATE or AUTHMODE_ANY. This argument is ignored if the RecordStore exists.
param
writable true if the RecordStore is to be writable by other MIDlet suites that are granted access. This argument is ignored if the RecordStore exists.
return
RecordStore object for the record store
exception
RecordStoreException if a record store-related exception occurred
exception
RecordStoreNotFoundException if the record store could not be found
exception
RecordStoreFullException if the operation cannot be completed because the record store is full
exception
IllegalArgumentException if authmode or recordStoreName is invalid

        RecordStore recordStore;
        boolean isExistingStorage = false;

        /*
         * First, we have to check if the record store already exists or not.
         * If we open an existing record store, "authmode" must be ignored!
         *
         */
        try {
            recordStore = openRecordStore(recordStoreName, false);
            isExistingStorage = true;
        } catch (RecordStoreNotFoundException ex)
        {
            recordStore = openRecordStore(recordStoreName, createIfNecessary);
        }

        if (!isExistingStorage) {
            try {
                recordStore.peer.setMode(authmode, writable);
            } catch (Exception e) {
                try {
                    recordStore.closeRecordStore();
                } catch (Exception ex) {
                    // do not overthrow the real exception
                }

                try {
                    int id = MIDletStateHandler.getMidletStateHandler().
                        getMIDletSuite().getID();
                    RecordStoreImpl.deleteRecordStore(
                        classSecurityToken, id, recordStoreName);
                } catch (Exception ex) {
                    // do not overthrow the real exception
                }

                if (e instanceof RecordStoreException) {
                    throw (RecordStoreException)e;
                }

                throw (RuntimeException)e;
            }
        }

        return recordStore;
    
public static javax.microedition.rms.RecordStoreopenRecordStore(java.lang.String recordStoreName, java.lang.String vendorName, java.lang.String suiteName)
Open a record store associated with the named MIDlet suite. The MIDlet suite is identified by MIDlet vendor and MIDlet name. Access is granted only if the authorization mode of the RecordStore allows access by the current MIDlet suite. Access is limited by the authorization mode set when the record store was created:
  • AUTHMODE_PRIVATE - Succeeds only if vendorName and suiteName identify the current MIDlet suite; this case behaves identically to openRecordStore(recordStoreName, createIfNecessary).
  • AUTHMODE_ANY - Always succeeds. Note that this makes your recordStore accessible by any other MIDlet on the device. This could have privacy and security issues depending on the data being shared. Please use carefully. Untrusted MIDlet suites are allowed to share data but this is not recommended. The authenticity of the origin of untrusted MIDlet suites cannot be verified so shared data may be used unscrupulously.

If this method is called by a MIDlet when the record store is already open by a MIDlet in the MIDlet suite, this method returns a reference to the same RecordStore object.

If a MIDlet calls this method to open a record store from its own suite, the behavior is identical to calling: {@link #openRecordStore(String, boolean) openRecordStore(recordStoreName, false)}

param
recordStoreName the MIDlet suite unique name for the record store, consisting of between one and 32 Unicode characters inclusive.
param
vendorName the vendor of the owning MIDlet suite
param
suiteName the name of the MIDlet suite
return
RecordStore object for the record store
exception
RecordStoreException if a record store-related exception occurred
exception
RecordStoreNotFoundException if the record store could not be found
exception
SecurityException if this MIDlet Suite is not allowed to open the specified RecordStore.
exception
IllegalArgumentException if recordStoreName is invalid


        int currentID = MIDletStateHandler.getMidletStateHandler().
            getMIDletSuite().getID();
        int id;
        RecordStore recordStore;

        if (vendorName == null || suiteName == null) {
            throw new IllegalArgumentException("vendorName and " +
                                               "suiteName must be " +
                                               "non null");
        }

        if (recordStoreName.length() > 32 || recordStoreName.length() == 0) {
            throw new IllegalArgumentException();
        }

        id = MIDletSuiteStorage.getSuiteID(vendorName, suiteName);

        if (id == MIDletSuite.UNUSED_SUITE_ID) {
            throw new RecordStoreNotFoundException();
        }

        recordStore = doOpen(id, recordStoreName, false);
        if ((currentID != id) &&
                (recordStore.peer.getAuthMode() == AUTHMODE_PRIVATE)) {
            recordStore.closeRecordStore();
            throw new SecurityException();
        }

        return recordStore;
    
public voidremoveRecordListener(RecordListener listener)
Removes the specified RecordListener. If the specified listener is not registered, this method does nothing.

param
listener the RecordChangedListener
see
#addRecordListener

        synchronized (recordListener) {
	    recordListener.removeElement(listener);
	}
    
public voidsetMode(int authmode, boolean writable)
Changes the access mode for this RecordStore. The authorization mode choices are:
  • AUTHMODE_PRIVATE - Only allows the MIDlet suite that created the RecordStore to access it. This case behaves identically to openRecordStore(recordStoreName, createIfNecessary).
  • AUTHMODE_ANY - Allows any MIDlet to access the RecordStore. Note that this makes your recordStore accessible by any other MIDlet on the device. This could have privacy and security issues depending on the data being shared. Please use carefully.

The owning MIDlet suite may always access the RecordStore and always has access to write and update the store. Only the owning MIDlet suite can change the mode of a RecordStore.

param
authmode the mode under which to check or create access. Must be one of AUTHMODE_PRIVATE or AUTHMODE_ANY.
param
writable true if the RecordStore is to be writable by other MIDlet suites that are granted access
exception
RecordStoreException if a record store-related exception occurred
exception
SecurityException if this MIDlet Suite is not allowed to change the mode of the RecordStore
exception
IllegalArgumentException if authmode is invalid


                                                                                                                                                                                                                                                                                                
         
              
	checkOpen();
        if (! isRecordStoreOwner()) {
            throw new SecurityException("not the owner");
        } else if (authmode != AUTHMODE_PRIVATE &&
                   authmode != AUTHMODE_ANY) {
            throw new IllegalArgumentException();
        }

        peer.setMode(authmode, writable);
    
public voidsetRecord(int recordId, byte[] newData, int offset, int numBytes)
Sets the data in the given record to that passed in. After this method returns, a call to getRecord(int recordId) will return an array of numBytes size containing the data supplied here.

param
recordId the ID of the record to use in this operation
param
newData the new data to store in the record
param
offset the index into the data buffer of the first relevant byte for this record
param
numBytes the number of bytes of the data buffer to use for this record
exception
RecordStoreNotOpenException if the record store is not open
exception
InvalidRecordIDException if the recordId is invalid
exception
RecordStoreException if a general record store exception occurs
exception
RecordStoreFullException if the operation cannot be completed because the record store has no more room
exception
SecurityException if the MIDlet has read-only access to the RecordStore
see
#getRecord


	if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {
	    Logging.report(Logging.INFORMATION, LogChannels.LC_RMS,
			   "setRecord("+recordId+")");
	}

	// validate parameters
	if ((newData == null) && (numBytes > 0)) {
	    throw new NullPointerException("illegal arguments: null " +
					   "data,  numBytes > 0");
	}
	if ((offset < 0) || (numBytes < 0) ||
	    ((newData != null) && (offset + numBytes > newData.length))) {
	    throw new ArrayIndexOutOfBoundsException();
	}

	checkOpen();
        checkWritable();

        peer.setRecord(recordId, newData, offset, numBytes);

	// update database header info and sync to file
	notifyRecordChangedListeners(recordId);