Problems with dataTable using ExtendedDataModel
gana May 12, 2009 8:04 AMHi,
I want to test whether the dataTable is providing the lazyloading using extendedDataModel or not.? for that i have written some code. but getting some errors as "Caused by: java.lang.NullPointerException at org.richfaces.demo.extendeddatamodel.DerbyDataModel.getRowCount(DerbyDataModel.java:79)"
I am sending my code. Pls review the code and tell me where was the problem. Here i am not using any DAO's since i am doing for testing only so i have used the queries directly in the dataProvider class. Please find my code below.
DerbyDataModel.java:
--------------------------
package org.richfaces.demo.extendeddatamodel;
import java.io.IOException;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.context.FacesContext;
import org.ajax4jsf.model.DataVisitor;
import org.ajax4jsf.model.Range;
import org.ajax4jsf.model.SequenceRange;
import org.ajax4jsf.model.SerializableDataModel;
/**
*
* @author ias
* This is example class that intended to demonstrate use of ExtendedDataModel and SerializableDataModel.
* This implementation intended to be used as a request scope bean. However, it actually provides serialized
* state, so on a post-back we do not load data from the data provider. Instead we use data that was used
* during rendering.
* This data model must be used together with Data Provider, which is responsible for actual data load
* from the database using specific filtering and sorting. Normally Data Provider must be in either session, or conversation
* scope.
*/
public class DerbyDataModel extends SerializableDataModel {
private DerbyDataProvider dataProvider;
private Integer currentPk;
private Map<Integer,DerbyItem> wrappedData = new HashMap<Integer,DerbyItem>();
private List wrappedKeys = null;
/**
*
*/
private static final long serialVersionUID = -1956179896877538628L;
/**
* 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) {
this.currentPk = (Integer) 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 {
int firstRow = ((SequenceRange)range).getFirstRow();
int numberOfRows = ((SequenceRange)range).getRows();
wrappedKeys = new ArrayList();
for (DerbyItem item:dataProvider.getItemsByrange(new Integer(firstRow), numberOfRows, null, true)) {
wrappedKeys.add(item.getPk());
wrappedData.put(item.getPk(), item);
visitor.process(context, item.getPk(), 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 {
DerbyItem ret = wrappedData.get(currentPk);
if (ret==null) {
ret = getDataProvider().getDemoDataByPk(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().hasDerbyItemByPk(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();
}
/**
* This method suppose to produce SerializableDataModel that will be serialized into View State and used on a post-back.
* In current implementation we just mark current model as serialized. In more complicated cases we may need to
* transform data to actually serialized form.
*/
public SerializableDataModel getSerializableModel(Range range) {
if (wrappedKeys!=null) {
return this;
} else {
return null;
}
}
/**
* This is helper method that is called by framework after model update. In must delegate actual database update to
* Data Provider.
*/
@Override
public void update() {
getDataProvider().update();
}
public DerbyDataProvider getDataProvider() {
return dataProvider;
}
public void setDataProvider(DerbyDataProvider dataProvider) {
this.dataProvider = dataProvider;
}
}
DerbyDataProvider.java:
-----------------------------
package org.richfaces.demo.extendeddatamodel;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
//import java.util.ArrayList;
//import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
//import org.richfaces.demo.common.RandomDataHelper;
public class DerbyDataProvider {
private ResultSet demoData;
private ResultSet demoCount;
private List rs;
public ResultSet getDemoData() {
return demoData;
}
public void setDemoData(ResultSet demoData) {
this.demoData = demoData;
}
@SuppressWarnings("unchecked")
public DerbyDataProvider()
{
Connection conn1 = null;
Connection conn2 = null;
demoData = null;
demoCount = null;
try {
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/derby");
conn1 = ds.getConnection();
conn2 = ds.getConnection();
Statement stmt1 = conn1.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
Statement stmt2 = conn2.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
demoData = stmt1.executeQuery("select * from webscript.demodata");
demoCount = stmt2.executeQuery("select count(*) from webscript.demodata");
demoData.absolute(100);
rs = (List) demoData;
} catch (NamingException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
public int getRowCount() {
int rc = 0;
try{
rc = Integer.parseInt(demoCount.getString(1));
}catch (SQLException e) {
e.printStackTrace();
}
return rc;
}
public List getItemsByrange(Integer startPk, int numberOfRows, String sortField, boolean ascending) {
List ret = new ArrayList();
for (int counter=0; counter<numberOfRows; counter++) {
ret.add(rs.get(startPk.intValue()+counter));
}
return ret;
}
public DerbyItem getDemoDataByPk(Integer pk) {
for (DerbyItem item:rs) {
if (item.getPk().equals(pk)) {
return item;
}
}
throw new RuntimeException("DerbyItem pk="+pk.toString()+" not found");
}
public boolean hasDerbyItemByPk(Integer pk) {
for (DerbyItem item:rs) {
if (item.getPk().equals(pk)) {
return true;
}
}
return false;
}
public void update() {
// nothing need to do
}
}
DerbyItem.java:
-------------------
package org.richfaces.demo.extendeddatamodel;
public class DerbyItem {
private Integer pk;
private String PERIOD_START_TIME;
private String TYPE;
private String BTS_INT_ID;
private String BSC_INT_ID;
private String BSC_NAME;
private String BTS_NAME;
private String PERIOD_DURATION;
private String CONNECTS;
private String ERRORS;
private String BYTES;
@SuppressWarnings("unused")
private DerbyItem() {};
public DerbyItem(Integer pk) {
this.pk = pk;
}
public Integer getPk() {
return pk;
}
public String getPERIOD_START_TIME() {
return PERIOD_START_TIME;
}
public void setPERIOD_START_TIME(String period_start_time) {
PERIOD_START_TIME = period_start_time;
}
public String getTYPE() {
return TYPE;
}
public void setTYPE(String type) {
TYPE = type;
}
public String getBTS_INT_ID() {
return BTS_INT_ID;
}
public void setBTS_INT_ID(String bts_int_id) {
BTS_INT_ID = bts_int_id;
}
public String getBSC_INT_ID() {
return BSC_INT_ID;
}
public void setBSC_INT_ID(String bsc_int_id) {
BSC_INT_ID = bsc_int_id;
}
public String getBSC_NAME() {
return BSC_NAME;
}
public void setBSC_NAME(String bsc_name) {
BSC_NAME = bsc_name;
}
public String getBTS_NAME() {
return BTS_NAME;
}
public void setBTS_NAME(String bts_name) {
BTS_NAME = bts_name;
}
public String getPERIOD_DURATION() {
return PERIOD_DURATION;
}
public void setPERIOD_DURATION(String period_duration) {
PERIOD_DURATION = period_duration;
}
public String getCONNECTS() {
return CONNECTS;
}
public void setCONNECTS(String connects) {
CONNECTS = connects;
}
public String getERRORS() {
return ERRORS;
}
public void setERRORS(String errors) {
ERRORS = errors;
}
public String getBYTES() {
return BYTES;
}
public void setBYTES(String bytes) {
BYTES = bytes;
}
}
If any one can help are very much appreciated..
Thanks in Advance,
Gana.