advantage : assume that the query results 1000 records. in this implementation at server side u cache a 100 records (page size) out of 1000
and deliver these 100 and eventually all 1000 records to client in a frame requested by client (say 10 records per page)
disadvantage : the com.sun.rowset.CachedRowSetImpl DOES NOT WORK SOMETIMES.
i dont know ! i was not able to look into its impl as i guess its source is not available.
below is the whole code!
// stateful session bean interface
package session;
// add imports
@Remote()
public interface CachedRowSetListerSessionRemote
extends CachedRowSetValueListIterator
{
public void executeStaffSearch(CriteriaVO oCriteriaVO,
RequiredFieldsVO oRequiredFieldsVO) throws ListHandlerException;
}
// stateful session bean impl
package session;
// add imports
@Stateful(mappedName = "CachedListerSessionBean")
public class CachedRowSetListerSessionBean
extends CachedRowSetValueListHandler
implements CachedRowSetListerSessionRemote
{
public void executeStaffSearch(CriteriaVO oCriteriaVO,
RequiredFieldsVO oRequiredFieldsVO) throws ListHandlerException
{
// Create DAO instance and fetch the list
// according to the required Fields
StaffDAO oStaffDAO = DAOFactory.getDAOFactory(DAOFactory.POSTGRES)
.getStaffDAO();
// Set the total size of the list
int iSize = oStaffDAO.getListSize();
setSize(iSize);
// get the list from dao and set it
// this list is nothing but custom list impl
// (iterating over list is simple compared to that of cachedrowset cursor !)
// get the required level of data
switch(oRequiredFieldsVO.getListingLevel())
{
// if L1 : minimum data (from a same table all compulsary columns)
case L1:
setList(new RowSetWrapperList(oStaffDAO.getL1Detail(oCriteriaVO),
iSize));
break;
// if L2 : medium data (from a same table all columns)
case L2:
setList(new RowSetWrapperList(oStaffDAO.getL2Detail(oCriteriaVO),
iSize));
break;
// if L2 : maximum data (from a same table as well as related relational tables data)
case L3:
setList(new RowSetWrapperList(oStaffDAO.getL3Detail(oCriteriaVO),
iSize));
break;
}
setList(new RowSetWrapperList(oStaffDAO.getList(oCriteriaVO),iSize));
}
}
}
// value list handler class
package session;
// add imports
public abstract class CachedRowSetValueListHandler
implements ValueListIterator
{
private List moList;
private ListIterator moListIterator;
private int miListSize;
public CachedRowSetValueListHandler()
{
moLogger.debug("Called the constructor");
}
protected void setSize(int lSize)
{
miListSize = lSize;
}
public int getSize()
{
moLogger.debug("Get the size in the getSize method: " + miListSize);
return miListSize;
}
public List getNextElements(int iSize) throws IteratorException
{
int iCount = 0;
Object oObject = null;
ArrayList oList = new ArrayList();
if(moListIterator != null)
{
while(moListIterator.hasNext() && (iCount = 0 && iStartIndex < getSize())
{
for(int iCounter = iStartIndex + 1; iCounter <= iEndIndex; iCounter++)
{
oList.add(moList.get(iCounter));
}
}
else
{
throw new IteratorException("Index out of bound");
}
return oList;
}
public void resetIndex()
{
if(moListIterator != null)
{
moListIterator = moList.listIterator();
}
}
protected void setList(List oList)
{
this.moList = oList;
moLogger.debug("Get the size in the setList method: " + moList.size());
this.moListIterator = moList.listIterator();
}
}
// value list iterator
package session;
public interface ValueListIterator
{
public int getSize();
public List getElements(int iStartIndex, int iEndIndex)
throws IteratorException;
public List getNextElements(int iSize) throws IteratorException;
public List getPreviousElements(int iSize) throws IteratorException;
public void resetIndex();
}
// row set wrapper list impl
package session;
//add imports
public class RowSetWrapperList
implements List, Serializable
{
private static final Logger moLogger = Logger
.getLogger(RowSetWrapperList.class
.getName());
private CachedRowSet moCachedRowSet = null;
private int miSize = 0;
public int micurrentPage = 0;
public int miMaxNoOfPages = 0;
public static int ROW_SET_PAGE_SIZE = 100;
public RowSetWrapperList(CachedRowSet oCachedRowSet, int iSize)
{
moCachedRowSet = oCachedRowSet;
miSize = iSize;
// find max no of pages
if((miSize % ROW_SET_PAGE_SIZE) == 0)
{
miMaxNoOfPages = miSize / ROW_SET_PAGE_SIZE;
}
else
{
miMaxNoOfPages = miSize / ROW_SET_PAGE_SIZE;
miMaxNoOfPages = miMaxNoOfPages + 1;
}
moLogger.debug("max no of pages are : " + miMaxNoOfPages);
}
public int size()
{
return miSize;
}
public boolean isEmpty()
{
return miSize == 0;
}
public boolean contains(Object oObject)
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support contains operation");
}
public Iterator iterator()
{
return this.listIterator();
}
public Object[] toArray()
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support toArray operation");
}
public Object[] toArray(Object[] aoObject)
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support toArray operation");
}
public boolean add(Object oObject)
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support add operation");
}
public boolean remove(Object oObject)
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support remove operation");
}
public boolean containsAll(Collection oCollection)
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support containsAll operation");
}
public boolean addAll(Collection oCollection)
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support addAll operation");
}
public boolean addAll(int iIndex, Collection oCollection)
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support addAll operation");
}
public boolean removeAll(Collection oCollection)
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support removeAll operation");
}
public boolean retainAll(Collection oCollection)
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support retainAll operation");
}
public void clear()
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support clear operation");
}
public Object get(int iIndex)
{
try
{
moLogger.debug("get request for index : " + iIndex);
if(iIndex > miSize)
{
moLogger.error("index " + iIndex + " out of bound !");
throw new IndexOutOfBoundsException("index " + iIndex
+ " out of bound !");
}
// find on which page this object is
int iPage = 0;
int iPageLocation = iIndex % ROW_SET_PAGE_SIZE;
if(iPageLocation == 0)
{
iPage = iIndex / ROW_SET_PAGE_SIZE;
iPage--;
iPageLocation = ROW_SET_PAGE_SIZE;
}
else
{
iPage = iIndex / ROW_SET_PAGE_SIZE;
}
moLogger.debug("the requested object is on page " + iPage);
moLogger.debug("the requested object is at location "
+ iPageLocation);
// get the object
// check whether object is on current page
if(micurrentPage == iPage)
{
// object is on same page
// get it
moCachedRowSet.absolute(iPageLocation);
return createStaffTO();
}
// object is not on current page
// go to that page
if(micurrentPage < iPage)
{
// object is ahead of current page
int iPageCounter = 0;
int iHowMuchAhead = iPage - micurrentPage;
while(iPageCounter < iHowMuchAhead)
{
goToNextPage();
micurrentPage++;
iPageCounter++;
}
// get the object
moCachedRowSet.beforeFirst();
moCachedRowSet.absolute(iPageLocation);
return createStaffTO();
}
// object is behind of current page
int iPageCounter = 0;
int iHowMuchBehind = micurrentPage - iPage;
while(iPageCounter < iHowMuchBehind)
{
goToPreviousPage();
micurrentPage--;
iPageCounter++;
}
// get the object
moCachedRowSet.afterLast();
moCachedRowSet.absolute(iPageLocation);
return createStaffTO();
}
catch(SQLException oSQLException)
{
moLogger.error("Error : ", oSQLException);
throw new RuntimeException("Error : " + oSQLException.getMessage());
}
}
private void goToNextPage() throws SQLException
{
boolean bReturn = moCachedRowSet.nextPage();
if(bReturn)
{
moLogger.debug("more pages exists ");
}
else
{
moLogger.debug("this is last page");
}
// again go to next page
// i dont know ... but it works
// does any one has any explaination ?
// more info
http://forum.java.sun.com/thread.jspa?threadID=769985
if(!moCachedRowSet.nextPage())
{
moCachedRowSet.previousPage();
}
}
private void goToPreviousPage() throws SQLException
{
boolean bReturn = moCachedRowSet.previousPage();
if(bReturn)
{
moLogger.debug("yup its previous page now");
}
else
{
moLogger.debug("this is the first page");
}
}
public Object set(int iIndex, Object oElement)
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support set operation");
}
public void add(int iIndex, Object oElement)
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support add operation");
}
public Object remove(int iIndex)
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support remove operation");
}
public int indexOf(Object oObject)
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support indexOf operation");
}
public int lastIndexOf(Object oObject)
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support lastIndexOf operation");
}
public ListIterator listIterator()
{
return new DataRowListIterator();
}
public ListIterator listIterator(int iIndex)
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support listIterator operation");
}
public List subList(int iFromIndex, int iToIndex)
{
throw new UnsupportedOperationException(
"RowSetWrapperList does not support subList operation");
}
private StaffTO createStaffTO()
{
StaffTO oStaffTO = null;
moLogger.debug("inside Create Array List");
try
{
oStaffTO = new StaffTO();
oStaffTO.setStaffId(moCachedRowSet.getInt(1));
moLogger.debug("inside Create Array List -- "
+ oStaffTO.getStaffId());
oStaffTO.setFirstName(moCachedRowSet.getString(2));
moLogger.debug("inside Create Array List -- "
+ oStaffTO.getFirstName());
oStaffTO.setMiddleName(moCachedRowSet.getString(3));
moLogger.debug("inside Create Array List -- "
+ oStaffTO.getMiddleName());
oStaffTO.setLastName(moCachedRowSet.getString(4));
moLogger.debug("inside Create Array List -- "
+ oStaffTO.getLastName());
oStaffTO.setDesignation(StaffDesignation.values()[moCachedRowSet.getInt(5)]);
moLogger.debug("inside Create Array List -- "
+ oStaffTO.getDesignation());
}
catch(SQLException oSQLException)
{
moLogger
.error("Could not fetch data from resultset", oSQLException);
throw new InternalException(
"Could not fetch data from resultset : "
+ oSQLException.getMessage());
}
return oStaffTO;
}
private class DataRowListIterator
implements ListIterator
{
private int miCurrentRow = 0;
public void add(Object oObject)
{
throw new UnsupportedOperationException(
"DataRowListIterator does not support add operation");
}
public boolean hasNext()
{
return miCurrentRow != size();
}
public boolean hasPrevious()
{
return miCurrentRow != 0;
}
public Object next()
{
return get(++miCurrentRow);
}
public int nextIndex()
{
return miCurrentRow;
}
public Object previous()
{
return get(miCurrentRow--);
}
public int previousIndex()
{
return miCurrentRow - 1;
}
public void remove()
{
throw new UnsupportedOperationException(
"DataRowListIterator does not support remove operation");
}
public void set(Object oObject)
{
throw new UnsupportedOperationException(
"DataRowListIterator does not support set operation");
}
}
}
// staff dao
package dao;
// add imports
public class StaffDAO
{
private static final Logger moLogger = Logger.getLogger(CourseDAO.class
.getName());
private final String ASCENDING = "asc";
private final String DESCENDING = "desc";
private static StaffDAO moStaffDAO = null;
private StaffDAO()
{
// do nothing
}
public static synchronized StaffDAO getInstance()
{
if(moStaffDAO == null)
{
moStaffDAO = new StaffDAO();
}
return moStaffDAO;
}
public CachedRowSet getL1Detail(CriteriaVO oCriteriaVO)
{
String szSortCriteria = null;
CachedRowSet oCachedRowSet = null;
try
{
if(oCriteriaVO.isAscending())
{
szSortCriteria = ASCENDING;
}
else
{
szSortCriteria = DESCENDING;
}
oCachedRowSet = new CachedRowSetImpl();
oCachedRowSet.setDataSourceName(PostgresDAOFactory.DATASOURCE);
oCachedRowSet.setPageSize(RowSetWrapperList.ROW_SET_PAGE_SIZE);
oCachedRowSet
.setCommand("select staff_id, first_name, middle_name, last_name, designation from staff "
+ " where is_deleted != '1' order by first_name "
+ szSortCriteria);
oCachedRowSet.execute();
}
catch(SQLException oSQLException)
{
moLogger.error("cannot execute at level1", oSQLException);
throw new InternalException("cannot execute at level1 : "
+ oSQLException.getMessage());
}
return oCachedRowSet;
}
public int getListSize()
{
Connection oConnection = null;
Statement oStatement = null;
ResultSet oResultSet = null;
try
{
oConnection = PostgresDAOFactory.createConnection();
oStatement = oConnection.createStatement();
oResultSet = oStatement
.executeQuery("SELECT count(*) from staff WHERE is_deleted !='1'");
oResultSet.next();
int iCount = oResultSet.getInt(1);
moLogger.debug("Result Set Size" + iCount);
return iCount;
}
catch(SQLException oSQLException)
{
moLogger.error("cannot execute at get Size", oSQLException);
throw new InternalException("cannot execute at get Size -- "
+ oSQLException.getMessage());
}
finally
{
try
{
if(oResultSet != null)
{
oResultSet.close();
}
}
catch(SQLException oSQLException)
{
// ignore
}
try
{
if(oStatement != null)
{
oStatement.close();
}
}
catch(SQLException oSQLException)
{
// ignore
}
try
{
if(oConnection != null)
{
oConnection.close();
}
}
catch(SQLException oSQLException)
{
// ignore
}
}
}
}