On Thu, 15 Nov 2001, Brian Cochran wrote:
> Date: Thu, 15 Nov 2001 18:31:58 -0500
> From: Brian Cochran <[EMAIL PROTECTED]>
> Reply-To: Struts Developers List <[EMAIL PROTECTED]>
> To: Struts Developers List <[EMAIL PROTECTED]>
> Subject: Other possible tools for paging collections
>
> Writing paging (i.e. next, previous, etc) iterators can be a real pain to do
> correctly (at least it is for me).
No, not just for you ... it is a real pain, especially if you want to
generalize your design :-).
> Looking at the petstore, they seem to wuss out on doing it nice. It occured
> to me that there are a few options as far as doing iteration over pages.
>
> 1) retrieve all results and keep them in memory (in a session var i guess)
> while the user pages through them.
Works for small result sets, not large ones.
> 2) go to the db every time.
Ideally, you would keep track of where you are in a way that lets you
start "where you left off", so you don't have to skip all the rows that go
on previous pages.
>
> 3) JDBC 2.0 allows scrollable recordsets so you could have time-out-able
> recordsets that essentially close themselves
> on a time expiration and may reopen themselves if needed. (May be some
> nasty concurrency problems with this)
>
The biggest problem is that keeping the RowSet open means you are also
keeping the underlying Connection (instead of returning it to the pool),
so you end up needing *lots* more database connections for a given user
population.
> 4) create a hybrid that will cache some of the pages and go to the database
> if needed. Maybe be able to configure
> the number of pages to cache. Really cool would be able to change it
> dynamically.
>
> 5) somebody elses neat idea
>
An approach I've been dabbling with is in the "Workflow" project of the
jakarta-commons-sandbox CVS repository, and also available as a nightly
download:
http://jakarta.apache.org/builds/jakarta-commons/nightly/commons-workflow/
The basic idea is that you "script" the flow of processing for a
particular multi-page interaction with the user in an XML-format file,
which includes the ability to support paging. While my original focus was
on wizard-style interactions, it would be possible to use this as the
basis for a paging mechanism as well, but still be extensible.
I believe there is also an example app using this in the "contrib"
directory of the HEAD branch of Struts, and therefore available in the
nightly downloads.
Craig
>
> But whatever is used there is the basic principle of getEntities(int index,
> int span). So what do you guys think about
> a series of paging iterators that looked something like this.
>
> abstract class PagingIterator
> abstract List getEntities(int startIndex, int span)
> int getPage()
> void setPage(int page)
> boolean hasNextPage()
> void nextPage()
> boolean hasPreviousPage()
> void previousPage()
>
> class RequeryPagingIterator extends PagingIterator // like the petstore
> abstract List getEntities(int startIndex, int span)
>
>
> class CacheingPagingIterator extends PaginingIterator // good for a lot
> of smaller datasets
> List _AllEntities = null;
> List getEntities(int startIndex, int span){
> if(_AllEntities == null){
> getAllEntities();
> }
> int stopIndex = max(startIndex + span, _AllEntities.size() - 1);
> return _AllEntites.subList(startIndex, stopIndex);
>
> }
>
> class MultiplePageCachingPagingIterator extends PagingIterator // great
> little combination
> ...
>
> class ResultSetPagingIterator extends PagingIterator { // little new to
> JDBC 2 so not sure bout this (suggestions)
> ... // used with JDBC 2.0
> }
>
> The cool thing is the tags on the JSP's all work with PagingIterator so
> there is no need for the page to know how
> the paging is implemented.
>
> Some other things. Currently i have a messy implementation of this running
> inside struts. Works ok. but basically some
> of the challenges include
> 1) knowing when the query is new and when its navigation. currently I check
> for the presense of a navigate in
> the request params.
> 2) where and when to stash the iterator. Currently I'm stashing it in the
> session using some other custom tags.
> 3) should the getEntities thing be done as an interface instead of an
> abstract method? e.g
> new SomePagingIterator(ChunkableRetriever c) where ChunkableRetriever has
> a method getEntities(int start, int span)
>
> 3) how do you cleanly handle errors (I suck at error handeling in JSPs)
>
>
>
> Here's an example how its being used.
>
> ItemsByCategoryPagingIterator extends RequeryPagingIterator {
> String _CategoryId = null;
>
> Collection getEntities(int start, int span) throws SomeException {
> Collection col = null;
> try {
> col = itemsHome.findByCategoryId(getCategoryId());
> }catch(BusinessException e){
> throw new SomeException(e.getMessage());
> }
> return col;
> }
> }
>
> Then i have some definition code that initiates sets all the properties
> (categoryId in the above example)
> and then sends it off to the jsp to do its navigation.
>
> There is also
> <list:chunk iterator="wheretheiteratorisstashed" collectionTarget="items"
> navigate="<%= navoption from request %>" >
> <logic:iterate id="eachitem" name="items">
> present the properties of eachitem
> </logic:iterate>
> <list:previous>something to display if there is a previous
> (link)</list:previous>
> <list:next>something to display if there is a next (link) </list:next>
>
> </list:chunk>
>
> Disclaimer:
> I am not an architecht. Moreover, I am just out of college and still wet
> behind the ears, but I would be glad to help
> out with this. I would love to hear what you guys think.
>
>
> Thanks a bunch in advance and keep up the great work.
> Brian
>
>
>
>
>
>
>
>
> --
> To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
>
>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>