Using Search Handlers

Search handlers allow the output from a RETS search to be processed. All search handlers need to implement the SearchHandler interface.

The RET IQ RETS Library provides a some out of the box handlers to get you started. These include the DelimitedSearchResponseHandler which writes the search response directly to an output stream such as a file in a comma delimited format; to collect all the records in memory and access as a list RecordCollectionResponseHandler is provided.

Developers can implement their own handlers to process search results, for example by entering them directly into their internal database.

The SearchHandler Interface

responseCode() is called to notify the handler of the RETS servers RETS response code. A status code of 0 indicates the search was successful and records were found. The status code 20201 indicates that no records were found for the search. Other status codes will be reported. The text is typically that returned by the server detailing the error. The description provides a fuller description of the error.

Most implementations will not to do anything with this notification. All status codes apart from 0 and 20201 will throw a RETSClientExceptionfrom the search method. The 20201 code will call the noRecordsFound() notification on the handler.

  void responseCode(int code, String text, String description);
          

noRecordsFound() is called when the search response contains the RETS code 20201 indicating that no error occurred.

  void noRecordsFound();
          

count() is called when a count is returned in the search response. The parameter represents the number of records that match the query and not necessarily the number of records in the response. This may because the number of records returned in the search was limited by the user or by the target RETS server.

  void count(int count);
          

columns() is called when the column names are received in the search response. The columns parameter contains a list of strings with the names of the columns in the order that they were received. If no results or an error occurs then this method will not be called.

  void columns(List<String> columns);
          

data() is called as each row of data is processed. The order of the list is maintained as per the search results and will match the indexes of the list of column headers. If no results or an error occurs then this method will not be called.

  void data(List<String> data);
          

hasMoreData() is called if a the search response indicates that there is more data available for the query. A further query with the offset set to the number of records already read will allow you to retrieve the remaining records. Note that some servers do not honour the offset parameter.

  void hasMoreData();
          

done() is called when processing of the search response has finished. This method is always called no matter what the response code or error from the server is.

  void done();
          

SearchHandler Example

The example below demonstrates a very simple implementation of a search response handler. The handler outputs the record in a tab delimited format to the console.

  public class MySearchResponseHandler implements SearchResponseHandler 
  {
    public void columns(List<String> columns) {
      for(String column: columns) {
        System.out.print(column + "\t");
      }
      System.out.println("\n");
    }
  
    public void data(List<String> data) {
      for(String value: data) {
        System.out.print(value + "\t");
      }
      System.out.println("\n");
    }
  
    public List<String> getSelect() { return null; }
    public String getPath() { return null;}
    public String getQuery() { return null;}
    public RETSUserSession getSession() { return null; }
    public void responseCode(int code, String text, String description) {}
    public void noRecordsFound() {}
    public void count(int count) {}
    public void delimiter(String hex) {}
    public void hasMoreData() {}
    public void done() {}
    public void setContext(
       RETSUserSession session, String path, String query, List<String> select) {}
  }
          

The AbstractSearchHandler Class

The RETS IQ RETS Library contains AbstractSearchResponseHandler an abstract implementation of SearchResponseHandler. This class provides partial processing of responses that derived handlers may find useful. Such as counting records and providing lookup of fields by field name.

Handlers derived from this can override the Child methods. So rather than trying to override data() they should override dataChild().

The dataChild() notification provides a SearchRecord as a parameter as opposed to a simple list of string values. The SearchRecord object allows lookup of fields by fieldname as well as being able to iterate through the list as normal.

  public void dataChild(SearchRecord record) {
    String mlsnum = record.getValue("MLSNUM");
    System.out.println("MLS Number is " + mlsnum);
  }