MELJUN CORTES Jedi course notes mobile application devt-lesson05-record management system


Published on

MELJUN CORTES Jedi course notes mobile application devt-lesson05-record management system

  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

MELJUN CORTES Jedi course notes mobile application devt-lesson05-record management system

  1. 1. J.E.D.I. The Record Management SystemMIDP provides an API where programs can persist application data locally on the device.The MIDP Record Management System is a facility for MIDlets to store application dataacross MIDlet invocations. Data is stored into the non-volatile memory of the device.This means that stored program data will not be lost even if the program is restarted orthe device is turned off.The Record Management System is a record-oriented database system for MIDP devices.A record in this database is simply an array of bytes with an index.1 Objectives At the end of the lesson, the student should be able to: • Understand the concept of a Record Store • Create and Open Record Stores • Add, Retrieve, Update and Delete records • Enumerate records using a RecordEnumerator • Create a Record Comparator • Create a Record Filter2 The Record StoreA Record Store is a collection of records. Record Ids in a Record Store are unique. RecordIds are automatically allocated at record creation time and act as the index or primarykey. Record Ids are assigned sequentially, and the first Record ID assigned to the firstrecord of every Record Store is 1 (one).When a record is deleted, its record id will not be reused. If we create four records anddelete the fourth record, the next record Id that the system will assign is 5 (see Figure). Record ID Array of bytes 1 Data of record #1 2 Data of record #2 3 Data of record #3 5 Data of record #5Mobile Application Development 1
  2. 2. J.E.D.I.MIDlets can create more than one record store. The record store name should be uniquewithin the MIDlet suite. Record store names are case sensitive. The maximum length of aRecord Store is 32 characters.When a MIDlet suite is deleted from a device, all record stores associated with theMIDlets in this suite will also be deleted.Mobile Application Development 2
  3. 3. J.E.D.I.Creating and Opening Record StoresThe following method creates or opens Record Stores: static RecordStore openRecordStore(String recordStoreName, boolean createIfNecessary) static RecordStore openRecordStore(String recordStoreName, boolean createIfNecessary, int authmode, boolean writable) static RecordStore openRecordStore(String recordStoreName, String vendorName, String suiteName)If createIfNecessary is set to true and the Record Store does not yet exist, the RecordStore will be created. If createIfNecessary is set to false and the Record Store is non-existent, a RecordStoreNotFoundException will be thrown.The authmode parameter may be RecordStore.AUTHMODE_PRIVATE orRecordStore.AUTHMODE_ANY. Using AUTHMODE_PRIVATE will cause the Record Store tobe accessible only by the MIDlet suite of the owner MIDlet. Setting authmode toAUTHMODE_ANY will make this Record Store to be accessible by ANY MIDlet. The accessmode is specified by the boolean parameter writable. To allow other MIDlets (outside ofthe MIDlet suite) to write on this record store, this parameter must be set to true.Using the first form of the openRecordStore() method will cause the Record store to beaccessible only by MIDlets in the same suite (authmode set to AUTHMODE_PRIVATE).To open an existing Record Store from a different MIDlet suite, the third form of theopenRecordStore method should be used. The vendorName and the MIDlet suiteNamemust be specified.If the Record Store is already open, these methods will return the reference to thisRecord Store. The system keeps track of how many times Record Stores have beenopened. Each Record Store must be closed the same number of times it has beenopened.Mobile Application Development 3
  4. 4. J.E.D.I.Adding a Record int addRecord(byte[] data, int offset, int numBytes)The method addRecord will create a new Record on the Record Store and return theRecord ID.Retrieving Records byte[] getRecord(int recordId) int getRecord(int recordId, byte[] buffer, int offset) int getRecordSize(int recordId)The first form of the getRecord method returns a copy of the data stored on the recordgiven the Record ID. The second form will copy the data on the supplied byte arrayparameter. When using the second form, the byte array must have been previouslyallocated. If the size of the record is larger than the size of the parameter, anArrayIndexOutOfBoundsException will be thrown. You can use the method getRecordSizein order to know beforehand the size of the record you are going to read.Mobile Application Development 4
  5. 5. J.E.D.I.Updating a RecordWe cannot modify only part of the record data. If we want to modify a record, we haveto:1. read the record using getRecord2. update the record in memory3. call setRecord to write the updated record data. void setRecord(int recordId, byte[] newData, int offset, int numBytes)Deleting a Record void deleteRecord(int recordId)When a record is deleted, the record Id will not be reused in the next calls to addRecord.This means that there could be a gap in the Record Ids. So it is not advisable to use anincrementing counter to list all the records in a record store. The Record Enumerator iswhat we should use to go through the list of records in a store.Closing a Record Store void closeRecordStore()Calling closeRecordStore() will not close the Record Store until it has been called thesame number of times openRecordStore() has been called on a particular store. Thesystem counts how many times a record store is opened. Calling closeRecordStore()more times than it has been opened will cause a RecordStoreNotOpen Exception.Mobile Application Development 5
  6. 6. J.E.D.I.This snippet from the example RmsExample1 is a simple MIDlet that demontrates how tocreate a Record Store, add records and retrieve all the records from the Record Store: // Open or Create Record Store with name "RmsExample1" recStore = RecordStore.openRecordStore("RmsExample1", true); // Load contents of Record Store for (int recId=1; recId<=recStore.getNumRecords(); recId++){ // getRecord returns the length of the record recLength = recStore.getRecord(recId, data, 0); // Convert the byte array into String String item = new String(data, 0, recLength); ... } ... // This is the String we will put into the Record String newItem = "Record #" + recStore.getNextRecordID(); // Convert the String into a byte array byte[] bytes = newItem.getBytes(); // Write the Record into the Store recStore.addRecord(bytes, 0, bytes.length);Programming Tips:1. The starting Record ID is 1, and not 0. When using loops, remember to use 1 as the starting index and not 0.2. It is better to use a Record Enumerator than using an incrementing index (as in this example). Deleted records will still be read by this example, which will cause an InvalidRecordIDException Exception.Mobile Application Development 6
  7. 7. J.E.D.I.Obtaining the List of Record Stores in a MIDlet Suite static String[] listRecordStores()This method returns an array of the names of record stores owned by the MIDlet suite. Ifthe MIDlet suite does not have a Record Store, this method will return null. String[] storeNames = RecordStore.listRecordStores(); System.out.println("Record Stores for this MIDlet suite:"); for (int i=0; storeNames != null && i<storeNames.length; i++){ System.out.println(storeNames[i]); }Example: RmsListStoresRecord Stores for this MIDlet suite:PrefsRmsExample1RmsExample2Sample Output of RmsListStoresThe order of the names returned is not defined and is implementation dependent. So ifwe want to display the names ordered alphabetically, we have to sort the array first.Mobile Application Development 7
  8. 8. J.E.D.I.Storing Java PrimitivesSo far, the data that we have been writing and reading from the record store are Strings.CLDC includes the standard classes for primitive manipulation. These classes are fromthe standard library of Java 2 Platform, Standard Edition (J2SE).We can write Java primitives by combining the ByteArrayOutputStream and theDataOutputStream classes. Reading primitives (int, long, short, string, boolean, etc) isalso done using the ByteArrayInputStream and DataInputStream.ByteArrayOutputStream out = new ByteArrayOutputStream();DataOutputStream dOut = new DataOutputStream(out);// Store an integer (square of the record iddOut.writeInt(recStore.getNextRecordID() * recStore.getNextRecordID());// Store a stringdOut.writeUTF("Record #" + recStore.getNextRecordID());byte[] bytes = out.toByteArray();// Write the Record into the StorerecStore.addRecord(bytes, 0, bytes.length);...// Get the next recordbyte[] recBytes = enumerator.nextRecord();ByteArrayInputStream in = new ByteArrayInputStream(recBytes);DataInputStream dIn = new DataInputStream(in);int count = dIn.readInt();String item = dIn.readUTF();Mobile Application Development 8
  9. 9. J.E.D.I.Other methods for Record Stores long getLastModified() int getVersion()The system remembers when a record store was last modified. The methodgetLastModified returns the last time a record store was last modified. It returns a longvalue, in the format used by System.currentTimeMillis().All record stores maintain a version information. Every time a record is modified, theirversion number is updated. Using the methods addRecord, setRecord and deleteRecordwill cause the version number of record store to be incremented. static void deleteRecordStore(String recordStoreName) Deletes the named record store. String getName() Returns the name of this RecordStore. int getNextRecordID() Returns the recordId of the next record to be added to the record store. int getNumRecords() Returns the number of records currently in the record store. int getSize() Returns the amount of space, in bytes, that the record store occupies. int getSizeAvailable() Returns the amount of additional room (in bytes) available for this record store to grow. void setMode(int authmode, boolean writable) Changes the access mode for this RecordStore.Mobile Application Development 9
  10. 10. J.E.D.I.3 Record EnumerationTraversing a Record Store using an incrementing index is inefficient. Deleted recordstores will have to be skipped over since Record Ids of deleted records are not reused.Using a record enumerator solves the problem of having to look out for deleted records.We can also sort the order of the enumeration by passing a comparator method. Bypassing a filter method, we can also skip records of no interest to our output. RecordEnumeration enumerateRecords(RecordFilter filter, RecordComparator comparator, boolean keepUpdated)The enumerateRecords method of a record store will return an enumeration fortraversing all the records in a store. This is the recommended way to traverse all therecords in a record store. We will be discussing the filter and comparator in the nextlessons.The simplest way to use this method is to use null for both filter and comparator. Thiswill return an enumeration off all the records in a store in an undefined order. // Open or Create Record Store with name "RmsExample2" recStore = RecordStore.openRecordStore("RmsExample2", true); // Load contents of Record Store RecordEnumeration enumerator = recStore.enumerateRecords(null, null, false); while (enumerator.hasNextElement()){ // Get the next record and convert the byte array into String String item = new String(enumerator.nextRecord()); // Do something with the record ... }Mobile Application Development 10
  11. 11. J.E.D.I.4 Record ComparatorThe ordering of an enumeration can be defined using a Record Comparator. A RecordComparator is passed on the method enumerateRecords. If we want to sort the output ofan enumeration, we have to define a comparator and pass that method as a secondparameter to enumerateRecords. int compare(byte[] rec1, byte[] rec2)In order to create a Record Comparator, we must implement the RecordComparatorinterface. This interface defines a single method, compare(byte[] rec1, byte[] rec2). Thismethod must return, RecordComparator.FOLLOWS or RecordComparator.PRECEDES ifrec1 follows or precedes rec2 in the sort order, respectively.RecordComparator.EQUIVALENT should be returned if rec1 is equivalent to rec2 in thesort order. // Create an enumeration, sorted alphabetically RecordEnumeration enumerator = recStore.enumerateRecords(null, new AlphaOrder(), false); ... // Sort alphabetically class AlphaOrder implements RecordComparator { public int compare(byte[] rec1, byte[] rec2){ String record1 = new String(rec1).toUpperCase(); String record2 = new String(rec2).toUpperCase(); if (record1.compareTo(record2) < 0){ return(PRECEDES); } else { if (record1.compareTo(record2) > 0){ return(FOLLOWS); } else { return(EQUIVALENT); } } } }Mobile Application Development 11
  12. 12. J.E.D.I.5 Record FilterThe examples we have seen so far reads all the records from the store. We can use afilter to get only the records that we want.Our program must implement the match() method to select our target record(s). Itshould return true if the record matches our criteria. It should return false otherwise. boolean matches(byte[] candidate)public boolean matches(byte[] candidate){ boolean isaMatch = false; try { ByteArrayInputStream bin = new ByteArrayInputStream(candidate); DataInputStream dIn = new DataInputStream(bin); int count = dIn.readInt(); String item = dIn.readUTF(); // return only records with contents ending in 0 if (item.endsWith("0")){ isaMatch = true; } else { isaMatch = false; } } catch (Exception e){items.append(e.toString(), null); } return(isaMatch);}Mobile Application Development 12
  13. 13. J.E.D.I.6 Exercises6.1 Preferences StoreCreate a class that can persist program preferences. The class will store the preferencesinto a Record Store. Each record will have a variable name and value. Eachvariable/value pair is stored in a single record. The name and value are stored in thedatabase as Strings.The class should implement these methods:public String readVar(RecordStore recStore, String name, String defaultValue){public void writeString(RecordStore recStore, String name, String value);Mobile Application Development 13