1 12 package org.displaytag.tags; 13 14 import java.text.Collator ; 15 import java.util.ArrayList ; 16 import java.util.Comparator ; 17 import java.util.List ; 18 19 import javax.servlet.http.HttpServletRequest ; 20 import javax.servlet.http.HttpServletResponse ; 21 import javax.servlet.jsp.JspException ; 22 import javax.servlet.jsp.tagext.BodyTagSupport ; 23 24 import org.apache.commons.lang.StringUtils; 25 import org.apache.commons.lang.builder.ToStringBuilder; 26 import org.apache.commons.lang.builder.ToStringStyle; 27 import org.apache.commons.logging.Log; 28 import org.apache.commons.logging.LogFactory; 29 import org.displaytag.decorator.AutolinkColumnDecorator; 30 import org.displaytag.decorator.DisplaytagColumnDecorator; 31 import org.displaytag.decorator.EscapeXmlColumnDecorator; 32 import org.displaytag.decorator.MessageFormatColumnDecorator; 33 import org.displaytag.exception.DecoratorInstantiationException; 34 import org.displaytag.exception.InvalidTagAttributeValueException; 35 import org.displaytag.exception.ObjectLookupException; 36 import org.displaytag.exception.TagStructureException; 37 import org.displaytag.model.Cell; 38 import org.displaytag.model.DefaultComparator; 39 import org.displaytag.model.HeaderCell; 40 import org.displaytag.properties.MediaTypeEnum; 41 import org.displaytag.properties.SortOrderEnum; 42 import org.displaytag.util.DefaultHref; 43 import org.displaytag.util.Href; 44 import org.displaytag.util.HtmlAttributeMap; 45 import org.displaytag.util.MediaUtil; 46 import org.displaytag.util.MultipleHtmlAttribute; 47 import org.displaytag.util.TagConstants; 48 49 50 63 public class ColumnTag extends BodyTagSupport implements MediaUtil.SupportsMedia 64 { 65 66 69 private static final long serialVersionUID = 899149338534L; 70 71 74 private static Log log = LogFactory.getLog(ColumnTag.class); 75 76 79 private HtmlAttributeMap attributeMap = new HtmlAttributeMap(); 80 81 84 private HtmlAttributeMap headerAttributeMap = new HtmlAttributeMap(); 85 86 91 private String property; 92 93 97 private String title; 98 99 103 private boolean nulls; 104 105 108 private boolean sortable; 109 110 113 private String sortName; 114 115 118 private SortOrderEnum defaultorder; 119 120 123 private Comparator comparator; 124 125 129 private boolean autolink; 130 131 134 private boolean escapeXml; 135 136 140 private String format; 141 142 148 private int group = -1; 149 150 156 private Href href; 157 158 163 private String paramId; 164 165 172 private String paramName; 173 174 180 private String paramProperty; 181 182 188 private String paramScope; 189 190 195 private int maxLength; 196 197 202 private int maxWords; 203 204 208 private String decorator; 209 210 213 private boolean alreadySorted; 214 215 218 private List supportedMedia; 219 220 223 private String titleKey; 224 225 229 private String sortProperty; 230 231 234 private boolean totaled; 235 236 239 private Object value; 240 241 245 public void setTotal(boolean totals) 246 { 247 this.totaled = totals; 248 } 249 250 254 public void setProperty(String value) 255 { 256 this.property = value; 257 } 258 259 263 public void setValue(Object value) 264 { 265 this.value = value; 266 } 267 268 272 public void setComparator(Object comparatorObj) 273 { 274 if (comparatorObj instanceof Comparator ) 276 { 277 this.comparator = (Comparator ) comparatorObj; 278 } 279 else if (comparatorObj instanceof String ) 280 { 281 String comparatorClassname = (String ) comparatorObj; 282 Class compClass; 283 try 284 { 285 compClass = Thread.currentThread().getContextClassLoader().loadClass(comparatorClassname); 286 } 287 catch (ClassNotFoundException e) 288 { 289 throw new RuntimeException ("InstantiationException setting column comparator as " 290 + comparatorClassname 291 + ": " 292 + e.getMessage(), e); 293 } 294 try 295 { 296 this.comparator = (Comparator ) compClass.newInstance(); 297 } 298 catch (InstantiationException e) 299 { 300 throw new RuntimeException ("InstantiationException setting column comparator as " 301 + comparatorClassname 302 + ": " 303 + e.getMessage(), e); 304 } 305 catch (IllegalAccessException e) 306 { 307 throw new RuntimeException ("IllegalAccessException setting column comparator as " 308 + comparatorClassname 309 + ": " 310 + e.getMessage(), e); 311 } 312 } 313 else 314 { 315 throw new IllegalArgumentException ("Value for comparator: " 316 + comparatorObj 317 + " of type " 318 + comparatorObj.getClass().getName()); 319 } 320 } 321 322 326 public void setTitle(String value) 327 { 328 this.title = value; 329 } 330 331 335 public void setFormat(String value) 336 { 337 this.format = value; 338 } 339 340 344 public void setNulls(boolean value) 345 { 346 this.nulls = value; 347 } 348 349 353 public void setSortable(boolean value) 354 { 355 this.sortable = value; 356 } 357 358 362 public void setAutolink(boolean value) 363 { 364 this.autolink = value; 365 } 366 367 371 public void setEscapeXml(boolean value) 372 { 373 this.escapeXml = value; 374 } 375 376 380 public void setGroup(int value) 381 { 382 this.group = value; 383 } 384 385 389 public void setTitleKey(String value) 390 { 391 this.titleKey = value; 392 } 393 394 398 public void setHref(String value) 399 { 400 String encodedHref = ((HttpServletResponse ) this.pageContext.getResponse()).encodeURL(StringUtils 402 .defaultString(value)); 403 this.href = new DefaultHref(encodedHref); 404 } 405 406 411 public void setUrl(String value) 412 { 413 HttpServletRequest req = (HttpServletRequest ) pageContext.getRequest(); 414 String encodedHref = ((HttpServletResponse ) this.pageContext.getResponse()).encodeURL(StringUtils 416 .defaultString(req.getContextPath() + value)); 417 this.href = new DefaultHref(encodedHref); 418 } 419 420 424 public void setParamId(String value) 425 { 426 this.paramId = value; 427 } 428 429 433 public void setParamName(String value) 434 { 435 this.paramName = value; 436 } 437 438 442 public void setParamProperty(String value) 443 { 444 this.paramProperty = value; 445 } 446 447 451 public void setParamScope(String value) 452 { 453 this.paramScope = value; 454 } 455 456 460 public void setScope(String value) 461 { 462 this.attributeMap.put(TagConstants.ATTRIBUTE_SCOPE, value); 463 } 464 465 469 public void setHeaderScope(String value) 470 { 471 this.headerAttributeMap.put(TagConstants.ATTRIBUTE_SCOPE, value); 472 } 473 474 478 public void setMaxLength(int value) 479 { 480 this.maxLength = value; 481 } 482 483 487 public void setMaxWords(int value) 488 { 489 this.maxWords = value; 490 } 491 492 496 public void setStyle(String value) 497 { 498 this.attributeMap.put(TagConstants.ATTRIBUTE_STYLE, value); 499 } 500 501 505 public void setClass(String value) 506 { 507 this.attributeMap.put(TagConstants.ATTRIBUTE_CLASS, new MultipleHtmlAttribute(value)); 508 } 509 510 514 public void setHeaderClass(String value) 515 { 516 this.headerAttributeMap.put(TagConstants.ATTRIBUTE_CLASS, new MultipleHtmlAttribute(value)); 517 } 518 519 523 public void setDecorator(String value) 524 { 525 this.decorator = value; 526 } 527 528 532 public void setSortProperty(String value) 533 { 534 this.sortProperty = value; 535 } 536 537 541 private TableTag getTableTag() 542 { 543 return (TableTag) findAncestorWithClass(this, TableTag.class); 544 } 545 546 550 public void setMedia(String media) 551 { 552 MediaUtil.setMedia(this, media); 553 } 554 555 558 public void setSupportedMedia(List media) 559 { 560 this.supportedMedia = media; 561 } 562 563 566 public List getSupportedMedia() 567 { 568 return this.supportedMedia; 569 } 570 571 575 public void setSortName(String sortName) 576 { 577 this.sortName = sortName; 578 } 579 580 585 public void setDefaultorder(String value) throws InvalidTagAttributeValueException 586 { 587 this.defaultorder = SortOrderEnum.fromName(value); 588 if (this.defaultorder == null) 589 { 590 throw new InvalidTagAttributeValueException(getClass(), "defaultorder", value); } 592 } 593 594 605 public int doEndTag() throws JspException 606 { 607 TableTag tableTag = getTableTag(); 608 609 MediaTypeEnum currentMediaType = (MediaTypeEnum) this.pageContext.findAttribute(TableTag.PAGE_ATTRIBUTE_MEDIA); 610 if (currentMediaType != null && !MediaUtil.availableForMedia(this, currentMediaType)) 611 { 612 if (log.isDebugEnabled()) 613 { 614 log.debug("skipping column body, currentMediaType=" + currentMediaType); 615 } 616 return SKIP_BODY; 617 } 618 619 if (tableTag.isFirstIteration()) 621 { 622 addHeaderToTable(tableTag); 623 } 624 625 if (!tableTag.isIncludedRow()) 626 { 627 return super.doEndTag(); 628 } 629 630 Cell cell = null; 631 if (this.property == null && this.value != null) 632 { 633 cell = new Cell(value); 634 } 635 else if (this.property == null && this.bodyContent != null) 636 { 637 cell = new Cell(this.bodyContent.getString()); 638 } 639 640 Object rowStyle = this.attributeMap.get(TagConstants.ATTRIBUTE_STYLE); 641 Object rowClass = this.attributeMap.get(TagConstants.ATTRIBUTE_CLASS); 642 if (rowStyle != null || rowClass != null) 643 { 644 HtmlAttributeMap perRowValues = new HtmlAttributeMap(); 645 if (rowStyle != null) 646 { 647 perRowValues.put(TagConstants.ATTRIBUTE_STYLE, rowStyle); 648 } 649 if (rowClass != null) 650 { 651 perRowValues.put(TagConstants.ATTRIBUTE_CLASS, rowClass); 652 } 653 if (cell == null) 654 { 655 cell = new Cell(null); 656 } 657 cell.setPerRowAttributes(perRowValues); 658 } 659 660 tableTag.addCell(cell != null ? cell : Cell.EMPTY_CELL); 661 662 this.alreadySorted = false; 664 665 return super.doEndTag(); 666 } 667 668 675 private void addHeaderToTable(TableTag tableTag) throws DecoratorInstantiationException, ObjectLookupException 676 { 677 String evalTitle = this.title; 679 680 if (evalTitle == null && (this.titleKey != null || this.property != null)) 682 { 683 evalTitle = tableTag.getProperties().geResourceProvider().getResource( 685 this.titleKey, 686 this.property, 687 tableTag, 688 this.pageContext); 689 } 690 691 HeaderCell headerCell = new HeaderCell(); 692 headerCell.setHeaderAttributes((HtmlAttributeMap) this.headerAttributeMap.clone()); 693 headerCell.setHtmlAttributes((HtmlAttributeMap) this.attributeMap.clone()); 694 headerCell.setTitle(evalTitle); 695 headerCell.setSortable(this.sortable); 696 697 List decorators = new ArrayList (); 698 699 if (StringUtils.isNotEmpty(this.decorator)) 701 { 702 String [] decoratorNames = StringUtils.split(this.decorator); 703 for (int j = 0; j < decoratorNames.length; j++) 704 { 705 decorators.add(tableTag.getProperties().getDecoratorFactoryInstance().loadColumnDecorator( 706 this.pageContext, 707 decoratorNames[j])); 708 } 709 } 710 711 if (this.escapeXml) 713 { 714 decorators.add(EscapeXmlColumnDecorator.INSTANCE); 715 } 716 if (this.autolink) 717 { 718 decorators.add(AutolinkColumnDecorator.INSTANCE); 719 } 720 if (StringUtils.isNotBlank(this.format)) 721 { 722 decorators.add(new MessageFormatColumnDecorator(this.format, tableTag.getProperties().getLocale())); 723 } 724 725 headerCell.setColumnDecorators((DisplaytagColumnDecorator[]) decorators 726 .toArray(new DisplaytagColumnDecorator[decorators.size()])); 727 728 headerCell.setBeanPropertyName(this.property); 729 headerCell.setShowNulls(this.nulls); 730 headerCell.setMaxLength(this.maxLength); 731 headerCell.setMaxWords(this.maxWords); 732 headerCell.setGroup(this.group); 733 headerCell.setSortProperty(this.sortProperty); 734 headerCell.setTotaled(this.totaled); 735 736 Comparator headerComparator = (comparator != null) ? comparator : new DefaultComparator(Collator 737 .getInstance(tableTag.getProperties().getLocale())); 738 739 headerCell.setComparator(headerComparator); 740 headerCell.setDefaultSortOrder(this.defaultorder); 741 headerCell.setSortName(this.sortName); 742 743 if (this.href != null) 745 { 746 Href colHref; 747 748 if (StringUtils.isEmpty(this.href.getBaseUrl())) 750 { 751 colHref = (Href) tableTag.getBaseHref().clone(); 752 } 753 else 754 { 755 colHref = (Href) this.href.clone(); 756 } 757 758 if (this.paramId != null) 759 { 760 if (this.paramName != null || this.paramScope != null) 762 { 763 StringBuffer expression = new StringBuffer (); 766 767 if (StringUtils.isNotBlank(this.paramScope)) 769 { 770 expression.append(this.paramScope).append("Scope."); 771 } 772 773 if (this.paramId != null) 775 { 776 expression.append(this.paramName); 777 } 778 else 779 { 780 expression.append(tableTag.getName()); 781 } 782 783 if (StringUtils.isNotBlank(this.paramProperty)) 785 { 786 expression.append('.').append(this.paramProperty); 787 } 788 789 Object paramValue = tableTag.evaluateExpression(expression.toString()); 793 794 colHref.addParameter(this.paramId, paramValue); 796 } 797 else 798 { 799 headerCell.setParamName(this.paramId); 801 802 headerCell.setParamProperty(this.paramProperty); 804 } 805 } 806 807 headerCell.setHref(colHref); 809 810 } 811 812 tableTag.addColumn(headerCell); 813 814 if (log.isDebugEnabled()) 815 { 816 log.debug("columnTag.addHeaderToTable() :: first iteration - adding header " + headerCell); 817 } 818 } 819 820 823 public void release() 824 { 825 super.release(); 826 this.attributeMap.clear(); 827 this.autolink = false; 828 this.decorator = null; 829 this.group = -1; 830 this.headerAttributeMap.clear(); 831 this.href = null; 832 this.maxLength = 0; 833 this.maxWords = 0; 834 this.nulls = false; 835 this.paramId = null; 836 this.paramName = null; 837 this.paramProperty = null; 838 this.paramScope = null; 839 this.property = null; 840 this.sortable = false; 841 this.sortName = null; 842 this.supportedMedia = null; 843 this.title = null; 844 this.titleKey = null; 845 this.sortProperty = null; 846 this.comparator = null; 847 this.defaultorder = null; 848 this.escapeXml = false; 849 this.format = null; 850 this.value = null; 851 } 852 853 856 public int doStartTag() throws JspException 857 { 858 TableTag tableTag = getTableTag(); 859 if (tableTag == null) 860 { 861 throw new TagStructureException(getClass(), "column", "table"); 862 } 863 864 if (tableTag.isEmpty() || !tableTag.isIncludedRow()) 866 { 867 return SKIP_BODY; 868 } 869 870 MediaTypeEnum currentMediaType = (MediaTypeEnum) this.pageContext.findAttribute(TableTag.PAGE_ATTRIBUTE_MEDIA); 871 if (!MediaUtil.availableForMedia(this, currentMediaType)) 872 { 873 return SKIP_BODY; 874 } 875 876 return super.doStartTag(); 877 } 878 879 882 public String toString() 883 { 884 return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) .append("bodyContent", this.bodyContent) .append("group", this.group) .append("maxLength", this.maxLength) .append("decorator", this.decorator) .append("href", this.href) .append("title", this.title) .append("paramScope", this.paramScope) .append("property", this.property) .append("paramProperty", this.paramProperty) .append("headerAttributeMap", this.headerAttributeMap) .append("paramName", this.paramName) .append("autolink", this.autolink) .append("format", this.format) .append("nulls", this.nulls) .append("maxWords", this.maxWords) .append("attributeMap", this.attributeMap) .append("sortable", this.sortable) .append("paramId", this.paramId) .append("alreadySorted", this.alreadySorted) .append("sortProperty", this.sortProperty) .append("defaultSortOrder", this.defaultorder) .toString(); 907 } 908 909 } | Popular Tags |