KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icesoft > faces > renderkit > dom_html_basic > TableRenderer


1 /*
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * "The contents of this file are subject to the Mozilla Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
11  * License for the specific language governing rights and limitations under
12  * the License.
13  *
14  * The Original Code is ICEfaces 1.5 open source software code, released
15  * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
16  * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
17  * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
18  *
19  * Contributor(s): _____________________.
20  *
21  * Alternatively, the contents of this file may be used under the terms of
22  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
23  * License), in which case the provisions of the LGPL License are
24  * applicable instead of those above. If you wish to allow use of your
25  * version of this file only under the terms of the LGPL License and not to
26  * allow others to use your version of this file under the MPL, indicate
27  * your decision by deleting the provisions above and replace them with
28  * the notice and other provisions required by the LGPL License. If you do
29  * not delete the provisions above, a recipient may use your version of
30  * this file under either the MPL or the LGPL License."
31  *
32  */

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 JavaDoc;
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 JavaDoc;
46 import java.util.ArrayList JavaDoc;
47 import java.util.Iterator JavaDoc;
48 import java.util.List JavaDoc;
49 import java.util.StringTokenizer JavaDoc;
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 JavaDoc {
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 JavaDoc root = null;
68             root = domContext.createRootElement("table");
69             setRootElementId(facesContext, root, uiComponent);
70             PassThruAttributeRenderer.renderAttributes(
71                     facesContext, uiComponent, null);
72         }
73         Element JavaDoc root = (Element JavaDoc) domContext.getRootNode();
74         DOMContext.removeChildren(root);
75         String JavaDoc 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 JavaDoc tr = domContext.createElement("tr");
82             root.appendChild(tr);
83             Element JavaDoc td = domContext.createElement("td");
84             tr.appendChild(td);
85             Element JavaDoc mainDiv = domContext.createElement("div");
86             td.appendChild(mainDiv);
87             Element JavaDoc headerDiv = domContext.createElement("div");
88             Element JavaDoc headerTable = domContext.createElement("table");
89             headerDiv.appendChild(headerTable);
90
91             mainDiv.appendChild(headerDiv);
92             Element JavaDoc bodyDiv = domContext.createElement("div");
93             String JavaDoc height =
94                     (String JavaDoc) uiComponent.getAttributes().get("scrollHeight");
95             bodyDiv.setAttribute("style",
96                                  "overflow:auto;height:" + height + ";");
97
98             Element JavaDoc bodytable = domContext.createElement("table");
99             bodyDiv.appendChild(bodytable);
100             mainDiv.appendChild(bodyDiv);
101         }
102         renderFacet(facesContext, uiComponent, domContext, true); //header facet
103
renderFacet(facesContext, uiComponent, domContext,
104                     false); //footer facet
105
}
106
107     // this method is overridden in the subclass
108
public String JavaDoc getComponentStyleClass(UIComponent uiComponent) {
109         String JavaDoc styleClass =
110                 (String JavaDoc) 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 JavaDoc {
120         String JavaDoc 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 JavaDoc root = (Element JavaDoc) domContext.getRootNode();
135         if (isScrollable(uiComponent)) {
136             if (header) {
137                 Element JavaDoc headerDiv = domContext.createElement("div");
138                 Element JavaDoc headerTable = domContext.createElement("table");
139                 headerDiv.appendChild(headerTable);
140                 root.getFirstChild().getFirstChild().appendChild(headerDiv);
141                 root = headerTable;
142             } else {
143                 // Get the table in the second div
144
root = (Element JavaDoc) root.getChildNodes().item(1).getFirstChild();
145             }
146         }
147
148         // detect whether a facet exists on the UIData component or any of the
149
// child UIColumn components; if so, then render a thead element
150
UIComponent headerFacet = getFacetByName(uiData, facet);
151         boolean childHeaderFacetExists =
152                 childColumnHasFacetWithName(uiData, facet);
153         Element JavaDoc thead = null;
154         if (headerFacet != null || childHeaderFacetExists) {
155             thead = domContext.createElement(tag);
156             root.appendChild(thead);
157         }
158         // if the header is associated with the UIData component then encode the
159
// header inside a tr and th element that span the whole table.
160
if (headerFacet != null && headerFacet.isRendered()) {
161             resetFacetChildId(headerFacet);
162             Element JavaDoc tr = domContext.createElement("tr");
163             thead.appendChild(tr);
164             Element JavaDoc 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 one or more of the child columns has a header facet then render a
179
// row to accommodate the header(s); render an empty th for each column
180
// that has no header facet
181
if (childHeaderFacetExists) {
182             Element JavaDoc tr = domContext.createElement("tr");
183             thead.appendChild(tr);
184             StringTokenizer JavaDoc columnWidths =
185                     getColumnWidths(uiData);
186
187             Iterator JavaDoc childColumns = getRenderedChildColumnsIterator(uiData);
188             while (childColumns.hasNext()) {
189
190
191                 UIColumn nextColumn = (UIColumn) childColumns.next();
192                 Element JavaDoc 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 JavaDoc 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 JavaDoc facetChild = component.getChildren().iterator();
223         while (facetChild.hasNext()) {
224             UIComponent child = (UIComponent) facetChild.next();
225             resetFacetChildId(child);
226         }
227     }
228
229     // this method is overridden in the subclass
230
public String JavaDoc getHeaderClass(UIComponent component) {
231         return (String JavaDoc) component.getAttributes().get("headerClass");
232     }
233
234
235     public String JavaDoc getFooterClass(UIComponent component) {
236         return (String JavaDoc) component.getAttributes().get("footerClass");
237     }
238
239
240
241     protected boolean childColumnHasFacetWithName(UIComponent component,
242                                                   String JavaDoc facetName) {
243         Iterator JavaDoc 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 JavaDoc {
256
257         validateParameters(facesContext, uiComponent, null);
258
259         DOMContext domContext =
260                 DOMContext.attachDOMContext(facesContext, uiComponent);
261         Element JavaDoc root = (Element JavaDoc) domContext.getRootNode();
262
263         Element JavaDoc tbody = domContext.createElement("tbody");
264         root.appendChild(tbody);
265
266         // render the appropriate styles for each row and column
267
String JavaDoc columnStyles[] = getColumnStyleClasses(uiComponent);
268
269         String JavaDoc 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         // keep track of row index on UIData component and how many rows we've displayed
276
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             // Have we finished the required number of rows ? Note that
284
// numberOfRowsToDisplay == 0 means that we display all remaining rows
285
// of the underlying model and in this case we rely on the
286
// isRowAvailable method (above) to limit rendering work.
287
if (numberOfRowsToDisplay > 0
288                 && countOfRowsDisplayed >= numberOfRowsToDisplay) {
289                 break;
290             }
291             // render another row
292
Element JavaDoc tr = domContext.createElement("tr");
293             tr.setAttribute("id", uiComponent.getClientId(facesContext));
294             tbody.appendChild(tr);
295             // if row styles exist, then render the appropriate one
296
if (rowStylesMaxIndex >= 0) {
297                 tr.setAttribute("class", rowStyles[rowStyleIndex]);
298                 if (++rowStyleIndex > rowStylesMaxIndex) {
299                     rowStyleIndex = 0;
300                 }
301             }
302             // render the child columns; each one in a td
303
Iterator JavaDoc childColumns;
304             childColumns = getRenderedChildColumnsIterator(uiData);
305             StringTokenizer JavaDoc columnWidths =
306                     getColumnWidths(uiComponent);
307
308             int colNumber = 1;
309             while (childColumns.hasNext()) {
310                 // render another td
311
UIColumn nextColumn = (UIColumn) childColumns.next();
312                 Element JavaDoc 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                 // if column styles exist, then apply the appropriate one
320
writeColStyles(columnStyles, columnStylesMaxIndex,
321                                columnStyleIndex, td, colNumber++,
322                                uiComponent);
323                 if (++columnStyleIndex > columnStylesMaxIndex) {
324                     columnStyleIndex = 0;
325                 }
326
327                 // recursively render the components contained within this td (column)
328
Iterator JavaDoc 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             // keep track of rows displayed
342
countOfRowsDisplayed++;
343             // maintain the row index property on the underlying UIData component
344
rowIndex++;
345             uiData.setRowIndex(rowIndex);
346             // reset the column style index for the next row
347
columnStyleIndex = 0;
348
349
350         }
351         // reset the underlying UIData component
352
uiData.setRowIndex(-1);
353         domContext.stepOver();
354         domContext.streamWrite(facesContext, uiComponent);
355     }
356
357     // this method is overridden in the subclass
358
public void writeColStyles(String JavaDoc[] columnStyles, int columnStylesMaxIndex,
359                                int columnStyleIndex, Element JavaDoc 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     // this method is overridden in the subclass
373
public String JavaDoc[] getRowStyles(UIComponent uiComponent) {
374         return getRowStyleClasses(uiComponent);
375     }
376
377     public void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
378             throws IOException JavaDoc {
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 JavaDoc getRenderedChildColumnsIterator(UIComponent component) {
390         return getRenderedChildColumnsList(component).iterator();
391     }
392
393     protected List JavaDoc getRenderedChildColumnsList(UIComponent component) {
394         List JavaDoc results = new ArrayList JavaDoc();
395         Iterator JavaDoc 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 JavaDoc o = uiComponent.getAttributes().get("scrollable");
407         if (o != null && o instanceof Boolean JavaDoc) {
408             return ((Boolean JavaDoc) o).booleanValue();
409         }
410         return false;
411     }
412
413     protected Element JavaDoc scrollBarSpacer(DOMContext domContext, FacesContext facesContext) {
414         Element JavaDoc spacer = domContext.createElement("th");
415         //spacer.setAttribute("style", "width:20px;");
416
String JavaDoc url = getResourceURL(facesContext, "/xmlhttp/css/xp/css-images/selection_spacer.gif");
417         Element JavaDoc 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 JavaDoc getColumnWidths(UIComponent uiComponent) {
425         Object JavaDoc o = uiComponent.getAttributes().get("columnWidths");
426         if (o != null && o instanceof String JavaDoc) {
427             return new StringTokenizer JavaDoc(o.toString(), ",");
428         }
429         return null;
430     }
431     
432     protected Element JavaDoc getScrollableHeaderTableElement(Element JavaDoc root) {
433         // First table in first div path : table/tr/td/div/div0/table
434
return (Element JavaDoc) root.getFirstChild().getFirstChild().getFirstChild().getFirstChild().getFirstChild();
435     }
436     
437     protected Element JavaDoc getScrollableBodyTableElement(Element JavaDoc root) {
438         // First table in second div path table/tr/td/div/div1/table
439
return (Element JavaDoc) root.getFirstChild().getFirstChild().getFirstChild().getFirstChild().getNextSibling().getFirstChild();
440     }
441 }
442
Popular Tags