Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Give Your Mobile Workforce Offline Muscle with the MIDP Record Management System : Page 2

MIDP offers the ability to store data locally on the device. This is a distinct advantage over browser-based approaches, especially when the user moves out of network coverage. Find out how to use the MIDP Record Management System (RMS) to store application data for offline browsing.

Getting to Know the RMS Package
The RMS package contains one class, RecordStore, and a number of interfaces that help applications use the RecordStore. Table 1 lists these interfaces and provides a brief description of how each interface is used.

Table 1. The classes and interfaces supported by the RMS package.

RecordComparator Interface that provides sorting criteria to a RecordStore query. This is analogous to the order by clause of a SQL statement.
RecordFilter Interface that provides filtering criteria to a RecordStore query. This is analogous to the where clause of a SQL statement.
RecordEnumeration Interface that provides a means of iterating over a result set returned by a RecordStore query (calls to enumerateRecords()).
RecordListener Interface used to provide a call-back method to notify listeners when data contained by the RecordStore is changed or new records are added.
RecordStore Class that represents a record store and provides methods for interacting with records in the store.

The next few sections discuss each of these classes in more detail.

Sorting Elements in a RecordStore
The RecordComparator interface provides a way to specify sort criteria specific to the content within a RecordStore. There are two steps to implementing a sorted query: 1) implement the RecordComparator interface and 2) query the RecordStore using a call to enumerateRecords(), passing an instance of the class implementing RecordComparator as the sort criteria.

The RecordComparator interface supports one method named compare(byte[], byte[]). The two-byte array parameters represent records in the RecordStore. The job of the RecordComparator is to determine which record should come first in the ordering of the result set. How this is determined is the responsibility of the class implementing the compare method of RecordComparator. A result of EQUIVALENT, PRECEDES, or FOLLOWS is returned indicating if the two records should be treated equal, that the first record should remain first, or that the second record should be placed ahead of the first record. (Note: the first record is the record passed in the first parameter position.)

The following code illustrates how a RecordComparator could be implemented to sort a list of contact names by the first name. In this example each record contains the first name, last name, and phone number of a person. Before the compare can take place, the first names must be parsed from each record.

public int compare(byte[] rec1, byte[] rec2){ //convert from a byte[] to a String String s = new String(rec1); //parse out the first name int idx = s.indexOf("|"); String firstName1 = s.substring(0, idx); s = new String(rec2); idx = s.indexOf("|"); String firstName2 = s.substring(0, idx); //determine the relative order of the two records if (firstName1.compareTo(firstName2) == 0){ return RecordComparator.EQUIVALENT; } else if (firstName1.compareTo(firstName2) > 0) { return RecordComparator.FOLLOWS; } else{ return RecordComparator.PRECEDES; } }

Once the first names are parsed, the strings can be compared using the String.compareTo() method to figure out in which order the records should be placed. The query is issued to the RecordStore method enumerateRecords() as shown below. The RecordStore must first be opened before calling this method.

RecordEnumeration e = rs.enumerateRecords(null, new NameComparator(), false);

Figure 2 shows the results of this query using sample data.

Figure 2. Calling All Contacts: Results from a query of a contact RecordStore using sample data.
The boolean parameter passed into the enumerateRecords() method is a flag: setting this flag to true will cause the internal index of the RecordEnumeration to be rebuilt if any records are added or deleted. Note, however, that you may incur a performance penalty for passing true for this parameter. This issue is discussed in detail later in the article.

Filtering Elements in a RecordStore
Now suppose a user wants to search for specific names in the contact database. This can be accomplished by calling enumerateRecords() and passing a class implementing the RecordFilter interface. RecordFilter requires the method matches(byte[]) to be implemented. The byte array parameter is the record the filter needs to match against. A boolean value of true is returned if the record should be included in the enumerateRecords() result set. A value of false is returned to exclude the record from the result set.

The following code implements a search for names starting with a given String.

class NameFilter implements RecordFilter { private String criteria; public NameFilter(String criteria){ this.criteria = criteria; } public boolean matches(byte[] candidate){ //if no criteria present, include all records if ((criteria == null) || (criteria.length()==0)) { return true; } //parse the first name String s = new String(candidate); int idx = s.indexOf("|"); String firstName = s.substring(0, idx); return s.firstName.startsWith(criteria); } }

In this example, a criteria String to match against must be supplied. This is done when the enumerateRecords() method is called. The following code queries for first names beginning with "B."

RecordEnumeration e = rs.enumerateRecords( new NameFilter("B"), null, false);

The results of the query are shown in Figure 3, using the same sample data as in the previous example.

Figure 3. Do B: Here is a call to enumerateRecords(), which passes a filter to find only names beginning with the letter "B."
Of course there will often be cases where an application needs to perform both a sort and a filter in the same query. This is no problem. The following applies to both the NameFilter and the NameComparator to a query.

RecordEnumeration e = rs.enumerateRecords( new NameFilter("B"), new NameComparator(), false);

Once a query result set is obtained, an application can use the result set to display information to the user, send information on a network connection and so forth.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date