J2ME Java

/*--------------------------------------------------
* SearchStreams.java
*
* Display a Form and TextField for searching records
* Each record contains multiple Java data types -  
* (String, boolean and integer). Use the String 
* data for searching
*
* Uses: Enumeration, RecordFilter
*
* Example from the book:     Core J2ME Technology
* Copyright John W. Muchow   http://www.CoreJ2ME.com
* You may use/modify for any non-commercial purpose
*-------------------------------------------------*/
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;
import javax.microedition.lcdui.*;
public class SearchStreams extends MIDlet implements CommandListener
{
  private Display display;      // Reference to Display object
  private Form fmMain;         // The main form
  private StringItem siMatch;  // The matching text, if any
  private Command cmFind;      // Command to search record store
  private Command cmExit;      // Command to insert items
  private TextField tfFind;    // Search text
  private RecordStore rs = null;    // Record store
  static final String REC_STORE = "db_7"; // Name of record store
  public SearchStreams()
  {
    display = Display.getDisplay(this);
    
    // Define textfield, stringItem and commands
    tfFind = new TextField("Find", "", 10, TextField.ANY); 
    siMatch = new StringItem(null, null);    
    cmExit = new Command("Exit", Command.EXIT, 1);
    cmFind = new Command("Find", Command.SCREEN, 2);
    // Create the form, add commands
    fmMain = new Form("Record Search");
    fmMain.addCommand(cmExit);    
    fmMain.addCommand(cmFind);
  
    // Append textfield and stringItem
    fmMain.append(tfFind);
    fmMain.append(siMatch);
    // Capture events
    fmMain.setCommandListener(this);    
    //--------------------------------
    // Open and write to record store
    //--------------------------------
    openRecStore();   // Create the record store
    writeTestData();  // Write a series of records
  }
  public void destroyApp( boolean unconditional )
  {
    closeRecStore();  // Close record store
  }
  public void startApp()
  {
    display.setCurrent(fmMain);   
  }
  public void pauseApp()
  {
  }
  public void openRecStore()
  {
    try
    {
      // The second parameter indicates that the record store
      // should be created if it does not exist
      rs = RecordStore.openRecordStore(REC_STORE, true );
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }    
  
  public void closeRecStore()
  {
    try
    {
      rs.closeRecordStore();
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  /*--------------------------------------------------
  * Create three arrays to write into record store
  *-------------------------------------------------*/
  public void writeTestData()
  {
   String[] pets = {"duke - big, goofy golden retriever", 
                    "tiger - we found in a field", 
                    "spike - loves chasing car tires",
                     "beauregard - barks at everything"};
   boolean[] dog = {true, false, true, true};    
   int[] rank = {3, 0, 1, 2};
 
   writeStream(pets, dog, rank);                    
  }
  /*--------------------------------------------------
  * Write to record store using streams.
  *-------------------------------------------------*/  
  public void writeStream(String[] sData, boolean[] bData, int[] iData)
  {
    try
    {
      // Only add the records once
      if (rs.getNumRecords() > 0)
        return;
      
       // Write data into an internal byte array
      ByteArrayOutputStream strmBytes = new ByteArrayOutputStream();
      
      // Write Java data types into the above byte array
      DataOutputStream strmDataType = new DataOutputStream(strmBytes);
      
      byte[] record;
      for (int i = 0; i < sData.length; i++)
      {
        // Write Java data types      
        strmDataType.writeUTF(sData[i]);    
        strmDataType.writeBoolean(bData[i]);
        strmDataType.writeInt(iData[i]);                
        
        // Clear any buffered data
        strmDataType.flush();
        // Get stream data into byte array and write record
        record = strmBytes.toByteArray();
        rs.addRecord(record, 0, record.length);      
        // Toss any data in the internal array so writes 
        // starts at beginning (of the internal array)
        strmBytes.reset();
      }
      
      strmBytes.close();
      strmDataType.close();
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  
  /*--------------------------------------------------
  * Search using enumerator and record filter
  *-------------------------------------------------*/
  private void searchRecordStore()
  {
  try
    {
      // Record store is not empty
      if (rs.getNumRecords() > 0)
      {
        // Setup the search filter with the user requested text
        SearchFilter search = 
              new SearchFilter(tfFind.getString());
        
        RecordEnumeration re = 
              rs.enumerateRecords(search, null, false);
        // A match was found using the filter        
        if (re.numRecords() > 0)
        {
          // Read from the specified byte array
          ByteArrayInputStream strmBytes = 
                new ByteArrayInputStream(re.nextRecord());
          // Read Java data types from the above byte array
          DataInputStream strmDataType = 
                new DataInputStream(strmBytes);
          // Show matching result in stringItem component on form          
          siMatch.setText(strmDataType.readUTF());
    
          search.searchFilterClose(); // Close record filter
          strmBytes.close();          // Close stream
          strmDataType.close();       // Close stream
          re.destroy();               // Free enumerator
        }
      }
    }
    catch (Exception e)
    {
      db(e.toString());
    }
  }
  public void commandAction(Command c, Displayable s)
  {
    if (c == cmFind)
    {
      searchRecordStore();
    }
    else if (c == cmExit)
    {
      destroyApp(false);
      notifyDestroyed();
    }
  }  
    
  /*--------------------------------------------------
  * Simple message to console for debug/errors
  * When used with Exceptions we should handle the 
  * error in a more appropriate manner.
  *-------------------------------------------------*/
  private void db(String str)
  {
    System.err.println("Msg: " + str);
  }
}
/*--------------------------------------------------
* Search for text within a record
* Each record passed in contains multiple Java data 
* types (String, boolean and integer) 
*-------------------------------------------------*/
class SearchFilter implements RecordFilter
{
  private String searchText = null;
  
   // Read from a specified byte array
  private ByteArrayInputStream strmBytes = null;
  // Read Java data types from the above byte array  
  private DataInputStream strmDataType = null;
  public SearchFilter(String searchText)
  {
    // This is the text to search for
    this.searchText = searchText.toLowerCase();
  }
  // Cleanup
  public void searchFilterClose()
  {
    try
    {
      if (strmBytes != null)
        strmBytes.close();
      if (strmDataType != null)
        strmDataType.close();
    }
    catch (Exception e)
    {}
  }
  public boolean matches(byte[] candidate)
  {
    String str = null;
    
    try
    {
      strmBytes = new ByteArrayInputStream(candidate);
      strmDataType = new DataInputStream(strmBytes);
      
      // Although 3 pieces of data were written to
      // the record (String, boolean and integer) 
      // we only need one read because the string to 
      // search is the first "field" in the record
      str = strmDataType.readUTF().toLowerCase();
    }
    catch (Exception e)
    { 
      return false;
    }
    // Look for a match     
    if (str != null && str.indexOf(searchText) != -1)
      return true;
    else
      return false;
  }
}