title: ExtendedDataTable in RichFaces 4: DataModel handling
body: <p>I have another question, somewhat related to the one I posted in January.  I have a list, which is rich:extendedDataTable component, and it gets updated on the fly, as the user types his search criteria in a separate text box (i.e. the user types in the first 4 characters and as he keeps typing, the results list changes).  And in the end it works fine, when I use RichFaces 3, but as I upgraded to RichFaces 4, I've got all sorts of compilation problems.  The following classes are no longer accessible and there no suitable replacement for these, it seems:</p>
  
  <pre><code>org.richfaces.model.DataProvider
  org.richfaces.model.ExtendedTableDataModel
  org.richfaces.model.selection.Selection
  org.richfaces.model.selection.SimpleSelection
  </code></pre>
  
  <p>Here is what it was before:</p>
  
  <p>This is the input text that should trigger the search logic:</p>
  
  <pre><code>&lt;h:inputText id="firmname" value="#{ExtendedTableBean.searchValue}"&gt;
     &lt;a4j:support ajaxSingle="true" eventsQueue="firmListUpdate"  
                  reRender="resultsTable" 
                  actionListener="#{ExtendedTableBean.searchForResults}" event="onkeyup" /&gt;
  &lt;/h:inputText&gt;
  </code></pre>
  
  <p>Action listener is what should update the list. Here is the extendedDataTable, right below the inputText:</p>
  
  <pre><code>&lt;rich:extendedDataTable tableState="#{ExtendedTableBean.tableState}" var="item"
                         id="resultsTable" value="#{ExtendedTableBean.dataModel}"&gt;
  
          ... &lt;%-- I'm listing columns here --%&gt;
  
  &lt;/rich:extendedDataTable&gt;
  </code></pre>
  
  <p>And here's the back-end code, where I use my data model handling:</p>
  
  <pre><code>/*
   * To change this template, choose Tools | Templates
   * and open the template in the editor.
   */
  
  package com.beans;
  
  import java.io.FileInputStream;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.ConcurrentModificationException;
  import java.util.List;
  import java.util.Properties;
  import java.util.concurrent.CopyOnWriteArrayList;
  import javax.faces.context.FacesContext;
  import javax.faces.event.ActionEvent;
  import org.richfaces.model.DataProvider;
  import org.richfaces.model.ExtendedTableDataModel;
  
  public class ExtendedTableBean {      
      private String sortMode="single";
      private ExtendedTableDataModel&lt;ResultObject&gt; dataModel;
      //ResultObject is a simple pojo and getResultsPerValue is a method that 
      //read the data from the properties file, assigns it to this pojo, and
      //adds a pojo to the list 
  
      private Object tableState;
      private List&lt;ResultObject&gt; results = new CopyOnWriteArrayList&lt;ResultObject&gt;();
      private List&lt;ResultObject&gt; selectedResults = 
                                        new CopyOnWriteArrayList&lt;ResultObject&gt;();
  
      private String searchValue;
  
      /**
       * This is the action listener that the user triggers, by typing the search value
       */
      public void searchForResults(ActionEvent e) {
         synchronized(results) {
             results.clear();
         }        
  
         //I don't think it's necessary to clear results list all the time, but here
         //I also make sure that we start searching if the value is at least 4 
         //characters long
         if (this.searchValue.length() &gt; 3) {
             results.clear();
             updateTableList();
         } else {
             results.clear();
         }
  
         dataModel = null; // to force the dataModel to be updated.
      }
  
      public List&lt;ResultObject&gt; getResultsPerValue(String searchValue) {
          List&lt;ResultObject&gt; resultsList = new CopyOnWriteArrayList&lt;ResultObject&gt;();
  
          //Logic for reading data from the properties file, populating ResultObject
          //and adding it to the list
  
          return resultsList;
      }
  
      /**
       * This method updates a firm list, based on a search value
       */
      public void updateTableList() {
          try {              
              List&lt;ResultObject&gt; searchedResults = getResultsPerValue(searchValue);
  
              //Once the results have been retrieved from the properties, empty 
              //current firm list and replace it with what was found.
  
              synchronized(firms) {
                  firms.clear();
                  firms.addAll(searchedFirms);
              }
          } catch(Throwable xcpt) {
              //Exception handling
          }
      }
  
      /**
       * This is a recursive method, that's used to constantly keep updating the 
       * table list.
       */
      public synchronized ExtendedTableDataModel&lt;ResultObject&gt; getDataModel() {
          try {
              if (dataModel == null) {
                  dataModel = new ExtendedTableDataModel&lt;ResultObject&gt;(
                                 new DataProvider&lt;ResultObject&gt;() {
                                     public ResultObject getItemByKey(Object key) {
                                         try {
                                             for(ResultObject c : results) {
                                                 if (key.equals(getKey(c))){
                                                     return c;
                                                 }
                                             }
                                         } catch (Exception ex) {
                                             //Exception handling
                                         }
                                         return null;
                                     }
  
                                     public List&lt;ResultObject&gt; getItemsByRange(
                                                   int firstRow, int endRow) {
                                         return Collections.unmodifiableList(results.subList(firstRow, endRow));
                                     }
  
                                     public Object getKey(ResultObject item) {
                                         return item.getResultName();
                                     }
  
                                     public int getRowCount() {
                                         return results.size();
                                     }
                                });
              }
          } catch (Exception ex) {
              //Exception handling    
          }
  
          return dataModel;
      }
  
      //Getters and setters 
  
  }
  </code></pre>
  
  <p>Now that the classes ExtendedTableDataModel and DataProvider are no longer available, what should I be using instead?  RichFaces forum claims there's really nothing and developers are pretty much on their own there (meaning they have to do their own implementation).  Does anyone have any other idea or suggestion?  </p>
  
  <p>Thanks again for all your help and again, sorry for a lengthy question.</p>