Please help on rich:scrollableDataTable / ScrollableTableDat
unlud Mar 13, 2009 1:16 AMHi,
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