5 Replies Latest reply on Mar 16, 2009 1:01 PM by Konstantin Mishin

    Please help on rich:scrollableDataTable / ScrollableTableDat

    ludovic havet Newbie

      Hi,

      I try to have such a component for pagination with a table which has a primary key of type string.

      My issue for the moment is that when the setRowKey method of ScrollableTableDataModel extended class is called, I get such an exception:

      java.lang.ClassCastException: org.richfaces.model.ScrollableTableDataModel$SimpleRowKey cannot be cast to java.lang.String
       at org.unludo.iknow.jsf.beans.ObjectObjectDataModel.setRowKey(ObjectObjectDataModel.java:72)
       at org.richfaces.model.DataModelCache.setRowKey(DataModelCache.java:185)
       at org.ajax4jsf.component.UIDataAdaptor.setRowKey(UIDataAdaptor.java:351)
      


      I searched but don't knw what to try next.

      I post the code:

      1/ the xhtml piece:
       <rich:scrollableDataTable
       height="400px" width="700px" rows="10"
       value="#{objectObjectDataModel}" columnClasses="col1" var="objectObjectVO">
       <rich:column id="object">
       <f:facet name="header">Object</f:facet>
       <h:outputText value="#{objectObjectVO.id}" />
       </rich:column>
       </rich:scrollableDataTable>
      


      2/ The model:
      public class ObjectObjectDataModel extends ScrollableTableDataModel {
      
       private String currentPk;
       private Map<String,ObjectObjectVO> wrappedData = new HashMap<String,ObjectObjectVO>();
       private List<String> wrappedKeys = null;
       private ObjectObjectDataProvider dataProvider;
      
       private static Logger logger = Logger.getLogger(ObjectObjectDataModel.class);
      
       /**
       *
       */
       private static final long serialVersionUID = -1956179896875438628L;
      
       public ObjectObjectDataModel()
       {
       logger.info("creation of data provider") ;
       dataProvider = new ObjectObjectDataProvider();
       }
      
       /**
       * This method never called from framework.
       * (non-Javadoc)
       * @see org.ajax4jsf.model.ExtendedDataModel#getRowKey()
       */
       @Override
       public Object getRowKey() {
       return currentPk;
       }
       /**
       * This method normally called by Visitor before request Data Row.
       */
       @Override
       public void setRowKey(Object key) {
       logger.info("setRowKey " + key + key != null ? key.getClass() : "") ;
       this.currentPk = (String) key;
      
       }
       /**
       * This is main part of Visitor pattern. Method called by framework many times during request processing.
       */
       @Override
       public void walk(FacesContext context, DataVisitor visitor, Range range, Object argument) throws IOException {
       logger.info("walk visitor " + visitor) ;
       int firstRow = ((SequenceRange)range).getFirstRow();
       int numberOfRows = ((SequenceRange)range).getRows();
       wrappedKeys = new ArrayList<String>();
       for (ObjectObjectVO item:getDataProvider().getItemsByrange(firstRow, numberOfRows))
       {
       wrappedKeys.add(item.getId());
       wrappedData.put(item.getId(), item);
       visitor.process(context, item.getId(), argument);
       }
       }
       /**
       * This method must return actual data rows count from the Data Provider. It is used by pagination control
       * to determine total number of data items.
       */
       private Integer rowCount; // better to buffer row count locally
       @Override
       public int getRowCount() {
       if (rowCount==null) {
       rowCount = new Integer(getDataProvider().getRowCount());
       return rowCount.intValue();
       } else {
       return rowCount.intValue();
       }
       }
       /**
       * This is main way to obtain data row. It is intensively used by framework.
       * We strongly recommend use of local cache in that method.
       */
       @Override
       public Object getRowData() {
       if (currentPk==null) {
       return null;
       } else {
       ObjectObjectVO ret = wrappedData.get(currentPk);
       if (ret==null)
       {
       ret = (ObjectObjectVO) getDataProvider().getItemByKey(currentPk);
       wrappedData.put(currentPk, ret);
       return ret;
       }
       else
       {
       return ret;
       }
       }
       }
      
       /**
       * Unused rudiment from old JSF staff.
       */
       @Override
       public int getRowIndex() {
       throw new UnsupportedOperationException();
       }
      
       /**
       * Unused rudiment from old JSF staff.
       */
       @Override
       public Object getWrappedData() {
       throw new UnsupportedOperationException();
       }
      
       /**
       * Never called by framework.
       */
       @Override
       public boolean isRowAvailable() {
       if (currentPk==null) {
       return false;
       } else {
       return getDataProvider().hasObjectObjectVOByPk(currentPk);
       }
       }
      
       /**
       * Unused rudiment from old JSF staff.
       */
       @Override
       public void setRowIndex(int rowIndex) {
       throw new UnsupportedOperationException();
       }
      
       /**
       * Unused rudiment from old JSF staff.
       */
       @Override
       public void setWrappedData(Object data) {
       throw new UnsupportedOperationException();
       }
      
       public ObjectObjectDataProvider getDataProvider()
       {
       logger.info("data provider has been accessed") ;
       return dataProvider;
       }
      
       public void setDataProvider(ObjectObjectDataProvider p_o)
       {
       logger.info("data provider has been set") ;
       dataProvider = p_o;
       }
      
      
       @Override
       public
       List loadData(int arg0, int arg1, SortOrder arg2)
       {
       Iterable<ObjectObjectVO> it;
      
       it = getDataProvider().getItemsByrange(arg0, arg1);
      
       if(it == null)
       {
       logger.error("loadData returned null") ;
       return null;
       }
      
       return (List) it;
       }
      
      }


      3/the data provider
      /*
      * To change this template, choose Tools | Templates
      * and open the template in the editor.
      */

      package org.unludo.iknow.jsf.beans.ObjectObject;

      import java.util.List;
      import javax.ejb.EJB;
      import javax.naming.InitialContext;
      import javax.naming.NamingException;
      import org.apache.log4j.Logger;
      import org.richfaces.model.DataProvider;
      import org.unludo.iKnow.ejb.session.ObjectObjectFacadeLocal;
      import org.unludo.iKnow.vo.ObjectObjectVO;

      /**
      *
      * @author Ludovic
      */
      @EJB(name="objectobjectfacaderef", beanInterface=ObjectObjectFacadeLocal.class)
      public class ObjectObjectDataProvider implements DataProvider
      {
      private static Logger logger = Logger.getLogger(ObjectObjectDataProvider.class);

      ObjectObjectFacadeLocal oObjectObjectFacade;

      public ObjectObjectDataProvider()
      {
      try
      {
      InitialContext ic = new InitialContext();
      oObjectObjectFacade = (ObjectObjectFacadeLocal) ic.lookup("java:comp/env/objectobjectfacaderef");
      logger.info("getRowCount oObjectObjectFacade constructor" + oObjectObjectFacade) ;
      }
      catch (NamingException ex)
      {
      logger.error("getRowCount oObjectObjectFacade null " + ex) ;
      }
      }

      public
      Iterable<ObjectObjectVO> getItemsByrange(int firstRow, int numberOfRows)
      {
      List<ObjectObjectVO> lvo =oObjectObjectFacade.getList(firstRow, numberOfRows);

      logger.info("getItemsByrange first row "+ firstRow + "nb rows " + numberOfRows + " -> " + lvo) ;

      return lvo;
      }

      @Override
      public
      int getRowCount()
      {
      Long nbObject = oObjectObjectFacade.count();
      logger.info("getRowCount nb objects" + nbObject);

      return nbObject.intValue();
      }

      public
      int count()
      {

      Long nbObject = oObjectObjectFacade.count();

      return nbObject.intValue();
      }

      @Override
      public
      List getItemsByRange(int arg0, int arg1)
      {
      return oObjectObjectFacade.getList(arg0, arg1);
      }

      @Override
      public
      Object getItemByKey(Object arg0)
      {
      return oObjectObjectFacade.find((String)arg0);
      }

      @Override
      public
      Object getKey(Object arg0)
      {
      return ((ObjectObjectVO)arg0).getId();
      }

      public boolean hasObjectObjectVOByPk(String p_sId)
      {
      return (getItemByKey(p_sId) != null);
      }
      }


      Any help would be greatly appreciated.
      Also if some one knows about a consistent example of this component, I would be interested. If not, I will post something if I find a solution.

      Thank you
      Ludo