UNIT II - Chapter 6 - How to record the persistent data?

Chapter 6          :           How to record the persistent data?

Every good programming medium needs to facilitate the saving of persistent data. The persistent storage is required for storing various kinds of data which may include text, images, video or audio recordings as well as other forms of binary data. Sensing this Java 2 Platform, Micro Edition (J2ME) has provided the javax.microedition.rms package.

The MIDP 1.0 profile contains support for a ‘Record Management System’ which helps us save various kinds of data. This may seem little different to the desktop programmers as they are used to the file system for storing the data. But MIDP has provided for the RMS because it is more suited to tiny devices for storing data. The founders of the J2ME have also made sure that the data residing in the RMS is secure. Ordinarily it is expected that the data within the RMS is persistently saved for future reference. It should not get erased automatically due to factors like closing the MIDlet or reboots or battery changes. Also the RMS enables different MIDlets within the same MIDletSuite to access each others records but it doesn’t allow MIDlets from a different MIDletSuite to access the data. This helps in restricting the unauthorized modification in data.

The record management system contains the following elements:

 

Interfaces:

·         RecordComparator

·         RecordEnumeration

·         RecordFilter

·         RecordListener

 

Classes:

·         RecordStore

 

Exceptions (Shown separately from classes for clarity):

·         InvalidRecordIDException

·         RecordStoreException

·         RecordStoreFullException

·         RecordStoreNotFoundException

·         RecordStoreNotOpenException

 

RecordStore

 

       The ‘RecordStore’ class is the single most important data base related class. The ‘RecordStore’ class which can be thought of as a collection of records. This class gives the methods for adding, deleting, traversing and performing several other functions on the data records. It is generally expected that data stored in RecordStore will be saved persistently and that battery changes or switching off the application or the phone would not result in any loss of data.

An application is allowed to have many different RecordStores as long as they all have different names. The RecordStore names could be any combination of up to 32 Unicode characters. Also the RecordStore names are case sensitive. Thus a RecordStore named “data” is different from a RecordStore named “Data”.

The records are arrays of bytes. You can use the following streams for saving and retrieving data from the RecordStore:

  • DataInputStream
  • DataOutputStream
  • ByteArrayInputStream
  • ByteArrayOutputStream

Records are stored in a RecordStore with a unique recordId. The recordId value is an integer and it starts with a value of 1 for the first record and the value of the next record is 2 and so on.

 

RecordComparator 

RecordComparator is an interface which defines a compare method which compares two records to see if they match or what their relative sort order is. Application implements RecordComparator to compare two records. The ordering of the two records is communicated by the return value. RecordEnumeration calls the compare method to sort and return records in an application specified order.

 

Example Code

RecordComparator rc = new CustomRecordComparator(); // A class implementing RecordComparator

if (rc.compare(recordStore1.getRecord(rec1), recordStore1.getRecord(rec2)) == RecordCompara

tor.PRECEDES)

{

            // your custom action code

}

 

RecordEnumeration

This class maintains a logical sequence of the recordId's of the records in a record store. Record enumerator iterates over each (or a partial set, if an optional record filter has been given) of the records in an order which is determined by an optional record comparator. This functionality of this interface can be used for providing sorting capabilities.

 

RecordFilter 

The RecordFilter interface defines a filter which scans a record to see if it matches the application defined criteria. It returns true if the criteria is matched.

 

Example Code

RecordFilter rf = new CustomRecordFilter(); // A class implementing RecordFilter

if (rf.matches(recordStore1.getRecord(theRecordID)) == true)

{

            // your customized action code

}

 

RecordListener 

The role of a RecordListener interface is to receive the following Record events from a record store:

§  recordAdded

§  recordChanged

§  recordDeleted

The methods of this interface provide us with the RecordStore and the recordId of the record which generated the event.

 

Given below is an example MIDlet which gives an option to either save or retrieve a simple text string. Please save the data before retrieving it.

 

Example Code: Record Management System

 

/*

 * HelloMIDlet.java

 *

 * Created on June 8, 2004, 10:23 PM

 */

 

import javax.microedition.midlet.* ;

import javax.microedition.lcdui.* ;

import java.io.* ;

import javax.microedition.rms.* ;

 

/**

 An example MIDlet which gives an option to either save or retrieve a simple text string

 * Please save the data before retrieving it

 *

 * @author  Saurabh Jain

 * @version 1.0.0

 */

public class HelloMIDlet extends MIDlet implements CommandListener

{

    private boolean init ;

    private Command save; // The save command

    private Command retrieve; // The exit command

   

    private Display display;    // The display for this MIDlet

    private TextBox t ;

   

    private RecordStore recordStore ;

   

    /**

     * Start up the Hello MIDlet by creating the TextBox and associating

     * the exit command and listener.

     */

    public void startApp()

    {

        if(init == false)

        {

            display = Display.getDisplay(this) ;

            this.save = new Command("Save",Command.OK,1) ;

            this.retrieve = new Command("Retrieve",Command.EXIT,1) ;

           

            t = new TextBox("Hello MIDlet", "Test string", 256, 0);

 

            t.addCommand(this.save);

            t.addCommand(this.retrieve);

            t.setCommandListener(this);

           

            init = true ;

        }

        display.setCurrent(t);

    }

   

    /**

     * Pause is a no-op since there are no background activities or

     * record stores that need to be closed.

     */

    public void pauseApp() {

    }

   

    /**

     * Destroy must cleanup everything not handled by the garbage collector.

     * In this case there is nothing to cleanup.

     */

    public void destroyApp(boolean unconditional) {

    }

    

    /*

     * Respond to commands, including exit

     * On the exit command, cleanup and notify that the MIDlet has been destroyed.

     */

    public void commandAction(Command c, Displayable s)

    {

        if(c == this.save)              // On pressing save command

        {

            this.save(t.getString()) ;

        }

        else if (c == this.retrieve)    // On pressing retrieve command

        {

            t.setString(this.retrieve()) ;

        }

    }

   

    // Method for saving a text string

    private void save(String text)

    {

        byte[] data;

 

            try

        {

            // Opening the recordStore

            // If the RecordStore exists opens it else creates one

            this.recordStore = RecordStore.openRecordStore("database", true) ;

           

            // Converts the String text into byte array

            data = text.getBytes() ;

           

            // Checking to see whether the RecordStore is not empty

            if(this.recordStore.getNumRecords() == 0)

            {

                // Adding the record in the RecordStore

                this.recordStore.addRecord(data,0,data.length) ;

            }

            else

            {

                // Setting the record in the RecordStore at position 1

                this.recordStore.setRecord(1,data,0,data.length) ;

            }

            }

        catch (Exception e)

        {

                e.printStackTrace() ;

            }

    }

   

    // Method for retrieving a text string

    private String retrieve()

    {

        String s = "" ;

       

        try

        {

            // Opening the recordStore

            // If the RecordStore exists opens it else creates one

            this.recordStore = RecordStore.openRecordStore("database", true) ;

          

            // Checking to see whether the RecordStore is not empty

            if(this.recordStore.getNumRecords() == 0)

            {

                s = new String("RecordStore Empty") ;

            }

            else

            {

                s = new String(this.recordStore.getRecord(1)) ;

            }

       }

       catch(Exception e)

       {

            e.printStackTrace() ;

       }

      

       return s ;

    }

}

Comments