smi filtering and searching records in rms draft

Upload: saumitra2

Post on 07-Aug-2018

213 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    1/23

    Filtering 

    and 

    Searching 

    Records 

    in 

    RMS.

    Version 

    0.4, 

    Draft 

    INFO 

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    2/23

      Filtering and Searching in RMS

    2

    COPYRIGHT

    Samsung Electronics Co. Ltd.

    This material is copyrighted by Samsung Electronics. Any unauthorized reproductions,

    use or disclosure of this material, or any part thereof, is strictly prohibited and is a

    violation under the Copyright Law. Samsung Electronics reserves the right to make

    changes in specifications at any time and without notice. The information furnished by

    Samsung Electronics in this material is believed to be accurate and reliable, but is not

    warranted true in all cases.

    Trademarks and Service Marks

    The Samsung Logo is the trademark of Samsung Electronics. Java is the trademark of

    Sun Microsystems.

     All other company and product names may be trademarks of the respective companieswith which they are associated.

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    3/23

      Filtering and Searching in RMS

    3

     About This Document

    The Java ME Record Management System (RMS) provides a mechanism through which

    MIDlets can insert records, read records, search for particular records and sort records

    stored by the RMS. Earlier Java ME Record Management System  document explains

    about RMS and its basic operation. This document explains about advanced RMS

    operations like traversing (filtering), searching and sorting records in RMS.

    Scope

    This document is intended for MIDP developers wishing to develop mobile applications

    using Record Management System (RMS). It assumes good knowledge of java

    programming language. This document focuses on RMS and therefore explaining the

    Java technology is out of the scope in this documentation.

    To know more about Java ME basics and Java programming language, refer to the

    Knowledge Base under Samsung Mobile Innovator (SMI).

    http://innovator.samsungmobile.com/platform.main.do?platformId=3 

    http://innovator.samsungmobile.com/cms/cnts/knowledge.detail.view.do?platformId=3&cntsId=6320http://innovator.samsungmobile.com/platform.main.do?platformId=3http://innovator.samsungmobile.com/platform.main.do?platformId=3http://innovator.samsungmobile.com/platform.main.do?platformId=3http://innovator.samsungmobile.com/cms/cnts/knowledge.detail.view.do?platformId=3&cntsId=6320

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    4/23

      Filtering and Searching in RMS

    4

    Table of Contents 

    Introduction .......................................................................................................... 5 

    Traversing a Record ............................................................................................. 5 

    Enumerating Records ........................................................................................... 6 

    Traversing in an Enumeration .............................................................................. 8 

    1. Moving Forward. ............................................................................................ 8 

    2. Moving Backward........................................................................................... 9 

    Filtering a Record ............................................................................................... 10 

    Sorting a Record ................................................................................................. 10 

    Sample Example................................................................................................. 12 

    Class: RMSMIDlet............................................................................................ 12 

    Class: RMSForm............................................................................................... 13 

    Class: RMSFilter............................................................................................... 22 

    Class: RMSComparator .................................................................................... 23 

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    5/23

      Filtering and Searching in RMS

    5

    Introduction

    In the first released RMS document, we have learned what RMS is all about and its basic

    operations. We learned how to open, create, and delete RecordStore. We also learned

    about adding, retrieving and deleting Records to and from RecordStore. Apart from these

    basic operations there are situations where you want to navigate through the records,

    sort out records, and filter records to get the wanted data. We will learn on how these

    operations can be achieved.

    Traversing a Record

    Whenever a Record is added in the RecordStore, RMS returns an index. This index is an

    integer positive value starting from 1 and it keeps on growing whenever a new Record is

    added in RecordStore.

    Similarly whenever we delete a Record from a RecordStore, we cannot use the deleted

    record index again. Using the same index again for adding or modifying would result in

    an InvalidRecordIDException.

    So how to do we traverse Records in RecordStore, since accessing deleted index would

    throw InvalidRecordIDException

    There are two ways for traversing through the Records.

    1.  Loop through the records skipping invalid index. Here you need to use try catch

    statement for catching InvalidRecordIDException as shown in the below code

    snippet. This looping is time consuming if the Records are huge.

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    6/23

      Filtering and Searching in RMS

    6

    ...

    try {

    RecordStore rs = RecordStore.openRecordStore("RecordName", true);

    for( int i = 1; i < rs.getNumRecords(); i++ ) {

    try {

    byte[] data = rs.getRecord( i );

    ... // process the data

    } catch( InvalidRecordIDException e ){

     // just ignore and move to the next record

    }

    } catch( RecordStoreException e ){

     // a more general error that should be handled somehow

    }

    }

    ...

    2. Another way to traverse through the Records is through the use of Enumeration.

    Enumerating Records

    RMS provides an enumerateRecords method in RecordStore class for traversing through

    the Records. enumerateRecords method returns an enumeration of valid records (valid

    indexes) for traversing using RecordEnumeration interface.

    So instead of looping through the records and skipping invalid records, we can tell RMS

    to give an enumeration of valid records.

    public RecordEnumeration enumerateRecords(RecordFilter filter,

    RecordComparator comparator,

    boolean keepUpdated)

    throws RecordStoreNotOpenException

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    7/23

      Filtering and Searching in RMS

    7

     You can traverse the records either way either ways i.e. forward or backward. You can

    always get an updated enumeration of Records (track changes to the records as they

    occur).

    RecordEnumeration takes three parameters for returning the enumeration.

    The First parameter is RecordFilter which can be used to determine what subset of the

    RecordStore Records will be used. We will learn in detail about RecordFilter later.

    Second parameter is RecordComparator which can be used to determine the order in

    which the records are returned. We will learn in detail about RecordComparator later.

    Third parameter is boolean value which when:

    true: the enumerator will keep its enumeration current with any changes in the records

    of the record store. Tracking changes requires extra overhead. So use it with caution as

    there are possible performance consequences.

    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.

    ...

    RecordStore rs = RecordStore.openRecordStore("RecordName", true);

    RecordEnumeration enum = rs.enumerateRecords( null, null, false );

    ... // use the enumeration here

    enum.destroy(); // always clean it up!

    Since RecordEnumeration can keep track of the latest changes in RecordStore, it may

    use system resources, so it always better to call destroy() after your work is done.

    destroy() frees internal resources used by RecordEnumeration.

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    8/23

      Filtering and Searching in RMS

    8

    Traversing in an Enumeration

     As already mentioned you can traverse the records either ways i.e. forward or backward.

    1. Moving Forward.

    RecordEnumeration interface has three methods for moving forward while traversing

    through the Records.

    hasNextElement() - Returns true if more elements exist in the next direction.

    nextRecordId() - Returns the recordId of the next record in this enumeration. After

    calling this method, the enumeration is advanced to the next available record.

    nextRecord() - Returns a copy of the next record in this enumeration. Any changes

    made to this array will NOT be reflected in the record store. After calling this

    method, the enumeration is advanced to the next available record.

    ...

    RecordStore rs = RecordStore.openRecordStore("RecordName", true);

    RecordEnumeration enum = rs.enumerateRecords( null, null, false );

    try {

    while( enum.hasNextElement() ){

    int id = enum.nextRecordId();

    byte[] data = rs.getRecord( id );

    OR

    byte[] data = enum.nextRecord();

    ... // do something here

    }} catch( RecordStoreException e ){

     // handle the error here

    }

    ...

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    9/23

      Filtering and Searching in RMS

    9

    2. Moving Backward.

    RecordEnumeration interface has three methods for moving backward while

    traversing through the Records.

    hasPreviousElement() - Returns true if more elements exist in the previous

    direction.

    previousRecordId() - Returns the recordId of the previous record in this

    enumeration. After calling this method, the enumeration is advanced to the previous

    available record.

    previousRecord () - Returns a copy of the previous record in this enumeration. Any

    changes made to this array will NOT be reflected in the record store. After calling this

    method, the enumeration is advanced to the previous available record.

    ...

    RecordStore rs = RecordStore.openRecordStore("RecordName", true);

    RecordEnumeration enum = rs.enumerateRecords( null, null, false );

    try {

    while( enum. hasPreviousElement () ){

    int id = enum. previousRecordId ();

    byte[] data = rs.getRecord( id );

    OR

    byte[] data = enum. previousRecord ();

    ... // do something here

    }

    } catch( RecordStoreException e ){

     // handle the error here

    }

    ...

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    10/23

      Filtering and Searching in RMS

    10

    Filtering a Record

    If you are interested in only a subset of the record, then you need to use RecordFilter

    interface. With this you can skip unwanted records by applying a filter (RecordFilter

    object).

    RecordFilter has a matches(byte[] candidate) method that filters out the data and

    decides whether a record is to be included in the enumeration or not. matches(byte[]

    candidate)  takes byte array data of the other record for matching. This interface is

    used in the RecordStore for searching or sub setting records.

    public class MyFilter implements RecordFilter {

    public boolean matches( byte[] recordData ){... // matching code here

    }

    }

    RecordStore enumerateRecords() method takes RecordFilter has the first parameter.

    ...

    enum = rs.enumerateRecords( new MyFilter(), null, false );

    ...

    Sorting a Record

    RecordStore enumerateRecords() method returns enumeration of records in unordered

    manner. So to get the records in a predictable order, we need to use the

    RecordComparator interface.

    RecordComparator has compare(byte[] rec1, byte[] rec2) methods that compares

    two records to see if they match or what their relative sort order is. The return value

    indicates the ordering of the two records. The return value can be one of the following:

    EQUIVALENT: means that in terms of search or sort order, the two records are the

    same.

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    11/23

      Filtering and Searching in RMS

    11

     

    FOLLOWS:  means that the left (first parameter) record follows the right (second

    parameter) record in terms of search or sort order.

    PRECEDES:  means that the left (first parameter) record precedes the right (secondparameter) record in terms of search or sort order.

    If you are interested in only a subset of the record, then you need to use RecordFilter

    interface. With this you can skip unwanted records by applying a filter (RecordFilter

    object).

    public class MyComparator implements RecordComparator {

    public int compare( byte[] r1, byte[] r2 ){

    int salary1 = getSalary( r1 );

    int salary2 = getSalary( r2 );

    if( salary1 < salary2 ){

    return PRECEDES;

    } else if( salary1 == salary2 ){

    return EQUIVALENT;

    } else {

    return FOLLOWS;

    }

    }

    private int getSalary( byte[] data ){

    ... // code to get salary info

    }

    }

    RecordStore enumerateRecords() method takes RecordComparator has the secondparameter.

    ...

    enum = rs.enumerateRecords( null, new MyComparator(), false );

    ...

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    12/23

      Filtering and Searching in RMS

    12

    Sample Example

    The example below demonstrates RecordFilter, RecordComparator interface usage.

    Class: RMSMIDlet

    import javax.microedition.lcdui.Display;

    import javax.microedition.midlet.*;

    public class RMSMIDlet extends MIDlet {

    private RMSForm rmsForm;

    public Display display;

    public void startApp() {

    display = Display.getDisplay(this);

    rmsForm = new RMSForm(this);

    display.setCurrent(rmsForm);

    }

    public void pauseApp() {

    }

    public void destroyApp(boolean unconditional) {

    notifyDestroyed();

    }

    }

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    13/23

      Filtering and Searching in RMS

    13

    Class: RMSForm

    import java.io.ByteArrayInputStream;

    import java.io.ByteArrayOutputStream;

    import java.io.DataInputStream;

    import java.io.DataOutputStream;

    import java.io.IOException;

    import javax.microedition.lcdui.Alert;

    import javax.microedition.lcdui.Choice;

    import javax.microedition.lcdui.ChoiceGroup;

    import javax.microedition.lcdui.Command;

    import javax.microedition.lcdui.CommandListener;

    import javax.microedition.lcdui.Displayable;import javax.microedition.lcdui.Form;

    import javax.microedition.lcdui.StringItem;

    import javax.microedition.lcdui.TextField;

    import javax.microedition.rms.InvalidRecordIDException;

    import javax.microedition.rms.RecordEnumeration;

    import javax.microedition.rms.RecordStore;

    import javax.microedition.rms.RecordStoreException;

    import javax.microedition.rms.RecordStoreFullException;

    import javax.microedition.rms.RecordStoreNotFoundException;

    import javax.microedition.rms.RecordStoreNotOpenException;

    public class RMSForm extends Form implements CommandListener{

    private Command addRecordCommand = new Command("Add Record",

    Command.ITEM, 1);

    private Command findRecordCommand = new Command("Filter Record",

    Command.ITEM, 1);

    private Command sortRecordCommand = new Command("Sort Record",

    Command.ITEM, 1);

    private Command selectCommand = new Command("Select", Command.OK, 1);

    private Command backCommand = new Command("Back", Command.BACK, 2);

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    14/23

      Filtering and Searching in RMS

    14

      private Command exitCommand = new Command("Exit", Command.EXIT, 1);

    private RMSMIDlet midlet;

    private RecordStore recordStore;

    private TextField studentNameTextField;

    private ChoiceGroup studentDepartmentChoiceGroup, sortOrderChoiceGroup;

    private final String department[] = {"Science", "Arts", "Commerce"};

    public static final String sortOrder[] = {"Ascending", "Descending"};

    private final String recordStoreName = "rmsexample";

    private boolean isFilterScreen;

    public RMSForm(RMSMIDlet midlet)

    {

    super("Traversing, Sorting, Searching");

    this.midlet = midlet;

    studentNameTextField = new TextField("Enter Student Name", null, 1024,

    TextField.ANY);

    studentDepartmentChoiceGroup = new ChoiceGroup("Select Department",

    Choice.EXCLUSIVE, department, null);

    sortOrderChoiceGroup = new ChoiceGroup("Select Order", Choice.EXCLUSIVE,

    sortOrder, null);

    setCommandListener(this);

    showRecordScreen();

    }

    private void openRecordStore()

    {

    try {

    recordStore = RecordStore.openRecordStore(recordStoreName, true);

    } catch (RecordStoreException ex) {

    ex.printStackTrace();

    }

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    15/23

      Filtering and Searching in RMS

    15

      }

    private void closeRecordStore()

    {

    try {

    recordStore.closeRecordStore();

    } catch (RecordStoreException ex) {

    ex.printStackTrace();

    }

    }

    private void removeAllCommands()

    {

    removeCommand(exitCommand);

    removeCommand(addRecordCommand);

    removeCommand(findRecordCommand);

    removeCommand(sortRecordCommand);

    removeCommand(backCommand);

    removeCommand(selectCommand);

    }

    private void showRecordScreen()

    {

    deleteAll();

    removeAllCommands();

    studentNameTextField.setString(null);

    addCommand(exitCommand);

    addCommand(addRecordCommand);

    addCommand(findRecordCommand);

    addCommand(sortRecordCommand);

    setTitle("Add Record");

    append(studentNameTextField);

    append(studentDepartmentChoiceGroup);

    setCommandListener(this);

    }

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    16/23

      Filtering and Searching in RMS

    16

      private void showSortRecordScreen()

    {

    deleteAll();

    removeAllCommands();

    setTitle("Select Sort Order");

    append(sortOrderChoiceGroup);

    addCommand(backCommand);

    addCommand(selectCommand);

    setCommandListener(this);

    isFilterScreen = false;

    }

    private void showFilterRecordScreen()

    {

    deleteAll();

    removeAllCommands();

    setTitle("Select Filter");

    append(studentDepartmentChoiceGroup);

    addCommand(backCommand);

    addCommand(selectCommand);

    setCommandListener(this);

    isFilterScreen = true;

    }

    private void doRecordFilter(String filterString)

    {

    try {

    openRecordStore();

    if(recordStore.getNumRecords()>0)

    {

    RMSFilter filter = new RMSFilter(filterString);

    RecordEnumeration recEnum = recordStore.enumerateRecords(filter,

    null, true);

    if( recEnum.numRecords()>0 )

    {

    deleteAll();

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    17/23

      Filtering and Searching in RMS

    17

      removeAllCommands();

    while(recEnum.hasNextElement())

    {

    try {

    byte[] filterRecordData = recEnum.nextRecord();

    ByteArrayInputStream bis = new

    ByteArrayInputStream(filterRecordData);

    DataInputStream dis = new DataInputStream(bis);

    String studentName = dis.readUTF();

    readUTF();String studentDept = dis.

      StringItem stringItem = new StringItem("Student Information",

    "\nName: "+studentName+"\nDepartment: "+studentDept+"\n");

    append(stringItem);

    } catch (IOException ex) {

    ex.printStackTrace();

    } catch (InvalidRecordIDException ex) {

    ex.printStackTrace();

    } catch (RecordStoreNotOpenException ex) {

    ex.printStackTrace();

    } catch (RecordStoreException ex) {

    ex.printStackTrace();

    }

    }

    addCommand(backCommand);

    setCommandListener(this);

    }else

    {

     Alert alert = new Alert("Error");

    alert.setString("No Record Exists.\nPlease select another filter");

    alert.setTimeout(Alert.FOREVER);

    midlet.display.setCurrent(alert);

    }

    }

    else

    {

     Alert alert = new Alert("Error");

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    18/23

      Filtering and Searching in RMS

    18

      alert.setString("No Record Exists.\nPlease Add record");

    alert.setTimeout(Alert.FOREVER);

    midlet.display.setCurrent(alert);

    }

    } catch (RecordStoreNotOpenException ex) {

    ex.printStackTrace();

    }

    }

    private void doRecordSorting(String sortingString)

    {

    try {

    openRecordStore();

    if(recordStore.getNumRecords()>0)

    {

    RMSComparator comparator = new RMSComparator(sortingString);

    RecordEnumeration recEnum = recordStore.enumerateRecords(null,

    comparator, true);

    if( recEnum.numRecords()>0 )

    {

    deleteAll();

    removeAllCommands();

    while(recEnum.hasNextElement())

    {

    try {

    byte[] filterRecordData = recEnum.nextRecord();

    ByteArrayInputStream bis = new

    ByteArrayInputStream(filterRecordData);

    DataInputStream dis = new DataInputStream(bis);

    String studentName = dis.readUTF();

    String studentDept = di ();s.readUTF

      StringItem stringItem = new StringItem("Student Information",

    "\nName: "+studentName+"\nDepartment: "+studentDept+"\n");

    append(stringItem);

    } catch (IOException ex) {

    ex.printStackTrace();

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    19/23

      Filtering and Searching in RMS

    19

      } catch (InvalidRecordIDException ex) {

    ex.printStackTrace();

    } catch (RecordStoreNotOpenException ex) {

    ex.printStackTrace();

    } catch (RecordStoreException ex) {

    ex.printStackTrace();

    }

    }

    addCommand(backCommand);

    setCommandListener(this);

    }else

    {

     Alert alert = new Alert("Error");

    alert.setString("No Record Exists.\nPlease select another filter");

    alert.setTimeout(Alert.FOREVER);

    midlet.display.setCurrent(alert);

    }

    }else

    {

     Alert alert = new Alert("Error");

    alert.setString("No Record Exists.\nPlease Add record");

    alert.setTimeout(Alert.FOREVER);

    midlet.display.setCurrent(alert);

    }

    } catch (RecordStoreNotOpenException ex) {

    ex.printStackTrace();

    }

    }

    private void addRecord(String data, int studentDeptIndex)

    {

    try {

    openRecordStore();

    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    DataOutputStream dos = new DataOutputStream(baos);

    dos.writeUTF(data);

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    20/23

      Filtering and Searching in RMS

    20

      dos.writeUTF(department[studentDeptIndex]);

    byte[] recordData = baos.toByteArray();

    int addedIndex =recordStore.addRecord(recordData, 0, recordData.length);

    dos.close();

    baos.close();

    closeRecordStore();

    } catch (IOException ex) {

    ex.printStackTrace();

    } catch (RecordStoreNotOpenException ex) {

    ex.printStackTrace();

    } catch (RecordStoreException ex) {

    ex.printStackTrace();

    }

    }

    public void commandAction(Command c, Displayable d) {

    if(c == exitCommand)

    midlet.destroyApp(true);

    else

    if(c == addRecordCommand)

    {

    String data = studentNameTextField.getString();

    int choiceIndex = studentDepartmentChoiceGroup.getSelectedIndex();

    if(data == null || data.length()

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    21/23

      Filtering and Searching in RMS

    21

      { showFilterRecordScreen(); }

    else

    if(c == sortRecordCommand)

    { showSortRecordScreen(); }

    else

    if(c == selectCommand)

    {

    if(isFilterScreen)

    {

    int filterIndex = studentDepartmentChoiceGroup.getSelectedIndex();

    doRecordFilter(department[filterIndex]);

    }else

    {

    int sortIndex = sortOrderChoiceGroup.getSelectedIndex();

    doRecordSorting(sortOrder[sortIndex]);

    }

    }else

    if(c == backCommand)

    {

    System.out.println("backCommand isFilterScreen "+isFilterScreen);

    showRecordScreen();

    }

    }

    }

    Class: RMSFilter

    import java.io.ByteArrayInputStream;

    import java.io.DataInputStream;

    import java.io.IOException;

    import javax.microedition.rms.RecordFilter;

    public class RMSFilter implements RecordFilter{

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    22/23

      Filtering and Searching in RMS

    22

      private String filterString;

    public RMSFilter(String filterString)

    { this.filterString = filterString; }

    public boolean matches(byte[] candidate) {

    try {

    ByteArrayInputStream bis = new ByteArrayInputStream(candidate);

    DataInputStream dis = new DataInputStream(bis);

    String studentName = dis.readUTF();

    String studentDept = dis.readUTF();

    if (filterString.equals(studentDept)) {

    return true;

    }

    return false;

    } catch (IOException ex) {

    ex.printStackTrace();

    }

    return false;

    }

    }

    lass: RMSComparatorC

    import javax.microedition.rms.RecordComparator;

    public class RMSComparator implements RecordComparator{

    private String sortingOrder;

    public RMSComparator(String sortingOrder)

    { this.sortingOrder = sortingOrder; }

  • 8/20/2019 SMI Filtering and Searching Records in RMS Draft

    23/23

      Filtering and Searching in RMS

     

    public int compare(byte[] rec1, byte[] rec2) {

    String str1 = new String(rec1);

    String str2 = new String(rec2);

    int result = str1.compareTo(str2);

    if (result == 0){

    return RecordComparator.EQUIVALENT;

    } else if (result < 0){

    if(sortingOrder.equals("Ascending"))

    return RecordComparator.FOLLOWS;

    else

    return RecordComparator.PRECEDES;

    } else {

    if(sortingOrder.equals("Ascending"))

    return RecordComparator.PRECEDES;

    else

    return RecordComparator.FOLLOWS;

    }

    }

    }