1 16 package org.apache.myfaces.renderkit.html; 17 18 import org.apache.myfaces.renderkit.JSFAttr; 19 import org.apache.myfaces.renderkit.RendererUtils; 20 import org.apache.myfaces.util.ArrayUtils; 21 import org.apache.myfaces.util.StringUtils; 22 import org.apache.myfaces.component.UIColumns; 23 24 import org.apache.commons.logging.Log; 25 import org.apache.commons.logging.LogFactory; 26 27 import javax.faces.component.UIColumn; 28 import javax.faces.component.UIComponent; 29 import javax.faces.component.UIData; 30 import javax.faces.component.html.HtmlDataTable; 31 import javax.faces.context.FacesContext; 32 import javax.faces.context.ResponseWriter; 33 import java.io.IOException ; 34 import java.util.Iterator ; 35 import java.util.List ; 36 37 60 public class HtmlTableRendererBase extends HtmlRenderer 61 { 62 63 protected static final String HEADER_FACET_NAME = "header"; 64 65 66 protected static final String FOOTER_FACET_NAME = "footer"; 67 68 69 private static final Log log = LogFactory.getLog(HtmlTableRendererBase.class); 70 71 74 public boolean getRendersChildren() 75 { 76 return true; 77 } 78 79 82 public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException 83 { 84 RendererUtils.checkParamValidity(facesContext, uiComponent, UIData.class); 85 86 ResponseWriter writer = facesContext.getResponseWriter(); 87 88 beforeTable(facesContext, (UIData) uiComponent); 89 90 HtmlRendererUtils.writePrettyLineSeparator(facesContext); 91 writer.startElement(HTML.TABLE_ELEM, uiComponent); 92 HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent, facesContext); 93 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.TABLE_PASSTHROUGH_ATTRIBUTES); 94 95 renderFacet(facesContext, writer, (UIData) uiComponent, true); 96 } 97 98 101 public void encodeChildren(FacesContext facesContext, UIComponent component) throws IOException 102 { 103 RendererUtils.checkParamValidity(facesContext, component, UIData.class); 104 105 UIData uiData = (UIData) component; 106 107 ResponseWriter writer = facesContext.getResponseWriter(); 108 109 HtmlRendererUtils.writePrettyLineSeparator(facesContext); 110 writer.startElement(HTML.TBODY_ELEM, component); 111 112 String rowClasses; 113 String columnClasses; 114 if (component instanceof HtmlDataTable) 115 { 116 rowClasses = ((HtmlDataTable) component).getRowClasses(); 117 columnClasses = ((HtmlDataTable) component).getColumnClasses(); 118 } 119 else 120 { 121 rowClasses = (String ) component.getAttributes().get(JSFAttr.ROW_CLASSES_ATTR); 122 columnClasses = (String ) component.getAttributes().get(JSFAttr.COLUMN_CLASSES_ATTR); 123 } 124 Styles styles = new Styles(rowClasses, columnClasses); 125 126 int first = uiData.getFirst(); 127 int rows = uiData.getRows(); 128 int rowCount = uiData.getRowCount(); 129 if (rows <= 0) 130 { 131 rows = rowCount - first; 132 } 133 int last = first + rows; 134 if (last > rowCount) 135 last = rowCount; 136 137 for (int i = first; i < last; i++) 138 { 139 uiData.setRowIndex(i); 140 if (!uiData.isRowAvailable()) 141 { 142 log.error("Row is not available. Rowindex = " + i); 143 return; 144 } 145 146 beforeRow(facesContext, uiData); 147 148 HtmlRendererUtils.writePrettyLineSeparator(facesContext); 149 renderRowStart(facesContext, writer, uiData, styles.getRowStyle(i)); 150 151 List children = component.getChildren(); 152 for (int j = 0, size = component.getChildCount(); j < size; j++) 153 { 154 UIComponent child = (UIComponent) children.get(j); 155 if(child.isRendered()) 156 { 157 if (child instanceof UIColumn) 158 { 159 String columnStyle = styles.getColumnStyle(j); 160 renderColumnBody(facesContext, writer, uiData, child, columnStyle); 161 } 162 else if (child instanceof UIColumns) 163 { 164 UIColumns columns = (UIColumns) child; 165 for (int k = 0, colSize = columns.getRowCount(); k < colSize; k++) 166 { 167 columns.setRowIndex(k); 168 String columnStyle = styles.getColumnStyle(j); 169 renderColumnBody(facesContext, writer, uiData, child, columnStyle); 170 } 171 columns.setRowIndex(-1); 172 } 173 } 174 } 175 renderRowEnd(facesContext, writer, uiData); 176 177 afterRow(facesContext, uiData); 178 } 179 writer.endElement(HTML.TBODY_ELEM); 180 } 181 182 192 protected void renderColumnBody( 193 FacesContext facesContext, 194 ResponseWriter writer, 195 UIData uiData, 196 UIComponent component, 197 String columnStyleClass) throws IOException 198 { 199 writer.startElement(HTML.TD_ELEM, uiData); 200 if (columnStyleClass != null) 201 { 202 writer.writeAttribute(HTML.CLASS_ATTR, columnStyleClass, null); 203 } 204 205 RendererUtils.renderChild(facesContext, component); 206 writer.endElement(HTML.TD_ELEM); 207 } 208 209 217 protected void renderRowStart( 218 FacesContext facesContext, 219 ResponseWriter writer, 220 UIData uiData, 221 String rowStyleClass) throws IOException 222 { 223 writer.startElement(HTML.TR_ELEM, uiData); 224 if (rowStyleClass != null) 225 { 226 writer.writeAttribute(HTML.CLASS_ATTR, rowStyleClass, null); 227 } 228 } 229 230 237 protected void renderRowEnd( 238 FacesContext facesContext, 239 ResponseWriter writer, 240 UIData uiData) throws IOException 241 { 242 writer.endElement(HTML.TR_ELEM); 243 } 244 245 250 protected void beforeTable(FacesContext facesContext, UIData uiData) throws IOException 251 { 252 } 253 254 259 protected void beforeRow(FacesContext facesContext, UIData uiData) throws IOException 260 { 261 } 262 263 268 protected void afterRow(FacesContext facesContext, UIData uiData) throws IOException 269 { 270 } 271 272 277 protected void afterTable(FacesContext facesContext, UIData uiData) throws IOException 278 { 279 } 280 281 284 public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException 285 { 286 RendererUtils.checkParamValidity(facesContext, uiComponent, UIData.class); 287 288 ResponseWriter writer = facesContext.getResponseWriter(); 289 renderFacet(facesContext, writer, (UIData) uiComponent, false); 290 writer.endElement(HTML.TABLE_ELEM); 291 HtmlRendererUtils.writePrettyLineSeparator(facesContext); 292 293 afterTable(facesContext, (UIData) uiComponent); 294 } 295 296 304 protected void renderFacet(FacesContext facesContext, ResponseWriter writer, UIComponent component, boolean header) 305 throws IOException 306 { 307 int colspan = 0; 308 boolean hasColumnFacet = false; 309 for (Iterator it = component.getChildren().iterator(); it.hasNext();) 310 { 311 UIComponent uiComponent = (UIComponent) it.next(); 312 if(uiComponent.isRendered()) 313 { 314 if (uiComponent instanceof UIColumn) 315 { 316 colspan++; 317 if (!hasColumnFacet) 318 { 319 hasColumnFacet = header ? ((UIColumn) uiComponent).getHeader() != null : ((UIColumn) uiComponent) 320 .getFooter() != null; 321 } 322 } 323 else if (uiComponent instanceof UIColumns) 324 { 325 UIColumns columns = (UIColumns) uiComponent; 326 colspan += columns.getRowCount(); 327 if (!hasColumnFacet) 328 { 329 hasColumnFacet = header ? columns.getHeader() != null : columns.getFooter() != null; 330 } 331 } 332 } 333 } 334 335 UIComponent facet = header ? (UIComponent) component.getFacets().get(HEADER_FACET_NAME) 336 : (UIComponent) component.getFacets().get(FOOTER_FACET_NAME); 337 if (facet != null || hasColumnFacet) 338 { 339 String elemName = header ? HTML.THEAD_ELEM : HTML.TFOOT_ELEM; 341 342 HtmlRendererUtils.writePrettyLineSeparator(facesContext); 343 writer.startElement(elemName, component); 344 if (header) 345 { 346 String headerStyleClass = getHeaderClass(component); 347 if (facet != null) 348 renderTableHeaderRow(facesContext, writer, component, facet, headerStyleClass, colspan); 349 if (hasColumnFacet) 350 renderColumnHeaderRow(facesContext, writer, component, headerStyleClass); 351 } 352 else 353 { 354 String footerStyleClass = getFooterClass(component); 355 if (hasColumnFacet) 356 renderColumnFooterRow(facesContext, writer, component, footerStyleClass); 357 if (facet != null) 358 renderTableFooterRow(facesContext, writer, component, facet, footerStyleClass, colspan); 359 } 360 writer.endElement(elemName); 361 } 362 } 363 364 375 protected void renderTableHeaderRow(FacesContext facesContext, ResponseWriter writer, UIComponent component, 376 UIComponent headerFacet, String headerStyleClass, int colspan) throws IOException 377 { 378 renderTableHeaderOrFooterRow(facesContext, writer, component, headerFacet, headerStyleClass, HTML.TH_ELEM, 379 colspan); 380 } 381 382 393 protected void renderTableFooterRow(FacesContext facesContext, ResponseWriter writer, UIComponent component, 394 UIComponent footerFacet, String footerStyleClass, int colspan) throws IOException 395 { 396 renderTableHeaderOrFooterRow(facesContext, writer, component, footerFacet, footerStyleClass, HTML.TD_ELEM, 397 colspan); 398 } 399 400 409 protected void renderColumnHeaderRow(FacesContext facesContext, ResponseWriter writer, UIComponent component, 410 String headerStyleClass) throws IOException 411 { 412 renderColumnHeaderOrFooterRow(facesContext, writer, component, headerStyleClass, true); 413 } 414 415 424 protected void renderColumnFooterRow(FacesContext facesContext, ResponseWriter writer, UIComponent component, 425 String footerStyleClass) throws IOException 426 { 427 renderColumnHeaderOrFooterRow(facesContext, writer, component, footerStyleClass, false); 428 } 429 430 private void renderTableHeaderOrFooterRow(FacesContext facesContext, ResponseWriter writer, UIComponent component, 431 UIComponent facet, String styleClass, String colElementName, int colspan) throws IOException 432 { 433 HtmlRendererUtils.writePrettyLineSeparator(facesContext); 434 writer.startElement(HTML.TR_ELEM, component); 435 writer.startElement(colElementName, component); 436 if (colElementName.equals(HTML.TH_ELEM)) 437 { 438 writer.writeAttribute(HTML.SCOPE_ATTR, HTML.SCOPE_COLGROUP_VALUE, null); 439 } 440 writer.writeAttribute(HTML.COLSPAN_ATTR, new Integer (colspan), null); 441 if (styleClass != null) 442 { 443 writer.writeAttribute(HTML.CLASS_ATTR, styleClass, null); 444 } 445 if (facet != null) 446 { 447 RendererUtils.renderChild(facesContext, facet); 448 } 449 writer.endElement(colElementName); 450 writer.endElement(HTML.TR_ELEM); 451 } 452 453 private void renderColumnHeaderOrFooterRow(FacesContext facesContext, ResponseWriter writer, 454 UIComponent component, String styleClass, boolean header) throws IOException 455 { 456 HtmlRendererUtils.writePrettyLineSeparator(facesContext); 457 458 writer.startElement(HTML.TR_ELEM, component); 459 for (Iterator it = component.getChildren().iterator(); it.hasNext();) 460 { 461 UIComponent uiComponent = (UIComponent) it.next(); 462 if(uiComponent.isRendered()) 463 { 464 if (uiComponent instanceof UIColumn) 465 { 466 if (header) 467 { 468 renderColumnHeaderCell(facesContext, writer, uiComponent, 469 ((UIColumn) uiComponent).getHeader(), styleClass, 0); 470 } 471 else 472 { 473 renderColumnFooterCell(facesContext, writer, uiComponent, 474 ((UIColumn) uiComponent).getFooter(), styleClass, 0); 475 } 476 } 477 else if (uiComponent instanceof UIColumns) 478 { 479 UIColumns columns = (UIColumns) uiComponent; 480 for (int i = 0, size = columns.getRowCount(); i < size; i++) 481 { 482 columns.setRowIndex(i); 483 if (header) 484 { 485 renderColumnHeaderCell(facesContext, writer, columns, columns.getHeader(), 486 styleClass, 0); 487 } 488 else 489 { 490 renderColumnFooterCell(facesContext, writer, columns, columns.getFooter(), 491 styleClass, 0); 492 } 493 } 494 columns.setRowIndex(-1); 495 } 496 } 497 } 498 writer.endElement(HTML.TR_ELEM); 499 } 500 501 511 protected void renderColumnHeaderCell(FacesContext facesContext, ResponseWriter writer, UIColumn uiColumn, 512 String headerStyleClass, int colspan) throws IOException 513 { 514 renderColumnHeaderCell(facesContext, writer, uiColumn, uiColumn.getHeader(), headerStyleClass, colspan); 515 } 516 517 528 protected void renderColumnHeaderCell(FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent, 529 UIComponent facet, String headerStyleClass, int colspan) throws IOException 530 { 531 writer.startElement(HTML.TH_ELEM, uiComponent); 532 if (colspan > 1) 533 { 534 writer.writeAttribute(HTML.COLSPAN_ATTR, new Integer (colspan), null); 535 } 536 if (headerStyleClass != null) 537 { 538 writer.writeAttribute(HTML.CLASS_ATTR, headerStyleClass, null); 539 } 540 if (facet != null) 541 { 542 RendererUtils.renderChild(facesContext, facet); 543 } 544 writer.endElement(HTML.TH_ELEM); 545 } 546 547 557 protected void renderColumnFooterCell(FacesContext facesContext, ResponseWriter writer, UIColumn uiColumn, 558 String footerStyleClass, int colspan) throws IOException 559 { 560 renderColumnFooterCell(facesContext, writer, uiColumn, uiColumn.getFooter(), footerStyleClass, colspan); 561 } 562 563 574 protected void renderColumnFooterCell(FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent, 575 UIComponent facet, String footerStyleClass, int colspan) throws IOException 576 { 577 writer.startElement(HTML.TD_ELEM, uiComponent); 578 if (colspan > 1) 579 { 580 writer.writeAttribute(HTML.COLSPAN_ATTR, new Integer (colspan), null); 581 } 582 if (footerStyleClass != null) 583 { 584 writer.writeAttribute(HTML.CLASS_ATTR, footerStyleClass, null); 585 } 586 if (facet != null) 587 { 588 RendererUtils.renderChild(facesContext, facet); 589 } 590 writer.endElement(HTML.TD_ELEM); 591 } 592 593 598 protected static String getHeaderClass(UIComponent component) 599 { 600 if (component instanceof HtmlDataTable) 601 { 602 return ((HtmlDataTable) component).getHeaderClass(); 603 } 604 else 605 { 606 return (String ) component.getAttributes().get(JSFAttr.HEADER_CLASS_ATTR); 607 } 608 } 609 610 615 protected static String getFooterClass(UIComponent component) 616 { 617 if (component instanceof HtmlDataTable) 618 { 619 return ((HtmlDataTable) component).getFooterClass(); 620 } 621 else 622 { 623 return (String ) component.getAttributes().get(JSFAttr.FOOTER_CLASS_ATTR); 624 } 625 } 626 627 private static class Styles 631 { 632 635 private String [] _columnStyle; 636 637 private String [] _rowStyle; 638 639 Styles(String rowStyles, String columnStyles) 642 { 643 _rowStyle = (rowStyles == null) ? ArrayUtils.EMPTY_STRING_ARRAY : StringUtils.trim(StringUtils 644 .splitShortString(rowStyles, ',')); 645 _columnStyle = (columnStyles == null) ? ArrayUtils.EMPTY_STRING_ARRAY : StringUtils.trim(StringUtils 646 .splitShortString(columnStyles, ',')); 647 } 648 649 public String getRowStyle(int idx) 650 { 651 if (!hasRowStyle()) 652 { 653 return null; 654 } 655 return _rowStyle[idx % _rowStyle.length]; 656 } 657 658 public String getColumnStyle(int idx) 659 { 660 if (!hasColumnStyle()) 661 { 662 return null; 663 } 664 return _columnStyle[idx % _columnStyle.length]; 665 } 666 667 public boolean hasRowStyle() 668 { 669 return _rowStyle.length > 0; 670 } 671 672 public boolean hasColumnStyle() 673 { 674 return _columnStyle.length > 0; 675 } 676 677 } 678 679 public void decode(FacesContext context, UIComponent component) 680 { 681 super.decode(context, component); 682 } 683 684 } | Popular Tags |