[ http://jira.codehaus.org/browse/DISPL-129?page=comments#action_55926 ]
Łukasz Matuszewski commented on DISPL-129: ----------------------------------------------- I was analyzing this patches and found one weekness... it was on TableTag.java in private void initParameters() throws ObjectLookupException, FactoryInstantiationException, InvalidTagAttributeValueException { // <XXX:LM2> (http://jira.codehaus.org/browse/DISPL-129) if (this.list instanceof PaginatedList) { this.paginatedList = (PaginatedList) this.list; this.list = this.paginatedList.getList(); } // </XXX:LM2> (http://jira.codehaus.org/browse/DISPL-129) if (rhf == null) { // first time initialization rhf = this.properties.getRequestHelperFactoryInstance(); } RequestHelper requestHelper = rhf .getRequestHelperInstance(this.pageContext); initHref(requestHelper); Integer pageNumberParameter = requestHelper .getIntParameter(encodeParameter(TableTagParameters.PARAMETER_PAGE)); this.pageNumber = (pageNumberParameter == null) ? 1 : pageNumberParameter .intValue(); //Integer sortColumnParameter = requestHelper // .getIntParameter(encodeParameter(TableTagParameters.PARAMETER_SORT)); //int sortColumn = (sortColumnParameter == null) ? this.defaultSortedColumn // : sortColumnParameter.intValue(); int sortColumn; // <XXX:LM2> (http://jira.codehaus.org/browse/DISPL-129) if (this.paginatedList == null) { Integer sortColumnParameter = requestHelper .getIntParameter(encodeParameter(TableTagParameters.PARAMETER_SORT)); sortColumn = (sortColumnParameter == null) ? this.defaultSortedColumn : sortColumnParameter.intValue(); this.tableModel.setSortedColumnNumber(sortColumn); } else { sortColumn = defaultSortedColumn; } // </XXX:LM2> (http://jira.codehaus.org/browse/DISPL-129) this.tableModel.setSortedColumnNumber(sortColumn); // default value // <XXX:LM> int finalSortFull = this.getSortValue(this.properties.getSortFullList()); // user value for this single table if (this.sortFullTable != null) { finalSortFull = this.sortFullTable; } this.tableModel.setSortFullTable(finalSortFull); // </XXX:LM> // <XXX:LM2> (http://jira.codehaus.org/browse/DISPL-129) if (this.paginatedList == null) { SortOrderEnum paramOrder = SortOrderEnum .fromCode(requestHelper .getIntParameter(encodeParameter(TableTagParameters.PARAMETER_ORDER))); // </XXX:LM2> (http://jira.codehaus.org/browse/DISPL-129) // if no order parameter is set use default if (paramOrder == null) { paramOrder = this.defaultSortOrder; } boolean order = SortOrderEnum.DESCENDING != paramOrder; this.tableModel.setSortOrderAscending(order); // <XXX:LM2> (http://jira.codehaus.org/browse/DISPL-129) } else { SortOrderEnum direction = paginatedList.getSortDirection(); this.tableModel .setSortOrderAscending(direction == SortOrderEnum.ASCENDING); } // </XXX:LM2> (http://jira.codehaus.org/browse/DISPL-129) Integer exportTypeParameter = requestHelper .getIntParameter(encodeParameter(TableTagParameters.PARAMETER_EXPORTTYPE)); this.currentMediaType = MediaTypeEnum.fromCode(exportTypeParameter); if (this.currentMediaType == null) { this.currentMediaType = MediaTypeEnum.HTML; } // <LM2> MOVE IT TO THE TOP OF METHOD String fullName = getFullObjectName(); // only evaluate if needed, else use list attribute if (fullName != null) { this.list = evaluateExpression(fullName); } else if (this.list == null) { // needed to allow removing the collection of objects if not set directly this.list = this.listAttribute; } // </LM2> MOVE IT TO THE TOP OF METHOD // do we really need to skip any row? boolean wishOptimizedIteration = (this.pagesize > 0 // we are paging || this.offset > 0 // or we are skipping some records using offset || this.length > 0 // or we are limiting the records using length ); // can we actually skip any row? if (wishOptimizedIteration && (this.list instanceof Collection) // we need // to know // the size && ((sortColumn == -1 // and we are not sorting || !(finalSortFull == TableTagParameters.SORT_AMOUNT_LIST_INT) // or we // are // sorting // with // the // "page" // behaviour ) && (this.currentMediaType == MediaTypeEnum.HTML // and we are not // exporting || !this.properties.getExportFullList()) // or we are exporting a // single page )) { int start = 0; int end = 0; if (this.offset > 0) { start = this.offset; } if (length > 0) { end = start + this.length; } if (this.pagesize > 0) { int fullSize = ((Collection) this.list).size(); start = (this.pageNumber - 1) * this.pagesize; // invalid page requested, go back to page one if (start > fullSize) { // <XXX:LM2> (http://jira.codehaus.org/browse/DISPL-212) int div = fullSize / this.pagesize; start = (fullSize % this.pagesize == 0) ? div : div + 1; // </XXX:LM2> (http://jira.codehaus.org/browse/DISPL-212) } end = start + this.pagesize; } // rowNumber starts from 1 filteredRows = new LongRange(start + 1, end); } else { filteredRows = new LongRange(1, Long.MAX_VALUE); } this.tableIterator = IteratorUtils.getIterator(this.list); } , you test for paginatedList at top of initParameters() method, while it may work in not EL version but NOT ALWAYS. To work it out you should move following code marked with <LM2> tags at the top of this method (befor mentioned test). So method will look like this: private void initParameters() throws ObjectLookupException, FactoryInstantiationException, InvalidTagAttributeValueException { // <LM2> TOP OF METHOD String fullName = getFullObjectName(); // only evaluate if needed, else use list attribute if (fullName != null) { this.list = evaluateExpression(fullName); } else if (this.list == null) { // needed to allow removing the collection of objects if not set directly this.list = this.listAttribute; } // </LM2> TOP OF METHOD // <XXX:LM2> (http://jira.codehaus.org/browse/DISPL-129) if (this.list instanceof PaginatedList) { this.paginatedList = (PaginatedList) this.list; this.list = this.paginatedList.getList(); } // </XXX:LM2> (http://jira.codehaus.org/browse/DISPL-129) if (rhf == null) { // first time initialization rhf = this.properties.getRequestHelperFactoryInstance(); } RequestHelper requestHelper = rhf .getRequestHelperInstance(this.pageContext); initHref(requestHelper); Integer pageNumberParameter = requestHelper .getIntParameter(encodeParameter(TableTagParameters.PARAMETER_PAGE)); this.pageNumber = (pageNumberParameter == null) ? 1 : pageNumberParameter .intValue(); //Integer sortColumnParameter = requestHelper // .getIntParameter(encodeParameter(TableTagParameters.PARAMETER_SORT)); //int sortColumn = (sortColumnParameter == null) ? this.defaultSortedColumn // : sortColumnParameter.intValue(); int sortColumn; // <XXX:LM2> (http://jira.codehaus.org/browse/DISPL-129) if (this.paginatedList == null) { Integer sortColumnParameter = requestHelper .getIntParameter(encodeParameter(TableTagParameters.PARAMETER_SORT)); sortColumn = (sortColumnParameter == null) ? this.defaultSortedColumn : sortColumnParameter.intValue(); this.tableModel.setSortedColumnNumber(sortColumn); } else { sortColumn = defaultSortedColumn; } // </XXX:LM2> (http://jira.codehaus.org/browse/DISPL-129) this.tableModel.setSortedColumnNumber(sortColumn); // default value // <XXX:LM> int finalSortFull = this.getSortValue(this.properties.getSortFullList()); // user value for this single table if (this.sortFullTable != null) { finalSortFull = this.sortFullTable; } this.tableModel.setSortFullTable(finalSortFull); // </XXX:LM> // <XXX:LM2> (http://jira.codehaus.org/browse/DISPL-129) if (this.paginatedList == null) { SortOrderEnum paramOrder = SortOrderEnum .fromCode(requestHelper .getIntParameter(encodeParameter(TableTagParameters.PARAMETER_ORDER))); // </XXX:LM2> (http://jira.codehaus.org/browse/DISPL-129) // if no order parameter is set use default if (paramOrder == null) { paramOrder = this.defaultSortOrder; } boolean order = SortOrderEnum.DESCENDING != paramOrder; this.tableModel.setSortOrderAscending(order); // <XXX:LM2> (http://jira.codehaus.org/browse/DISPL-129) } else { SortOrderEnum direction = paginatedList.getSortDirection(); this.tableModel .setSortOrderAscending(direction == SortOrderEnum.ASCENDING); } // </XXX:LM2> (http://jira.codehaus.org/browse/DISPL-129) Integer exportTypeParameter = requestHelper .getIntParameter(encodeParameter(TableTagParameters.PARAMETER_EXPORTTYPE)); this.currentMediaType = MediaTypeEnum.fromCode(exportTypeParameter); if (this.currentMediaType == null) { this.currentMediaType = MediaTypeEnum.HTML; } // do we really need to skip any row? boolean wishOptimizedIteration = (this.pagesize > 0 // we are paging || this.offset > 0 // or we are skipping some records using offset || this.length > 0 // or we are limiting the records using length ); // can we actually skip any row? if (wishOptimizedIteration && (this.list instanceof Collection) // we need // to know // the size && ((sortColumn == -1 // and we are not sorting || !(finalSortFull == TableTagParameters.SORT_AMOUNT_LIST_INT) // or we // are // sorting // with // the // "page" // behaviour ) && (this.currentMediaType == MediaTypeEnum.HTML // and we are not // exporting || !this.properties.getExportFullList()) // or we are exporting a // single page )) { int start = 0; int end = 0; if (this.offset > 0) { start = this.offset; } if (length > 0) { end = start + this.length; } if (this.pagesize > 0) { int fullSize = ((Collection) this.list).size(); start = (this.pageNumber - 1) * this.pagesize; // invalid page requested, go back to page one if (start > fullSize) { // <XXX:LM2> (http://jira.codehaus.org/browse/DISPL-212) int div = fullSize / this.pagesize; start = (fullSize % this.pagesize == 0) ? div : div + 1; // </XXX:LM2> (http://jira.codehaus.org/browse/DISPL-212) } end = start + this.pagesize; } // rowNumber starts from 1 filteredRows = new LongRange(start + 1, end); } else { filteredRows = new LongRange(1, Long.MAX_VALUE); } this.tableIterator = IteratorUtils.getIterator(this.list); } > allow for partial lists where the rest remains in DB > ---------------------------------------------------- > > Key: DISPL-129 > URL: http://jira.codehaus.org/browse/DISPL-129 > Project: DisplayTag > Type: Improvement > Components: Paging/Sorting > Versions: 1.0 RC2 > Reporter: fabrizio giustina > Fix For: 1.1 > Attachments: patch.zip, patch.zip > > > ==== > imported from sf tracker > id 951204 > submitted by Ralf Hauser - ralfhauser > http://sourceforge.net/support/tracker.php?aid=951204 > ==== > displaytag is an amazing tool to spare end-users the > long download times of huge tables and make tables more > versatile. > When tables get really big, this approach still might > be problematic because the java.util.List a) take a > long time to assemble from the DB and b) may end up so > big that it will be a problem if there are multiple > parallel user sessions with huge java.util.List (or > request.setAttribute... as alternative to sessions) > Suggestion: > ========= > Allow to only provide partial lists to begin with - the > "display:table" tag as per > http://displaytag.sourceforge.net/tagreference.html#Attributes > would need the following additional attributes: > 1) list-size- default would be the size of the > java.util.List, otherwise, the programmer should > retrieve that number with SELECT COUNT(*) FROM ... > 2) call-back function name - e.g. struts action to call > with off-set parameter and rowcount if the rows to > display are not present in the partial list in the > request/session scope. On the DB-side e.g. SELECT * > FROM `TBL_MESSAGE` LIMIT 110, 145 is readily available > to do that > 3) listOffset (optional) - if java.util.List's first > entry is not what logically is considered the first element > obviously doing this is imcompatible with sort="list" > ==== > Date: 2004-09-13 17:45 > Sender: ralfhauserAccepting Donations > Logged In: YES > user_id=266141 > see a solution approach in > http://sourceforge.net/tracker/index.php?func=detail&aid=1026408& > group_id=73068&atid=536613 > Date: 2004-09-07 03:51 > Sender: ianbdev > Logged In: YES > user_id=461701 > Hello, > I posted the 872183 request. > Since then we've come up with an alternate approach. > See [ 1023387 ] Pagination - use subList instead of iterating > all records. > If this change is implemented then you can implement a List > object that overrides the subList method of the List interface. > This would allow you to limit database/datasource accesses > to obtain just the few page records required for the page > being displayed. > No other changes to display tag are required. > Date: 2004-05-27 15:12 > Sender: carlossg > Logged In: YES > user_id=792979 > This has been already pointed out in RFE 872183 > Date: 2004-05-10 21:13 > Sender: smccrory > Logged In: YES > user_id=20779 > Also see https://sourceforge.net/tracker/index.php? > func=detail&aid=950819&group_id=73068&atid=536613 -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://jira.codehaus.org/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira ------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Do you grep through log files for problems? Stop! Download the new AJAX search engine that makes searching your log files as easy as surfing the web. DOWNLOAD SPLUNK! http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click _______________________________________________ displaytag-devel mailing list displaytag-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/displaytag-devel