| 1 33 34 package com.icesoft.faces.renderkit.dom_html_basic; 35 36 import com.icesoft.faces.context.DOMContext; 37 import com.icesoft.faces.util.Debug; 38 import org.w3c.dom.Element ; 39 40 import javax.faces.component.UIColumn; 41 import javax.faces.component.UIComponent; 42 import javax.faces.component.UIData; 43 import javax.faces.context.FacesContext; 44 import javax.faces.context.ResponseWriter; 45 import java.io.IOException ; 46 import java.util.ArrayList ; 47 import java.util.Iterator ; 48 import java.util.List ; 49 import java.util.StringTokenizer ; 50 51 public class TableRenderer extends DomBasicRenderer { 52 53 public boolean getRendersChildren() { 54 return true; 55 } 56 57 public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) 58 throws IOException { 59 60 validateParameters(facesContext, uiComponent, null); 61 ResponseWriter responseWriter = facesContext.getResponseWriter(); 62 Debug.assertTrue(responseWriter != null, "ResponseWriter is null"); 63 DOMContext domContext = 64 DOMContext.attachDOMContext(facesContext, uiComponent); 65 66 if (!domContext.isInitialized()) { 67 Element root = null; 68 root = domContext.createRootElement("table"); 69 setRootElementId(facesContext, root, uiComponent); 70 PassThruAttributeRenderer.renderAttributes( 71 facesContext, uiComponent, null); 72 } 73 Element root = (Element ) domContext.getRootNode(); 74 DOMContext.removeChildren(root); 75 String styleClass = getComponentStyleClass(uiComponent); 76 if (styleClass != null && styleClass.length() > 0) { 77 root.setAttribute("class", styleClass); 78 } 79 root.setAttribute(HTML.CELLSPACING_ATTR, "0"); 80 if (isScrollable(uiComponent)) { 81 Element tr = domContext.createElement("tr"); 82 root.appendChild(tr); 83 Element td = domContext.createElement("td"); 84 tr.appendChild(td); 85 Element mainDiv = domContext.createElement("div"); 86 td.appendChild(mainDiv); 87 Element headerDiv = domContext.createElement("div"); 88 Element headerTable = domContext.createElement("table"); 89 headerDiv.appendChild(headerTable); 90 91 mainDiv.appendChild(headerDiv); 92 Element bodyDiv = domContext.createElement("div"); 93 String height = 94 (String ) uiComponent.getAttributes().get("scrollHeight"); 95 bodyDiv.setAttribute("style", 96 "overflow:auto;height:" + height + ";"); 97 98 Element bodytable = domContext.createElement("table"); 99 bodyDiv.appendChild(bodytable); 100 mainDiv.appendChild(bodyDiv); 101 } 102 renderFacet(facesContext, uiComponent, domContext, true); renderFacet(facesContext, uiComponent, domContext, 104 false); } 106 107 public String getComponentStyleClass(UIComponent uiComponent) { 109 String styleClass = 110 (String ) uiComponent.getAttributes().get("styleClass"); 111 return styleClass; 112 } 113 114 115 116 protected void renderFacet(FacesContext facesContext, 117 UIComponent uiComponent, 118 DOMContext domContext, boolean header) 119 throws IOException { 120 String facet, tag, element, facetClass; 121 if (header) { 122 facet = "header"; 123 tag = HTML.THEAD_ELEM; 124 element = HTML.TH_ELEM; 125 facetClass = getHeaderClass(uiComponent); 126 } else { 127 facet = "footer"; 128 tag = HTML.TFOOT_ELEM; 129 element = HTML.TD_ELEM; 130 facetClass = getFooterClass(uiComponent); 131 } 132 UIData uiData = (UIData) uiComponent; 133 uiData.setRowIndex(-1); 134 Element root = (Element ) domContext.getRootNode(); 135 if (isScrollable(uiComponent)) { 136 if (header) { 137 Element headerDiv = domContext.createElement("div"); 138 Element headerTable = domContext.createElement("table"); 139 headerDiv.appendChild(headerTable); 140 root.getFirstChild().getFirstChild().appendChild(headerDiv); 141 root = headerTable; 142 } else { 143 root = (Element ) root.getChildNodes().item(1).getFirstChild(); 145 } 146 } 147 148 UIComponent headerFacet = getFacetByName(uiData, facet); 151 boolean childHeaderFacetExists = 152 childColumnHasFacetWithName(uiData, facet); 153 Element thead = null; 154 if (headerFacet != null || childHeaderFacetExists) { 155 thead = domContext.createElement(tag); 156 root.appendChild(thead); 157 } 158 if (headerFacet != null && headerFacet.isRendered()) { 161 resetFacetChildId(headerFacet); 162 Element tr = domContext.createElement("tr"); 163 thead.appendChild(tr); 164 Element th = domContext.createElement(element); 165 tr.appendChild(th); 166 if (facetClass != null) { 167 th.setAttribute("class", facetClass); 168 } 169 th.setAttribute("colspan", 170 String.valueOf(getNumberOfChildColumns(uiData))); 171 th.setAttribute("scope", "colgroup"); 172 domContext.setCursorParent(th); 173 domContext.streamWrite(facesContext, uiComponent, 174 domContext.getRootNode(), th); 175 encodeParentAndChildren(facesContext, headerFacet); 176 } 177 178 if (childHeaderFacetExists) { 182 Element tr = domContext.createElement("tr"); 183 thead.appendChild(tr); 184 StringTokenizer columnWidths = 185 getColumnWidths(uiData); 186 187 Iterator childColumns = getRenderedChildColumnsIterator(uiData); 188 while (childColumns.hasNext()) { 189 190 191 UIColumn nextColumn = (UIColumn) childColumns.next(); 192 Element th = domContext.createElement(element); 193 tr.appendChild(th); 194 if (facetClass != null) { 195 th.setAttribute("class", facetClass); 196 } 197 if (columnWidths != null && columnWidths.hasMoreTokens()) { 198 String width = columnWidths.nextToken(); 199 200 th.setAttribute("style", 201 "width:" + width + ";overflow:hidden;"); 202 } 203 th.setAttribute("colgroup", "col"); 204 UIComponent nextFacet = getFacetByName(nextColumn, facet); 205 if (nextFacet != null) { 206 resetFacetChildId(nextFacet); 207 domContext.setCursorParent(th); 208 domContext.streamWrite(facesContext, uiComponent, 209 domContext.getRootNode(), th); 210 encodeParentAndChildren(facesContext, nextFacet); 211 } 212 } 213 if (isScrollable(uiComponent)) { 214 tr.appendChild(scrollBarSpacer(domContext, facesContext)); 215 } 216 } 217 domContext.setCursorParent(root); 218 } 219 220 protected void resetFacetChildId(UIComponent component) { 221 component.setId(component.getId()); 222 Iterator facetChild = component.getChildren().iterator(); 223 while (facetChild.hasNext()) { 224 UIComponent child = (UIComponent) facetChild.next(); 225 resetFacetChildId(child); 226 } 227 } 228 229 public String getHeaderClass(UIComponent component) { 231 return (String ) component.getAttributes().get("headerClass"); 232 } 233 234 235 public String getFooterClass(UIComponent component) { 236 return (String ) component.getAttributes().get("footerClass"); 237 } 238 239 240 241 protected boolean childColumnHasFacetWithName(UIComponent component, 242 String facetName) { 243 Iterator childColumns = getRenderedChildColumnsIterator(component); 244 while (childColumns.hasNext()) { 245 UIColumn nextChildColumn = (UIColumn) childColumns.next(); 246 if (getFacetByName(nextChildColumn, facetName) != null) { 247 return true; 248 } 249 } 250 return false; 251 } 252 253 public void encodeChildren(FacesContext facesContext, 254 UIComponent uiComponent) 255 throws IOException { 256 257 validateParameters(facesContext, uiComponent, null); 258 259 DOMContext domContext = 260 DOMContext.attachDOMContext(facesContext, uiComponent); 261 Element root = (Element ) domContext.getRootNode(); 262 263 Element tbody = domContext.createElement("tbody"); 264 root.appendChild(tbody); 265 266 String columnStyles[] = getColumnStyleClasses(uiComponent); 268 269 String rowStyles[] = getRowStyles(uiComponent); 270 271 int columnStyleIndex = 0; 272 int rowStyleIndex = 0; 273 int columnStylesMaxIndex = columnStyles.length - 1; 274 int rowStylesMaxIndex = rowStyles.length - 1; 275 UIData uiData = (UIData) uiComponent; 277 int rowIndex = uiData.getFirst(); 278 int numberOfRowsToDisplay = uiData.getRows(); 279 int countOfRowsDisplayed = 0; 280 uiData.setRowIndex(rowIndex); 281 282 while (uiData.isRowAvailable()) { 283 if (numberOfRowsToDisplay > 0 288 && countOfRowsDisplayed >= numberOfRowsToDisplay) { 289 break; 290 } 291 Element tr = domContext.createElement("tr"); 293 tr.setAttribute("id", uiComponent.getClientId(facesContext)); 294 tbody.appendChild(tr); 295 if (rowStylesMaxIndex >= 0) { 297 tr.setAttribute("class", rowStyles[rowStyleIndex]); 298 if (++rowStyleIndex > rowStylesMaxIndex) { 299 rowStyleIndex = 0; 300 } 301 } 302 Iterator childColumns; 304 childColumns = getRenderedChildColumnsIterator(uiData); 305 StringTokenizer columnWidths = 306 getColumnWidths(uiComponent); 307 308 int colNumber = 1; 309 while (childColumns.hasNext()) { 310 UIColumn nextColumn = (UIColumn) childColumns.next(); 312 Element td = domContext.createElement("td"); 313 if (columnWidths != null && columnWidths.hasMoreTokens()) { 314 td.setAttribute("style", 315 "width:" + columnWidths.nextToken() + ";"); 316 } 317 tr.appendChild(td); 318 319 writeColStyles(columnStyles, columnStylesMaxIndex, 321 columnStyleIndex, td, colNumber++, 322 uiComponent); 323 if (++columnStyleIndex > columnStylesMaxIndex) { 324 columnStyleIndex = 0; 325 } 326 327 Iterator childrenOfThisColumn = 329 nextColumn.getChildren().iterator(); 330 domContext.setCursorParent(td); 331 domContext.streamWrite(facesContext, uiComponent, 332 domContext.getRootNode(), td); 333 while (childrenOfThisColumn.hasNext()) { 334 UIComponent nextChild = 335 (UIComponent) childrenOfThisColumn.next(); 336 if (nextChild.isRendered()) { 337 encodeParentAndChildren(facesContext, nextChild); 338 } 339 } 340 } 341 countOfRowsDisplayed++; 343 rowIndex++; 345 uiData.setRowIndex(rowIndex); 346 columnStyleIndex = 0; 348 349 350 } 351 uiData.setRowIndex(-1); 353 domContext.stepOver(); 354 domContext.streamWrite(facesContext, uiComponent); 355 } 356 357 public void writeColStyles(String [] columnStyles, int columnStylesMaxIndex, 359 int columnStyleIndex, Element td, 360 int colNumber, 361 UIComponent uiComponent) { 362 if (columnStyles.length > 0) { 363 if (columnStylesMaxIndex >= 0) { 364 td.setAttribute("class", columnStyles[columnStyleIndex]); 365 if (++columnStyleIndex > columnStylesMaxIndex) { 366 columnStyleIndex = 0; 367 } 368 } 369 } 370 } 371 372 public String [] getRowStyles(UIComponent uiComponent) { 374 return getRowStyleClasses(uiComponent); 375 } 376 377 public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) 378 throws IOException { 379 validateParameters(facesContext, uiComponent, null); 380 if (!uiComponent.isRendered()) { 381 return; 382 } 383 } 384 385 protected int getNumberOfChildColumns(UIComponent component) { 386 return getRenderedChildColumnsList(component).size(); 387 } 388 389 protected Iterator getRenderedChildColumnsIterator(UIComponent component) { 390 return getRenderedChildColumnsList(component).iterator(); 391 } 392 393 protected List getRenderedChildColumnsList(UIComponent component) { 394 List results = new ArrayList (); 395 Iterator kids = component.getChildren().iterator(); 396 while (kids.hasNext()) { 397 UIComponent kid = (UIComponent) kids.next(); 398 if ((kid instanceof UIColumn) && kid.isRendered()) { 399 results.add(kid); 400 } 401 } 402 return results; 403 } 404 405 protected boolean isScrollable(UIComponent uiComponent) { 406 Object o = uiComponent.getAttributes().get("scrollable"); 407 if (o != null && o instanceof Boolean ) { 408 return ((Boolean ) o).booleanValue(); 409 } 410 return false; 411 } 412 413 protected Element scrollBarSpacer(DOMContext domContext, FacesContext facesContext) { 414 Element spacer = domContext.createElement("th"); 415 String url = getResourceURL(facesContext, "/xmlhttp/css/xp/css-images/selection_spacer.gif"); 417 Element spacerImg = domContext.createElement(HTML.IMG_ELEM); 418 spacerImg.setAttribute(HTML.SRC_ATTR, url); 419 spacerImg.setAttribute(HTML.BORDER_ATTR,"0"); 420 spacer.appendChild(spacerImg); 421 return spacer; 422 } 423 424 protected StringTokenizer getColumnWidths(UIComponent uiComponent) { 425 Object o = uiComponent.getAttributes().get("columnWidths"); 426 if (o != null && o instanceof String ) { 427 return new StringTokenizer (o.toString(), ","); 428 } 429 return null; 430 } 431 432 protected Element getScrollableHeaderTableElement(Element root) { 433 return (Element ) root.getFirstChild().getFirstChild().getFirstChild().getFirstChild().getFirstChild(); 435 } 436 437 protected Element getScrollableBodyTableElement(Element root) { 438 return (Element ) root.getFirstChild().getFirstChild().getFirstChild().getFirstChild().getNextSibling().getFirstChild(); 440 } 441 } 442 | Popular Tags |