1 12 package org.displaytag.tags; 13 14 import java.io.ByteArrayOutputStream ; 15 import java.io.IOException ; 16 import java.io.StringWriter ; 17 import java.io.Writer ; 18 import java.util.Collection ; 19 import java.util.HashMap ; 20 import java.util.Iterator ; 21 import java.util.List ; 22 import java.util.Map ; 23 24 import javax.servlet.http.HttpServletRequest ; 25 import javax.servlet.http.HttpServletResponse ; 26 import javax.servlet.jsp.JspException ; 27 import javax.servlet.jsp.JspTagException ; 28 import javax.servlet.jsp.JspWriter ; 29 30 import org.apache.commons.beanutils.BeanUtils; 31 import org.apache.commons.collections.IteratorUtils; 32 import org.apache.commons.lang.ObjectUtils; 33 import org.apache.commons.lang.StringUtils; 34 import org.apache.commons.lang.math.LongRange; 35 import org.apache.commons.lang.math.NumberUtils; 36 import org.apache.commons.lang.math.Range; 37 import org.apache.commons.logging.Log; 38 import org.apache.commons.logging.LogFactory; 39 import org.displaytag.Messages; 40 import org.displaytag.decorator.TableDecorator; 41 import org.displaytag.exception.ExportException; 42 import org.displaytag.exception.FactoryInstantiationException; 43 import org.displaytag.exception.InvalidTagAttributeValueException; 44 import org.displaytag.exception.WrappedRuntimeException; 45 import org.displaytag.export.BinaryExportView; 46 import org.displaytag.export.ExportView; 47 import org.displaytag.export.ExportViewFactory; 48 import org.displaytag.export.TextExportView; 49 import org.displaytag.model.Cell; 50 import org.displaytag.model.Column; 51 import org.displaytag.model.HeaderCell; 52 import org.displaytag.model.Row; 53 import org.displaytag.model.TableModel; 54 import org.displaytag.pagination.PaginatedList; 55 import org.displaytag.pagination.PaginatedListSmartListHelper; 56 import org.displaytag.pagination.SmartListHelper; 57 import org.displaytag.properties.MediaTypeEnum; 58 import org.displaytag.properties.SortOrderEnum; 59 import org.displaytag.properties.TableProperties; 60 import org.displaytag.render.HtmlTableWriter; 61 import org.displaytag.util.CollectionUtil; 62 import org.displaytag.util.DependencyChecker; 63 import org.displaytag.util.Href; 64 import org.displaytag.util.ParamEncoder; 65 import org.displaytag.util.RequestHelper; 66 import org.displaytag.util.RequestHelperFactory; 67 import org.displaytag.util.TagConstants; 68 69 70 79 public class TableTag extends HtmlTableTag 80 { 81 82 86 public static final String PAGE_ATTRIBUTE_MEDIA = "mediaType"; 88 91 public static final String FILTER_CONTENT_OVERRIDE_BODY = "org.displaytag.filter.ResponseOverrideFilter.CONTENT_OVERRIDE_BODY"; 94 97 private static final long serialVersionUID = 899149338534L; 98 99 102 private static Log log = LogFactory.getLog(TableTag.class); 103 104 107 private static RequestHelperFactory rhf; 108 109 113 protected Object list; 114 115 117 121 protected Object listAttribute; 122 123 126 private int rowNumber = 1; 127 128 131 private String name; 132 133 136 private int length; 137 138 141 private String decoratorName; 142 143 146 private int pagesize; 147 148 151 private boolean partialList; 152 153 156 private boolean export; 157 158 161 private int offset; 162 163 166 private Object size; 167 168 171 private String sizeObjectName; 172 173 176 private Boolean sortFullTable; 177 178 181 private boolean localSort = true; 182 183 186 private String requestUri; 187 188 191 private boolean dontAppendContext; 192 193 196 private int defaultSortedColumn = -1; 197 198 201 private SortOrderEnum defaultSortOrder; 202 203 206 private String excludedParams; 207 208 211 private String uid; 212 213 216 private String varTotals; 217 218 220 223 private TableModel tableModel; 224 225 228 private Row currentRow; 229 230 233 234 237 private SmartListHelper listHelper; 238 239 242 private Href baseHref; 243 244 247 private TableProperties properties; 248 249 252 private int pageNumber = 1; 253 254 257 private Iterator tableIterator; 258 259 262 private MediaTypeEnum currentMediaType; 263 264 267 private boolean doAfterBodyExecuted; 268 269 272 private ParamEncoder paramEncoder; 273 274 277 private String footer; 278 279 282 private boolean lastIteration; 283 284 287 private String caption; 288 289 292 private CaptionTag captionTag; 293 294 300 private Object filteredRows; 301 302 306 private PaginatedList paginatedList; 307 308 312 protected boolean isLastIteration() 313 { 314 return this.lastIteration; 315 } 316 317 321 public void setExcludedParams(String value) 322 { 323 this.excludedParams = value; 324 } 325 326 330 public void setFooter(String string) 331 { 332 this.footer = string; 333 this.tableModel.setFooter(this.footer); 334 } 335 336 340 public void setCaption(String string) 341 { 342 this.caption = string; 343 this.tableModel.setCaption(this.caption); 344 } 345 346 350 public void setCaptionTag(CaptionTag captionTag) 351 { 352 this.captionTag = captionTag; 353 } 354 355 359 public CaptionTag getCaptionTag() 360 { 361 return this.captionTag; 362 } 363 364 368 protected boolean isEmpty() 369 { 370 return this.currentRow == null; 371 } 372 373 377 public void setSize(Object size) 378 { 379 if (size instanceof String ) 380 { 381 this.sizeObjectName = (String ) size; 382 } 383 else 384 { 385 this.size = size; 386 } 387 } 388 389 393 public void setSizeObjectName(String sizeObjectName) 394 { 395 this.sizeObjectName = sizeObjectName; 396 } 397 398 403 public void setSort(String value) throws InvalidTagAttributeValueException 404 { 405 if (TableTagParameters.SORT_AMOUNT_PAGE.equals(value)) 406 { 407 this.sortFullTable = Boolean.FALSE; 408 } 409 else if (TableTagParameters.SORT_AMOUNT_LIST.equals(value)) 410 { 411 this.sortFullTable = Boolean.TRUE; 412 } 413 else if (TableTagParameters.SORT_AMOUNT_EXTERNAL.equals(value)) 414 { 415 this.localSort = false; 416 } 417 else 418 { 419 throw new InvalidTagAttributeValueException(getClass(), "sort", value); } 421 } 422 423 427 public void setRequestURI(String value) 428 { 429 this.requestUri = value; 430 } 431 432 436 public void setRequestURIcontext(boolean value) 437 { 438 this.dontAppendContext = !value; 439 } 440 441 446 public void setList(Object value) 447 { 448 this.listAttribute = value; 449 } 450 451 456 public void setName(Object value) 457 { 458 if (value instanceof String ) 459 { 460 this.name = (String ) value; 462 } 463 else 464 { 465 this.list = value; 467 } 468 } 469 470 475 public void setNameString(String value) 476 { 477 this.name = value; 478 } 479 480 485 public void setDefaultorder(String value) throws InvalidTagAttributeValueException 486 { 487 this.defaultSortOrder = SortOrderEnum.fromName(value); 488 if (this.defaultSortOrder == null) 489 { 490 throw new InvalidTagAttributeValueException(getClass(), "defaultorder", value); } 492 } 493 494 498 public void setDecorator(String decorator) 499 { 500 this.decoratorName = decorator; 501 } 502 503 507 public void setExport(boolean value) 508 { 509 this.export = value; 510 } 511 512 516 public void setVarTotals(String varTotalsName) 517 { 518 this.varTotals = varTotalsName; 519 } 520 521 525 public String getVarTotals() 526 { 527 return this.varTotals; 528 } 529 530 534 public void setLength(int value) 535 { 536 this.length = value; 537 } 538 539 543 public void setDefaultsort(int value) 544 { 545 this.defaultSortedColumn = value - 1; 547 } 548 549 553 public void setPagesize(int value) 554 { 555 this.pagesize = value; 556 } 557 558 563 public void setPartialList(boolean partialList) 564 { 565 this.partialList = partialList; 566 } 567 568 572 public void setOffset(int value) 573 { 574 if (value < 1) 575 { 576 this.offset = 0; 578 } 579 else 580 { 581 this.offset = value - 1; 582 } 583 } 584 585 589 public void setUid(String value) 590 { 591 this.uid = value; 592 } 593 594 598 public String getUid() 599 { 600 return this.uid; 601 } 602 603 607 protected TableProperties getProperties() 608 { 609 return this.properties; 610 } 611 612 617 protected Href getBaseHref() 618 { 619 return this.baseHref; 620 } 621 622 627 public void addColumn(HeaderCell column) 628 { 629 if (log.isDebugEnabled()) 630 { 631 log.debug("[" + getUid() + "] addColumn " + column); 632 } 633 634 if ((this.paginatedList != null) && (column.getSortable())) 635 { 636 String sortCriterion = paginatedList.getSortCriterion(); 637 638 String sortProperty = column.getSortProperty(); 639 if (sortProperty == null) 640 { 641 sortProperty = column.getBeanPropertyName(); 642 } 643 644 if ((sortCriterion != null) && sortCriterion.equals(sortProperty)) 645 { 646 this.tableModel.setSortedColumnNumber(this.tableModel.getNumberOfColumns()); 647 column.setAlreadySorted(); 648 } 649 } 650 651 this.tableModel.addColumnHeader(column); 652 } 653 654 658 public void addCell(Cell cell) 659 { 660 if (this.currentRow != null) 662 { 663 int columnNumber = this.currentRow.getCellList().size(); 664 this.currentRow.addCell(cell); 665 666 if (columnNumber < tableModel.getHeaderCellList().size()) 669 { 670 HeaderCell header = (HeaderCell) tableModel.getHeaderCellList().get(columnNumber); 671 header.addCell(new Column(header, cell, currentRow)); 672 } 673 } 674 } 675 676 680 protected boolean isFirstIteration() 681 { 682 if (log.isDebugEnabled()) 683 { 684 log.debug("[" 685 + getUid() 686 + "] first iteration=" 687 + (this.rowNumber == 1) 688 + " (row number=" 689 + this.rowNumber 690 + ")"); 691 } 692 return this.rowNumber == 1; 695 } 696 697 704 public int doStartTag() throws JspException 705 { 706 DependencyChecker.check(); 707 708 ExportViewFactory.getInstance(); 710 711 if (log.isDebugEnabled()) 712 { 713 log.debug("[" + getUid() + "] doStartTag called"); 714 } 715 716 this.properties = TableProperties.getInstance((HttpServletRequest ) pageContext.getRequest()); 717 this.tableModel = new TableModel(this.properties, pageContext.getResponse().getCharacterEncoding(), pageContext); 718 719 this.tableModel.setId(getUid()); 721 722 initParameters(); 723 724 this.tableModel.setMedia(this.currentMediaType); 725 726 Object previousMediaType = this.pageContext.getAttribute(PAGE_ATTRIBUTE_MEDIA); 727 if (previousMediaType == null || MediaTypeEnum.HTML.equals(previousMediaType)) 729 { 730 if (log.isDebugEnabled()) 731 { 732 log.debug("[" + getUid() + "] setting media [" + this.currentMediaType + "] in this.pageContext"); 733 } 734 this.pageContext.setAttribute(PAGE_ATTRIBUTE_MEDIA, this.currentMediaType); 735 } 736 737 doIteration(); 738 739 return 2; 742 } 743 744 747 public int doAfterBody() 748 { 749 this.doAfterBodyExecuted = true; 751 752 if (log.isDebugEnabled()) 753 { 754 log.debug("[" + getUid() + "] doAfterBody called - iterating on row " + this.rowNumber); 755 } 756 757 this.rowNumber++; 759 760 return doIteration(); 762 } 763 764 768 protected int doIteration() 769 { 770 771 if (log.isDebugEnabled()) 772 { 773 log.debug("[" + getUid() + "] doIteration called"); 774 } 775 776 if (this.currentRow != null) 778 { 779 this.tableModel.addRow(this.currentRow); 781 this.currentRow = null; 782 } 783 784 if (this.tableIterator.hasNext()) 785 { 786 787 Object iteratedObject = this.tableIterator.next(); 788 if (getUid() != null) 789 { 790 if ((iteratedObject != null)) 791 { 792 if (log.isDebugEnabled()) 794 { 795 log.debug("[" + getUid() + "] setting attribute \"" + getUid() + "\" in pageContext"); 796 } 797 this.pageContext.setAttribute(getUid(), iteratedObject); 798 799 } 800 else 801 { 802 this.pageContext.removeAttribute(getUid()); 804 } 805 this.pageContext.setAttribute(getUid() + TableTagExtraInfo.ROWNUM_SUFFIX, new Integer (this.rowNumber)); 807 } 808 809 this.currentRow = new Row(iteratedObject, this.rowNumber); 811 812 this.lastIteration = !this.tableIterator.hasNext(); 813 814 return 2; 817 } 818 this.lastIteration = true; 819 820 if (log.isDebugEnabled()) 821 { 822 log.debug("[" + getUid() + "] doIteration() - iterator ended after " + (this.rowNumber - 1) + " rows"); 823 } 824 825 return SKIP_BODY; 827 } 828 829 833 private void initParameters() throws JspTagException , FactoryInstantiationException 834 { 835 836 if (rhf == null) 837 { 838 rhf = this.properties.getRequestHelperFactoryInstance(); 840 } 841 842 String fullName = getFullObjectName(); 843 844 if (fullName != null) 846 { 847 this.list = evaluateExpression(fullName); 848 } 849 else if (this.list == null) 850 { 851 this.list = this.listAttribute; 853 } 854 855 if (this.list instanceof PaginatedList) 856 { 857 this.paginatedList = (PaginatedList) this.list; 858 this.list = this.paginatedList.getList(); 859 } 860 861 this.tableModel.setLocalSort(this.localSort && (this.paginatedList == null)); 863 864 RequestHelper requestHelper = rhf.getRequestHelperInstance(this.pageContext); 865 866 initHref(requestHelper); 867 868 Integer pageNumberParameter = requestHelper.getIntParameter(encodeParameter(TableTagParameters.PARAMETER_PAGE)); 869 this.pageNumber = (pageNumberParameter == null) ? 1 : pageNumberParameter.intValue(); 870 871 int sortColumn = -1; 872 if (!this.tableModel.isLocalSort()) 873 { 874 String sortColumnName = requestHelper.getParameter(encodeParameter(TableTagParameters.PARAMETER_SORT)); 876 877 String usename = requestHelper.getParameter(encodeParameter(TableTagParameters.PARAMETER_SORTUSINGNAME)); 879 880 if (sortColumnName == null) 881 { 882 this.tableModel.setSortedColumnNumber(this.defaultSortedColumn); 883 } 884 else 885 { 886 if (usename != null) 887 { 888 889 this.tableModel.setSortedColumnName(sortColumnName); } 891 else if (NumberUtils.isNumber(sortColumnName)) 892 { 893 sortColumn = Integer.parseInt(sortColumnName); 894 this.tableModel.setSortedColumnNumber(sortColumn); } 896 } 897 } 898 else if (this.paginatedList == null) 899 { 900 Integer sortColumnParameter = requestHelper 901 .getIntParameter(encodeParameter(TableTagParameters.PARAMETER_SORT)); 902 sortColumn = (sortColumnParameter == null) ? this.defaultSortedColumn : sortColumnParameter.intValue(); 903 this.tableModel.setSortedColumnNumber(sortColumn); 904 } 905 else 906 { 907 sortColumn = defaultSortedColumn; 908 } 909 910 boolean finalSortFull = this.properties.getSortFullList(); 912 913 if (this.sortFullTable != null) 915 { 916 finalSortFull = this.sortFullTable.booleanValue(); 917 } 918 919 if (!this.partialList || !finalSortFull) 921 { 922 this.tableModel.setSortFullTable(finalSortFull); 923 } 924 925 if (this.paginatedList == null) 926 { 927 SortOrderEnum paramOrder = SortOrderEnum.fromCode(requestHelper 928 .getIntParameter(encodeParameter(TableTagParameters.PARAMETER_ORDER))); 929 930 if (paramOrder == null) 932 { 933 paramOrder = this.defaultSortOrder; 934 } 935 936 boolean order = SortOrderEnum.DESCENDING != paramOrder; 937 this.tableModel.setSortOrderAscending(order); 938 } 939 else 940 { 941 SortOrderEnum direction = paginatedList.getSortDirection(); 942 this.tableModel.setSortOrderAscending(direction == SortOrderEnum.ASCENDING); 943 } 944 945 Integer exportTypeParameter = requestHelper 946 .getIntParameter(encodeParameter(TableTagParameters.PARAMETER_EXPORTTYPE)); 947 948 this.currentMediaType = (MediaTypeEnum) ObjectUtils.defaultIfNull( 949 MediaTypeEnum.fromCode(exportTypeParameter), 950 MediaTypeEnum.HTML); 951 952 if (this.partialList) 954 { 955 if ((this.sizeObjectName == null) && (this.size == null)) 956 { 957 } 959 if (this.sizeObjectName != null) 960 { 961 this.size = evaluateExpression(this.sizeObjectName); 963 } 964 if (size == null) 965 { 966 throw new JspTagException (Messages.getString("MissingAttributeException.msg", new Object []{"size"})); 967 } 968 else if (!(size instanceof Integer )) 969 { 970 throw new JspTagException (Messages.getString( 971 "InvalidTypeException.msg", 972 new Object []{"size", "Integer"})); 973 } 974 } 975 976 boolean wishOptimizedIteration = ((this.pagesize > 0 || this.offset > 0 || this.length > 0 ) && !partialList); 982 if (wishOptimizedIteration && (this.list instanceof Collection ) && ((sortColumn == -1 || !finalSortFull ) && (this.currentMediaType == MediaTypeEnum.HTML || !this.properties.getExportFullList()) )) 989 { 990 int start = 0; 991 int end = 0; 992 if (this.offset > 0) 993 { 994 start = this.offset; 995 } 996 if (length > 0) 997 { 998 end = start + this.length; 999 } 1000 1001 if (this.pagesize > 0) 1002 { 1003 int fullSize = ((Collection ) this.list).size(); 1004 start = (this.pageNumber - 1) * this.pagesize; 1005 1006 if (start > fullSize) 1008 { 1009 int div = fullSize / this.pagesize; 1010 start = (fullSize % this.pagesize == 0) ? div : div + 1; 1011 } 1012 1013 end = start + this.pagesize; 1014 } 1015 1016 filteredRows = new LongRange(start + 1, end); 1018 } 1019 else 1020 { 1021 filteredRows = new LongRange(1, Long.MAX_VALUE); 1022 } 1023 1024 this.tableIterator = IteratorUtils.getIterator(this.list); 1025 } 1026 1027 1033 protected boolean isIncludedRow() 1034 { 1035 return ((Range) filteredRows).containsLong(this.rowNumber); 1036 } 1037 1038 1043 private String getFullObjectName() 1044 { 1045 if (this.name == null) 1047 { 1048 return null; 1049 } 1050 1051 return this.name; 1052 } 1053 1054 1058 protected void initHref(RequestHelper requestHelper) 1059 { 1060 this.baseHref = requestHelper.getHref(); 1062 1063 if (this.excludedParams != null) 1064 { 1065 String [] splittedExcludedParams = StringUtils.split(this.excludedParams); 1066 1067 if (splittedExcludedParams.length == 1 && "*".equals(splittedExcludedParams[0])) 1069 { 1070 if (this.paramEncoder == null) 1072 { 1073 this.paramEncoder = new ParamEncoder(getUid()); 1074 } 1075 1076 Iterator paramsIterator = baseHref.getParameterMap().keySet().iterator(); 1077 while (paramsIterator.hasNext()) 1078 { 1079 String key = (String ) paramsIterator.next(); 1080 1081 if (!this.paramEncoder.isParameterEncoded(key)) 1083 { 1084 baseHref.removeParameter(key); 1085 } 1086 } 1087 } 1088 else 1089 { 1090 for (int j = 0; j < splittedExcludedParams.length; j++) 1091 { 1092 baseHref.removeParameter(splittedExcludedParams[j]); 1093 } 1094 } 1095 } 1096 1097 if (this.requestUri != null) 1098 { 1099 String fullURI = requestUri; 1101 if (!this.dontAppendContext) 1102 { 1103 String contextPath = ((HttpServletRequest ) this.pageContext.getRequest()).getContextPath(); 1104 1105 if (!StringUtils.isEmpty(contextPath) 1108 && requestUri != null 1109 && requestUri.startsWith("/") 1110 && !requestUri.startsWith(contextPath)) 1111 { 1112 fullURI = contextPath + this.requestUri; 1113 } 1114 } 1115 1116 fullURI = ((HttpServletResponse ) this.pageContext.getResponse()).encodeURL(fullURI); 1118 1119 baseHref.setFullUrl(fullURI); 1120 1121 } 1125 1126 } 1127 1128 1135 public int doEndTag() throws JspException 1136 { 1137 1138 if (log.isDebugEnabled()) 1139 { 1140 log.debug("[" + getUid() + "] doEndTag called"); 1141 } 1142 1143 if (!this.doAfterBodyExecuted) 1144 { 1145 if (log.isDebugEnabled()) 1146 { 1147 log.debug("[" + getUid() + "] tag body is empty."); 1148 } 1149 1150 if (this.currentRow != null) 1152 { 1153 this.tableModel.addRow(this.currentRow); 1155 } 1156 1157 while (this.tableIterator.hasNext()) 1159 { 1160 Object iteratedObject = this.tableIterator.next(); 1161 this.rowNumber++; 1162 1163 this.currentRow = new Row(iteratedObject, this.rowNumber); 1165 1166 this.tableModel.addRow(this.currentRow); 1167 } 1168 } 1169 1170 if (this.tableModel.isEmpty()) 1172 { 1173 describeEmptyTable(); 1174 } 1175 1176 String tableDecoratorName = null; 1178 Object previousMediaType = this.pageContext.getAttribute(PAGE_ATTRIBUTE_MEDIA); 1179 if (MediaTypeEnum.HTML.equals(this.currentMediaType) 1180 && (previousMediaType == null || MediaTypeEnum.HTML.equals(previousMediaType))) 1181 { 1182 tableDecoratorName = this.decoratorName; 1183 } 1184 else if (!MediaTypeEnum.HTML.equals(this.currentMediaType)) 1185 { 1186 tableDecoratorName = this.properties.getExportDecoratorName(this.currentMediaType); 1187 } 1188 TableDecorator tableDecorator = this.properties.getDecoratorFactoryInstance().loadTableDecorator( 1189 this.pageContext, 1190 tableDecoratorName); 1191 1192 if (tableDecorator != null) 1193 { 1194 tableDecorator.init(this.pageContext, this.list, this.tableModel); 1195 this.tableModel.setTableDecorator(tableDecorator); 1196 } 1197 1198 setupViewableData(); 1199 1200 if (this.paginatedList == null && this.tableModel.isLocalSort()) 1203 { 1204 if (!this.tableModel.isSortFullTable()) 1205 { 1206 this.tableModel.sortPageList(); 1207 } 1208 } 1209 1210 int returnValue = EVAL_PAGE; 1212 1213 if (MediaTypeEnum.HTML.equals(this.currentMediaType) 1216 && (previousMediaType == null || MediaTypeEnum.HTML.equals(previousMediaType))) 1217 { 1218 writeHTMLData(); 1219 } 1220 else if (!MediaTypeEnum.HTML.equals(this.currentMediaType)) 1221 { 1222 if (log.isDebugEnabled()) 1223 { 1224 log.debug("[" + getUid() + "] doEndTag - exporting"); 1225 } 1226 1227 returnValue = doExport(); 1228 } 1229 1230 1233 if (log.isDebugEnabled()) 1234 { 1235 log.debug("[" + getUid() + "] doEndTag - end"); 1236 } 1237 1238 cleanUp(); 1239 return returnValue; 1240 } 1241 1242 1245 private void cleanUp() 1246 { 1247 this.currentMediaType = null; 1249 this.baseHref = null; 1250 this.caption = null; 1251 this.captionTag = null; 1252 this.currentRow = null; 1253 this.doAfterBodyExecuted = false; 1254 this.footer = null; 1255 this.listHelper = null; 1256 this.pageNumber = 0; 1257 this.paramEncoder = null; 1258 this.properties = null; 1259 this.rowNumber = 1; 1260 this.tableIterator = null; 1261 this.tableModel = null; 1262 this.list = null; 1263 } 1264 1265 1270 private void describeEmptyTable() 1271 { 1272 this.tableIterator = IteratorUtils.getIterator(this.list); 1273 1274 if (this.tableIterator.hasNext()) 1275 { 1276 Object iteratedObject = this.tableIterator.next(); 1277 Map objectProperties = new HashMap (); 1278 1279 if (iteratedObject instanceof String ) 1281 { 1282 return; 1283 } 1284 if (iteratedObject instanceof Map ) 1286 { 1287 objectProperties = (Map ) iteratedObject; 1288 } 1289 else 1290 { 1291 try 1292 { 1293 objectProperties = BeanUtils.describe(iteratedObject); 1294 } 1295 catch (Exception e) 1296 { 1297 log.warn("Unable to automatically add columns: " + e.getMessage(), e); 1298 } 1299 } 1300 1301 Iterator propertiesIterator = objectProperties.keySet().iterator(); 1303 1304 while (propertiesIterator.hasNext()) 1305 { 1306 String propertyName = (String ) propertiesIterator.next(); 1308 1309 if (!"class".equals(propertyName)) { 1312 HeaderCell headerCell = new HeaderCell(); 1314 headerCell.setBeanPropertyName(propertyName); 1315 1316 headerCell.setTitle(this.properties.geResourceProvider().getResource( 1318 null, 1319 propertyName, 1320 this, 1321 this.pageContext)); 1322 1323 this.tableModel.addColumnHeader(headerCell); 1324 } 1325 } 1326 } 1327 } 1328 1329 1334 protected int doExport() throws JspException 1335 { 1336 1337 boolean exportFullList = this.properties.getExportFullList(); 1338 1339 if (log.isDebugEnabled()) 1340 { 1341 log.debug("[" + getUid() + "] currentMediaType=" + this.currentMediaType); 1342 } 1343 1344 boolean exportHeader = this.properties.getExportHeader(this.currentMediaType); 1345 boolean exportDecorated = this.properties.getExportDecorated(); 1346 1347 ExportView exportView = ExportViewFactory.getInstance().getView( 1348 this.currentMediaType, 1349 this.tableModel, 1350 exportFullList, 1351 exportHeader, 1352 exportDecorated); 1353 1354 try 1355 { 1356 writeExport(exportView); 1357 } 1358 catch (IOException e) 1359 { 1360 throw new WrappedRuntimeException(getClass(), e); 1361 } 1362 1363 return SKIP_PAGE; 1364 } 1365 1366 1373 protected void writeExport(ExportView exportView) throws IOException , JspException 1374 { 1375 String filename = properties.getExportFileName(this.currentMediaType); 1376 1377 HttpServletResponse response = (HttpServletResponse ) this.pageContext.getResponse(); 1378 HttpServletRequest request = (HttpServletRequest ) this.pageContext.getRequest(); 1379 1380 Map bean = (Map ) request.getAttribute(FILTER_CONTENT_OVERRIDE_BODY); 1381 boolean usingFilter = bean != null; 1382 1383 String mimeType = exportView.getMimeType(); 1384 String characterEncoding = response.getCharacterEncoding(); 1386 1387 if (usingFilter) 1388 { 1389 if (!bean.containsKey(TableTagParameters.BEAN_BUFFER)) 1390 { 1391 log.debug("Exportfilter enabled in unbuffered mode, setting headers"); 1393 response.addHeader(TableTagParameters.PARAMETER_EXPORTING, TagConstants.EMPTY_STRING); 1394 } 1395 else 1396 { 1397 bean.put(TableTagParameters.BEAN_CONTENTTYPE, mimeType); 1399 bean.put(TableTagParameters.BEAN_FILENAME, filename); 1400 1401 if (exportView instanceof TextExportView) 1402 { 1403 StringWriter writer = new StringWriter (); 1404 ((TextExportView) exportView).doExport(writer); 1405 bean.put(TableTagParameters.BEAN_BODY, writer.toString()); 1406 } 1407 else if (exportView instanceof BinaryExportView) 1408 { 1409 ByteArrayOutputStream stream = new ByteArrayOutputStream (); 1410 ((BinaryExportView) exportView).doExport(stream); 1411 bean.put(TableTagParameters.BEAN_BODY, stream.toByteArray()); 1412 1413 } 1414 else 1415 { 1416 throw new JspTagException ("Export view " 1417 + exportView.getClass().getName() 1418 + " must implement TextExportView or BinaryExportView"); 1419 } 1420 1421 return; 1422 } 1423 } 1424 else 1425 { 1426 log.debug("Exportfilter NOT enabled"); 1427 if (response.isCommitted()) 1429 { 1430 throw new ExportException(getClass()); 1431 } 1432 1433 try 1434 { 1435 response.reset(); 1436 pageContext.getOut().clearBuffer(); 1437 } 1438 catch (Exception e) 1439 { 1440 throw new ExportException(getClass()); 1441 } 1442 } 1443 1444 if (!usingFilter && characterEncoding != null && mimeType.indexOf("charset") == -1) { 1446 mimeType += "; charset=" + characterEncoding; } 1448 1449 response.setContentType(mimeType); 1450 1451 if (StringUtils.isNotEmpty(filename)) 1452 { 1453 response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); } 1456 1457 if (exportView instanceof TextExportView) 1458 { 1459 Writer writer; 1460 if (usingFilter) 1461 { 1462 writer = response.getWriter(); 1463 } 1464 else 1465 { 1466 writer = pageContext.getOut(); 1467 } 1468 1469 ((TextExportView) exportView).doExport(writer); 1470 } 1471 else if (exportView instanceof BinaryExportView) 1472 { 1473 ((BinaryExportView) exportView).doExport(response.getOutputStream()); 1477 } 1478 else 1479 { 1480 throw new JspTagException ("Export view " 1481 + exportView.getClass().getName() 1482 + " must implement TextExportView or BinaryExportView"); 1483 } 1484 1485 log.debug("Export completed"); 1486 1487 } 1488 1489 1494 protected void setupViewableData() 1495 { 1496 1497 1501 if (this.paginatedList == null || this.tableModel.isLocalSort()) 1502 { 1503 if (this.tableModel.isSortFullTable()) 1504 { 1505 this.tableModel.sortFullList(); 1507 } 1508 } 1509 1510 Object originalData = this.tableModel.getRowListFull(); 1511 1512 List fullList = CollectionUtil.getListFromObject(originalData, this.offset, this.length); 1515 1516 int pageOffset = this.offset; 1517 if (this.paginatedList == null && this.pagesize > 0) 1520 { 1521 this.listHelper = new SmartListHelper(fullList, (this.partialList) ? ((Integer ) size).intValue() : fullList 1522 .size(), this.pagesize, this.properties, this.partialList); 1523 this.listHelper.setCurrentPage(this.pageNumber); 1524 pageOffset = this.listHelper.getFirstIndexForCurrentPage(); 1525 fullList = this.listHelper.getListForCurrentPage(); 1526 } 1527 else if (this.paginatedList != null) 1528 { 1529 this.listHelper = new PaginatedListSmartListHelper(this.paginatedList, this.properties); 1530 } 1531 this.tableModel.setRowListPage(fullList); 1532 this.tableModel.setPageOffset(pageOffset); 1533 } 1534 1535 1539 private void writeHTMLData() throws JspException 1540 { 1541 JspWriter out = this.pageContext.getOut(); 1542 1543 String css = this.properties.getCssTable(); 1544 if (StringUtils.isNotBlank(css)) 1545 { 1546 this.addClass(css); 1547 } 1548 new HtmlTableWriter( 1550 this.tableModel, 1551 this.properties, 1552 this.baseHref, 1553 this.export, 1554 out, 1555 getCaptionTag(), 1556 this.paginatedList, 1557 this.listHelper, 1558 this.pagesize, 1559 getAttributeMap(), 1560 this.uid).writeTable(this.tableModel, this.getUid()); 1561 1562 if (this.varTotals != null) 1563 { 1564 pageContext.setAttribute(this.varTotals, getTotals()); 1565 } 1566 } 1567 1568 1572 public Map getTotals() 1573 { 1574 Map totalsMap = new HashMap (); 1575 if (this.varTotals != null) 1576 { 1577 List headers = this.tableModel.getHeaderCellList(); 1578 for (Iterator iterator = headers.iterator(); iterator.hasNext();) 1579 { 1580 HeaderCell headerCell = (HeaderCell) iterator.next(); 1581 if (headerCell.isTotaled()) 1582 { 1583 totalsMap.put("column" + (headerCell.getColumnNumber() + 1), new Double (headerCell.getTotal())); 1584 } 1585 } 1586 } 1587 return totalsMap; 1588 } 1589 1590 1596 public TableModel getTableModel() 1597 { 1598 return this.tableModel; 1599 } 1600 1601 1606 public void setProperty(String propertyName, String propertyValue) 1607 { 1608 this.properties.setProperty(propertyName, propertyValue); 1609 } 1610 1611 1614 public void release() 1615 { 1616 if (log.isDebugEnabled()) 1617 { 1618 log.debug("[" + getUid() + "] release() called"); 1619 } 1620 1621 super.release(); 1622 1623 this.decoratorName = null; 1625 this.defaultSortedColumn = -1; 1626 this.defaultSortOrder = null; 1627 this.export = false; 1628 this.length = 0; 1629 this.listAttribute = null; 1630 this.localSort = true; 1631 this.name = null; 1632 this.offset = 0; 1633 this.pagesize = 0; 1634 this.partialList = false; 1635 this.requestUri = null; 1636 this.dontAppendContext = false; 1637 this.sortFullTable = null; 1638 this.excludedParams = null; 1639 this.filteredRows = null; 1640 this.uid = null; 1641 this.paginatedList = null; 1642 } 1643 1644 1648 protected String getName() 1649 { 1650 return this.name; 1651 } 1652 1653 1658 private String encodeParameter(String parameterName) 1659 { 1660 if (this.paramEncoder == null) 1662 { 1663 this.paramEncoder = new ParamEncoder(getUid()); 1665 } 1666 1667 return this.paramEncoder.encodeParameterName(parameterName); 1668 } 1669 1670} | Popular Tags |