Source Code Cross Referenced for HtmlTableRendererBase.java in  » J2EE » myfaces-core-1.2.0 » org » apache » myfaces » shared_impl » renderkit » html » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » myfaces core 1.2.0 » org.apache.myfaces.shared_impl.renderkit.html 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2004 The Apache Software Foundation.
003:         *
004:         * Licensed under the Apache License, Version 2.0 (the "License");
005:         * you may not use this file except in compliance with the License.
006:         * You may obtain a copy of the License at
007:         *
008:         *      http://www.apache.org/licenses/LICENSE-2.0
009:         *
010:         * Unless required by applicable law or agreed to in writing, software
011:         * distributed under the License is distributed on an "AS IS" BASIS,
012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013:         * See the License for the specific language governing permissions and
014:         * limitations under the License.
015:         */
016:        package org.apache.myfaces.shared_impl.renderkit.html;
017:
018:        import org.apache.commons.logging.Log;
019:        import org.apache.commons.logging.LogFactory;
020:        import org.apache.myfaces.shared_impl.renderkit.JSFAttr;
021:        import org.apache.myfaces.shared_impl.renderkit.RendererUtils;
022:        import org.apache.myfaces.shared_impl.util.ArrayUtils;
023:        import org.apache.myfaces.shared_impl.util.StringUtils;
024:
025:        import javax.faces.component.UIColumn;
026:        import javax.faces.component.UIComponent;
027:        import javax.faces.component.UIData;
028:        import javax.faces.component.html.HtmlColumn;
029:        import javax.faces.component.html.HtmlDataTable;
030:        import javax.faces.context.FacesContext;
031:        import javax.faces.context.ResponseWriter;
032:        import java.io.IOException;
033:        import java.util.Iterator;
034:        import java.util.List;
035:
036:        /**
037:         * Common methods for renderers for components that subclass the standard
038:         * JSF HtmlDataTable component.
039:         * 
040:         * @author Thomas Spiegl (latest modification by $Author: baranda $)
041:         * @version $Revision: 544646 $ $Date: 2007-06-05 23:51:27 +0200 (Di, 05 Jun 2007) $
042:         */
043:        public class HtmlTableRendererBase extends HtmlRenderer {
044:            /** Header facet name. */
045:            protected static final String HEADER_FACET_NAME = "header";
046:
047:            /** Footer facet name. */
048:            protected static final String FOOTER_FACET_NAME = "footer";
049:
050:            protected static final String CAPTION_FACET_NAME = "caption";
051:
052:            /** The logger. */
053:            private static final Log log = LogFactory
054:                    .getLog(HtmlTableRendererBase.class);
055:
056:            /**
057:             * @param component dataTable
058:             * @return number of layout columns
059:             */
060:            protected int getNewspaperColumns(UIComponent component) {
061:                return 1;
062:            }
063:
064:            /**
065:             * @param component dataTable
066:             * @return component to display between layout columns
067:             */
068:            protected UIComponent getNewspaperTableSpacer(UIComponent component) {
069:                return null;
070:            }
071:
072:            /**
073:             * @param component dataTable
074:             * @return whether dataTable has component to display between layout columns
075:             */
076:            protected boolean hasNewspaperTableSpacer(UIComponent component) {
077:                return false;
078:            }
079:
080:            /**
081:             * @param component dataTable
082:             * @return whether dataTable has newspaper columns layed out horizontally
083:             */
084:            protected boolean isNewspaperHorizontalOrientation(
085:                    UIComponent component) {
086:                return false;
087:            }
088:
089:            /**
090:             * @see javax.faces.render.Renderer#getRendersChildren()
091:             */
092:            public boolean getRendersChildren() {
093:                return true;
094:            }
095:
096:            /**
097:             * Render the necessary bits that come before any actual <i>rows</i> in the table.
098:             * 
099:             * @see javax.faces.render.Renderer#encodeBegin(FacesContext, UIComponent)
100:             */
101:            public void encodeBegin(FacesContext facesContext,
102:                    UIComponent uiComponent) throws IOException {
103:                RendererUtils.checkParamValidity(facesContext, uiComponent,
104:                        UIData.class);
105:
106:                ResponseWriter writer = facesContext.getResponseWriter();
107:
108:                beforeTable(facesContext, (UIData) uiComponent);
109:
110:                HtmlRendererUtils.writePrettyLineSeparator(facesContext);
111:                writer.startElement(HTML.TABLE_ELEM, uiComponent);
112:                HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent,
113:                        facesContext);
114:                HtmlRendererUtils
115:                        .renderHTMLAttributes(
116:                                writer,
117:                                uiComponent,
118:                                org.apache.myfaces.shared_impl.renderkit.html.HTML.TABLE_PASSTHROUGH_ATTRIBUTES);
119:            }
120:
121:            /**
122:             * Render the TBODY section of the html table. See also method encodeInnerHtml.
123:             * 
124:             * @see javax.faces.render.Renderer#encodeChildren(FacesContext, UIComponent)
125:             */
126:            public void encodeChildren(FacesContext facesContext,
127:                    UIComponent component) throws IOException {
128:                RendererUtils.checkParamValidity(facesContext, component,
129:                        UIData.class);
130:
131:                ResponseWriter writer = facesContext.getResponseWriter();
132:
133:                beforeBody(facesContext, (UIData) component);
134:
135:                HtmlRendererUtils.writePrettyLineSeparator(facesContext);
136:                renderCaptionFacet(facesContext, writer, component);
137:                writer.startElement(HTML.TBODY_ELEM, component);
138:                writer.writeAttribute(HTML.ID_ATTR, component
139:                        .getClientId(facesContext)
140:                        + ":tbody_element", null);
141:
142:                encodeInnerHtml(facesContext, component);
143:
144:                writer.endElement(HTML.TBODY_ELEM);
145:
146:                afterBody(facesContext, (UIData) component);
147:            }
148:
149:            /**
150:             * Renders the caption facet.
151:             * @param facesContext the <code>FacesContext</code>.
152:             * @param writer the <code>ResponseWriter</code>.
153:             * @param component the parent <code>UIComponent</code> containing the facets.
154:             * @throws IOException if an exception occurs.
155:             */
156:            protected void renderCaptionFacet(FacesContext facesContext,
157:                    ResponseWriter writer, UIComponent component)
158:                    throws IOException {
159:                UIComponent facet = (UIComponent) component.getFacets().get(
160:                        CAPTION_FACET_NAME);
161:                if (facet != null) {
162:                    HtmlRendererUtils.writePrettyLineSeparator(facesContext);
163:                    writer.startElement(HTML.CAPTION_ELEM, component);
164:                    RendererUtils.renderChild(facesContext, facet);
165:                    writer.endElement(HTML.CAPTION_ELEM);
166:                }
167:            }
168:
169:            /**
170:             * Gets styles for the specified component.
171:             */
172:            protected static Styles getStyles(UIData uiData) {
173:                String rowClasses;
174:                String columnClasses;
175:                if (uiData instanceof  HtmlDataTable) {
176:                    rowClasses = ((HtmlDataTable) uiData).getRowClasses();
177:                    columnClasses = ((HtmlDataTable) uiData).getColumnClasses();
178:                } else {
179:                    rowClasses = (String) uiData.getAttributes().get(
180:                            JSFAttr.ROW_CLASSES_ATTR);
181:                    columnClasses = (String) uiData.getAttributes().get(
182:                            JSFAttr.COLUMN_CLASSES_ATTR);
183:                }
184:                return new Styles(rowClasses, columnClasses);
185:            }
186:
187:            /**
188:             * Class manages the styles from String lists.
189:             */
190:            protected static class Styles {
191:
192:                private String[] _columnStyle;
193:                private String[] _rowStyle;
194:
195:                Styles(String rowStyles, String columnStyles) {
196:                    _rowStyle = (rowStyles == null) ? ArrayUtils.EMPTY_STRING_ARRAY
197:                            : StringUtils.trim(StringUtils.splitShortString(
198:                                    rowStyles, ','));
199:                    _columnStyle = (columnStyles == null) ? ArrayUtils.EMPTY_STRING_ARRAY
200:                            : StringUtils.trim(StringUtils.splitShortString(
201:                                    columnStyles, ','));
202:                }
203:
204:                public String getRowStyle(int idx) {
205:                    if (!hasRowStyle()) {
206:                        return null;
207:                    }
208:                    return _rowStyle[idx % _rowStyle.length];
209:                }
210:
211:                public String getColumnStyle(int idx) {
212:                    if (!hasColumnStyle()) {
213:                        return null;
214:                    }
215:                    return _columnStyle[idx % _columnStyle.length];
216:                }
217:
218:                public boolean hasRowStyle() {
219:                    return _rowStyle.length > 0;
220:                }
221:
222:                public boolean hasColumnStyle() {
223:                    return _columnStyle.length > 0;
224:                }
225:            }
226:
227:            /**
228:             * Renders everything inside the TBODY tag by iterating over the row objects
229:             * between offsets first and first+rows and applying the UIColumn components
230:             * to those objects. 
231:             * <p>
232:             * This method is separated from the encodeChildren so that it can be overridden by
233:             * subclasses. One class that uses this functionality is autoUpdateDataTable.
234:             */
235:            public void encodeInnerHtml(FacesContext facesContext,
236:                    UIComponent component) throws IOException {
237:
238:                UIData uiData = (UIData) component;
239:                ResponseWriter writer = facesContext.getResponseWriter();
240:
241:                // begin the table
242:                // get the CSS styles
243:                Styles styles = getStyles(uiData);
244:
245:                int first = uiData.getFirst();
246:                int rows = uiData.getRows();
247:                int last;
248:                if (rows <= 0) {
249:                    last = uiData.getRowCount();
250:                } else {
251:                    last = first + rows;
252:                    if (last > uiData.getRowCount()) {
253:                        last = uiData.getRowCount();
254:                    }
255:                }
256:
257:                int newspaperColumns = getNewspaperColumns(component);
258:                int newspaperRows;
259:                if ((last - first) % newspaperColumns == 0)
260:                    newspaperRows = (last - first) / newspaperColumns;
261:                else
262:                    newspaperRows = ((last - first) / newspaperColumns) + 1;
263:                boolean newspaperHorizontalOrientation = isNewspaperHorizontalOrientation(component);
264:
265:                // walk through the newspaper rows
266:                for (int nr = 0; nr < newspaperRows; nr++) {
267:                    beforeRow(facesContext, uiData);
268:
269:                    // walk through the newspaper columns
270:                    for (int nc = 0; nc < newspaperColumns; nc++) {
271:
272:                        // the current row in the 'real' table
273:                        int currentRow;
274:                        if (newspaperHorizontalOrientation)
275:                            currentRow = nr * newspaperColumns + nc + first;
276:                        else
277:                            currentRow = nc * newspaperRows + nr + first;
278:
279:                        // if this row is not to be rendered
280:                        if (currentRow >= last)
281:                            continue;
282:
283:                        // bail if any row does not exist
284:                        uiData.setRowIndex(currentRow);
285:                        if (!uiData.isRowAvailable()) {
286:                            log.error("Row is not available. Rowindex = "
287:                                    + currentRow);
288:                            break;
289:                        }
290:
291:                        if (nc == 0) {
292:                            // first column in table, start new row
293:                            beforeRow(facesContext, uiData);
294:
295:                            HtmlRendererUtils
296:                                    .writePrettyLineSeparator(facesContext);
297:                            renderRowStart(facesContext, writer, uiData,
298:                                    styles, nr);
299:                        }
300:
301:                        List children = getChildren(component);
302:                        for (int j = 0, size = getChildCount(component); j < size; j++) {
303:                            UIComponent child = (UIComponent) children.get(j);
304:                            if (child.isRendered()) {
305:                                boolean columnRendering = child instanceof  UIColumn;
306:
307:                                if (columnRendering)
308:                                    beforeColumn(facesContext, uiData, j);
309:
310:                                encodeColumnChild(facesContext, writer, uiData,
311:                                        child, styles, nc
312:                                                * uiData.getChildCount() + j);
313:
314:                                if (columnRendering)
315:                                    afterColumn(facesContext, uiData, j);
316:                            }
317:                        }
318:
319:                        if (hasNewspaperTableSpacer(uiData)) {
320:                            // draw the spacer facet
321:                            if (nc < newspaperColumns - 1)
322:                                renderSpacerCell(facesContext, writer, uiData);
323:                        }
324:                    }
325:                    renderRowEnd(facesContext, writer, uiData);
326:
327:                    afterRow(facesContext, uiData);
328:                }
329:            }
330:
331:            protected void encodeColumnChild(FacesContext facesContext,
332:                    ResponseWriter writer, UIData uiData,
333:                    UIComponent component, Styles styles, int columnStyleIndex)
334:                    throws IOException {
335:                if (component instanceof  UIColumn) {
336:                    renderColumnBody(facesContext, writer, uiData, component,
337:                            styles, columnStyleIndex);
338:                }
339:            }
340:
341:            /**
342:             * Renders the body of a given <code>UIColumn</code> (everything but
343:             * the header and footer facets). This emits a TD cell, whose contents
344:             * are the result of calling encodeBegin, encodeChildren and
345:             * encodeEnd methods on the component (or its associated renderer).
346:             * 
347:             * @param facesContext the <code>FacesContext</code>.
348:             * @param writer the <code>ResponseWriter</code>.
349:             * @param uiData the <code>UIData</code> being rendered.
350:             * @param component the <code>UIComponent</code> to render.
351:             * @throws IOException if an exception occurs.
352:             */
353:            protected void renderColumnBody(FacesContext facesContext,
354:                    ResponseWriter writer, UIData uiData,
355:                    UIComponent component, Styles styles, int columnStyleIndex)
356:                    throws IOException {
357:                writer.startElement(HTML.TD_ELEM, uiData);
358:                if (styles.hasColumnStyle()) {
359:                    writer.writeAttribute(HTML.CLASS_ATTR, styles
360:                            .getColumnStyle(columnStyleIndex), null);
361:                }
362:
363:                RendererUtils.renderChild(facesContext, component);
364:                writer.endElement(HTML.TD_ELEM);
365:            }
366:
367:            /**
368:             * Renders the start of a new row of body content.
369:             * @param facesContext the <code>FacesContext</code>.
370:             * @param writer the <code>ResponseWriter</code>.
371:             * @param uiData the <code>UIData</code> being rendered.
372:             * @throws IOException if an exceptoin occurs.
373:             */
374:            protected void renderRowStart(FacesContext facesContext,
375:                    ResponseWriter writer, UIData uiData, Styles styles,
376:                    int rowStyleIndex) throws IOException {
377:                writer.startElement(HTML.TR_ELEM, uiData);
378:
379:                renderRowStyle(facesContext, writer, uiData, styles,
380:                        rowStyleIndex);
381:
382:                Object rowId = uiData
383:                        .getAttributes()
384:                        .get(
385:                                org.apache.myfaces.shared_impl.renderkit.JSFAttr.ROW_ID);
386:
387:                if (rowId != null) {
388:                    writer.writeAttribute(HTML.ID_ATTR, rowId.toString(), null);
389:                }
390:            }
391:
392:            protected void renderRowStyle(FacesContext facesContext,
393:                    ResponseWriter writer, UIData uiData, Styles styles,
394:                    int rowStyleIndex) throws IOException {
395:                if (styles.hasRowStyle()) {
396:                    String rowStyle = styles.getRowStyle(rowStyleIndex);
397:                    writer.writeAttribute(HTML.CLASS_ATTR, rowStyle, null);
398:                }
399:            }
400:
401:            /**
402:             * Renders the end of a row of body content.
403:             * @param facesContext the <code>FacesContext</code>.
404:             * @param writer the <code>ResponseWriter</code>.
405:             * @param uiData the <code>UIData</code> being rendered.
406:             * @throws IOException if an exceptoin occurs.
407:             */
408:            protected void renderRowEnd(FacesContext facesContext,
409:                    ResponseWriter writer, UIData uiData) throws IOException {
410:                writer.endElement(HTML.TR_ELEM);
411:            }
412:
413:            /**
414:             * Perform any operations necessary immediately before the TABLE start tag
415:             * is output.
416:             *
417:             * @param facesContext the <code>FacesContext</code>.
418:             * @param uiData the <code>UIData</code> being rendered.
419:             */
420:            protected void beforeTable(FacesContext facesContext, UIData uiData)
421:                    throws IOException {
422:            }
423:
424:            /**
425:             * Perform any operations necessary after TABLE start tag is output
426:             * but before the TBODY start tag.
427:             * <p>
428:             * This method generates the THEAD/TFOOT sections of a table if there
429:             * are any header or footer facets defined on the table or on any child
430:             * UIColumn component.
431:             *
432:             * @param facesContext the <code>FacesContext</code>.
433:             * @param uiData the <code>UIData</code> being rendered.
434:             */
435:            protected void beforeBody(FacesContext facesContext, UIData uiData)
436:                    throws IOException {
437:                ResponseWriter writer = facesContext.getResponseWriter();
438:
439:                HtmlRendererUtils.renderTableCaption(facesContext, writer,
440:                        uiData);
441:                renderFacet(facesContext, writer, uiData, true);
442:                renderFacet(facesContext, writer, uiData, false);
443:            }
444:
445:            /**
446:             * Perform any operations necessary immediately before each TR start tag
447:             * is output.
448:             *
449:             * @param facesContext the <code>FacesContext</code>.
450:             * @param uiData the <code>UIData</code> being rendered.
451:             */
452:            protected void beforeRow(FacesContext facesContext, UIData uiData)
453:                    throws IOException {
454:            }
455:
456:            /**
457:             * Perform any operations necessary immediately after each TR end tag
458:             * is output.
459:             *
460:             * @param facesContext the <code>FacesContext</code>.
461:             * @param uiData the <code>UIData</code> being rendered.
462:             */
463:            protected void afterRow(FacesContext facesContext, UIData uiData)
464:                    throws IOException {
465:            }
466:
467:            /**
468:             * Perform any operations necessary immediately before each column child is rendered
469:             *
470:             * @param facesContext the <code>FacesContext</code>.
471:             * @param uiData the <code>UIData</code> being rendered.
472:             * @param columnIndex the index of the currenly rendered column
473:             */
474:            protected void beforeColumn(FacesContext facesContext,
475:                    UIData uiData, int columnIndex) throws IOException {
476:            }
477:
478:            /**
479:             * Perform any operations necessary immediately after each column child is rendered
480:             *
481:             * @param facesContext the <code>FacesContext</code>.
482:             * @param uiData the <code>UIData</code> being rendered.
483:             * @param columnIndex the index of the currenly rendered column
484:             */
485:            protected void afterColumn(FacesContext facesContext,
486:                    UIData uiData, int columnIndex) throws IOException {
487:            }
488:
489:            /**
490:             *Perform any operations necessary immediately before each column child's header or footer is rendered
491:             *
492:             * @param facesContext the <code>FacesContext</code>.
493:             * @param uiData the <code>UIData</code> being rendered.
494:             * @param header true if the header of the column child is rendered
495:             * @param columnIndex the index of the currenly rendered column
496:             */
497:            protected void beforeColumnHeaderOrFooter(
498:                    FacesContext facesContext, UIData uiData, boolean header,
499:                    int columnIndex) throws IOException {
500:            }
501:
502:            /**
503:             * Perform any operations necessary immediately after each column child's header of footer is rendered
504:             *
505:             * @param facesContext the <code>FacesContext</code>.
506:             * @param uiData the <code>UIData</code> being rendered.
507:             * @param header true if the header of the column child is rendered
508:             * @param columnIndex the index of the currenly rendered column
509:             */
510:            protected void afterColumnHeaderOrFooter(FacesContext facesContext,
511:                    UIData uiData, boolean header, int columnIndex)
512:                    throws IOException {
513:            }
514:
515:            /**
516:             * Perform any operations necessary in the TBODY start tag.
517:             *
518:             * @param facesContext the <code>FacesContext</code>.
519:             * @param uiData the <code>UIData</code> being rendered.
520:             */
521:            protected void inBodyStart(FacesContext facesContext, UIData uiData)
522:                    throws IOException {
523:            }
524:
525:            /**
526:             * Perform any operations necessary immediately after the TBODY end tag
527:             * is output.
528:             *
529:             * @param facesContext the <code>FacesContext</code>.
530:             * @param uiData the <code>UIData</code> being rendered.
531:             */
532:            protected void afterBody(FacesContext facesContext, UIData uiData)
533:                    throws IOException {
534:            }
535:
536:            /**
537:             * Perform any operations necessary immediately after the TABLE end tag
538:             * is output.
539:             *
540:             * @param facesContext the <code>FacesContext</code>.
541:             * @param uiData the <code>UIData</code> being rendered.
542:             */
543:            protected void afterTable(FacesContext facesContext, UIData uiData)
544:                    throws IOException {
545:            }
546:
547:            /**
548:             * @see javax.faces.render.Renderer#encodeEnd(FacesContext, UIComponent)
549:             */
550:            public void encodeEnd(FacesContext facesContext,
551:                    UIComponent uiComponent) throws IOException {
552:                RendererUtils.checkParamValidity(facesContext, uiComponent,
553:                        UIData.class);
554:
555:                ResponseWriter writer = facesContext.getResponseWriter();
556:                writer.endElement(HTML.TABLE_ELEM);
557:                HtmlRendererUtils.writePrettyLineSeparator(facesContext);
558:
559:                afterTable(facesContext, (UIData) uiComponent);
560:            }
561:
562:            /**
563:             * Renders either the header or the footer facets for the UIData component
564:             * and all the child UIColumn components, as a THEAD or TFOOT element
565:             * containing TR (row) elements.
566:             * <p>
567:             * If there is a header or footer attached to the UIData then that is
568:             * rendered as a TR element whose COLSPAN is the sum of all rendered
569:             * columns in the table. This allows that header/footer to take up the
570:             * entire width of the table.
571:             * <p>
572:             * If any child column has a header or footer then a TR is rendered
573:             * with a TH cell for each column child. 
574:             * 
575:             * @param facesContext the <code>FacesContext</code>.
576:             * @param writer the <code>ResponseWriter</code>.
577:             * @param component the UIData component
578:             * @param header whether this is the header facet (if not, then the footer facet).
579:             * @throws IOException if an exception occurs.
580:             */
581:            protected void renderFacet(FacesContext facesContext,
582:                    ResponseWriter writer, UIComponent component, boolean header)
583:                    throws IOException {
584:                int colspan = 0;
585:                boolean hasColumnFacet = false;
586:                for (Iterator it = getChildren(component).iterator(); it
587:                        .hasNext();) {
588:                    UIComponent uiComponent = (UIComponent) it.next();
589:                    if (uiComponent.isRendered()) {
590:                        // a UIColumn has a span of 1, anything else has a span of 0
591:                        colspan += determineChildColSpan(uiComponent);
592:
593:                        // hasColumnFacet is true if *any* child column has a facet of
594:                        // the specified type.
595:                        if (!hasColumnFacet) {
596:                            hasColumnFacet = hasFacet(header, uiComponent);
597:                        }
598:                    }
599:                }
600:
601:                UIComponent facet = header ? (UIComponent) component
602:                        .getFacets().get(HEADER_FACET_NAME)
603:                        : (UIComponent) component.getFacets().get(
604:                                FOOTER_FACET_NAME);
605:                if (facet != null || hasColumnFacet) {
606:                    // Header or Footer present on either the UIData or a column, so we
607:                    // definitely need to render the THEAD or TFOOT section.
608:                    String elemName = header ? HTML.THEAD_ELEM
609:                            : HTML.TFOOT_ELEM;
610:
611:                    HtmlRendererUtils.writePrettyLineSeparator(facesContext);
612:                    writer.startElement(elemName, component);
613:                    if (header) {
614:                        String headerStyleClass = getHeaderClass(component);
615:                        if (facet != null)
616:                            renderTableHeaderRow(facesContext, writer,
617:                                    component, facet, headerStyleClass, colspan);
618:                        if (hasColumnFacet)
619:                            renderColumnHeaderRow(facesContext, writer,
620:                                    component, headerStyleClass);
621:                    } else {
622:                        String footerStyleClass = getFooterClass(component);
623:                        if (hasColumnFacet)
624:                            renderColumnFooterRow(facesContext, writer,
625:                                    component, footerStyleClass);
626:                        if (facet != null)
627:                            renderTableFooterRow(facesContext, writer,
628:                                    component, facet, footerStyleClass, colspan);
629:                    }
630:                    writer.endElement(elemName);
631:                }
632:            }
633:
634:            /**
635:             * @param header
636:             * @param uiComponent
637:             * @return boolean
638:             */
639:            protected boolean hasFacet(boolean header, UIComponent uiComponent) {
640:                if (uiComponent instanceof  UIColumn) {
641:                    UIColumn uiColumn = (UIColumn) uiComponent;
642:                    return header ? uiColumn.getHeader() != null : uiColumn
643:                            .getFooter() != null;
644:                }
645:                return false;
646:            }
647:
648:            /**
649:             * Calculate the number of columns the specified child component will span
650:             * when rendered.
651:             * <p>
652:             * Normally, this is a fairly simple calculation: a UIColumn component
653:             * is rendered as one column, every other child type is not rendered
654:             * (ie spans zero columns). However custom subclasses of this renderer may
655:             * override this method to handle cases where a single component renders
656:             * as multiple columns. 
657:             */
658:            protected int determineChildColSpan(UIComponent uiComponent) {
659:                if (uiComponent instanceof  UIColumn) {
660:                    return 1;
661:                }
662:                return 0;
663:            }
664:
665:            /**
666:             * Renders the header row of the table being rendered.
667:             * @param facesContext the <code>FacesContext</code>.
668:             * @param writer the <code>ResponseWriter</code>.
669:             * @param component the <code>UIComponent</code> for whom a table is being rendered.
670:             * @param headerFacet the facet for the header.
671:             * @param headerStyleClass the styleClass of the header.
672:             * @param colspan the number of columns the header should span.  Typically, this is
673:             * the number of columns in the table.
674:             * @throws IOException if an exception occurs.
675:             */
676:            protected void renderTableHeaderRow(FacesContext facesContext,
677:                    ResponseWriter writer, UIComponent component,
678:                    UIComponent headerFacet, String headerStyleClass,
679:                    int colspan) throws IOException {
680:                renderTableHeaderOrFooterRow(facesContext, writer, component,
681:                        headerFacet, headerStyleClass, HTML.TH_ELEM, colspan,
682:                        true);
683:            }
684:
685:            /**
686:             * Renders the footer row of the table being rendered.
687:             * @param facesContext the <code>FacesContext</code>.
688:             * @param writer the <code>ResponseWriter</code>.
689:             * @param component the <code>UIComponent</code> for whom a table is being rendered.
690:             * @param footerFacet the facet for the footer.
691:             * @param footerStyleClass the styleClass of the footer.
692:             * @param colspan the number of columns the header should span.  Typically, this is
693:             * the number of columns in the table.
694:             * @throws IOException if an exception occurs.
695:             */
696:            protected void renderTableFooterRow(FacesContext facesContext,
697:                    ResponseWriter writer, UIComponent component,
698:                    UIComponent footerFacet, String footerStyleClass,
699:                    int colspan) throws IOException {
700:                renderTableHeaderOrFooterRow(facesContext, writer, component,
701:                        footerFacet, footerStyleClass, HTML.TD_ELEM, colspan,
702:                        false);
703:            }
704:
705:            /**
706:             * Renders the header row for the columns, which is a separate row from the header row for the
707:             * <code>UIData</code> header facet.
708:             * 
709:             * @param facesContext the <code>FacesContext</code>.
710:             * @param writer the <code>ResponseWriter</code>.
711:             * @param component the UIData component for whom a table is being rendered.
712:             * @param headerStyleClass the styleClass of the header
713:             * @throws IOException if an exception occurs.
714:             */
715:            protected void renderColumnHeaderRow(FacesContext facesContext,
716:                    ResponseWriter writer, UIComponent component,
717:                    String headerStyleClass) throws IOException {
718:                renderColumnHeaderOrFooterRow(facesContext, writer, component,
719:                        headerStyleClass, true);
720:            }
721:
722:            /**
723:             * Renders the footer row for the columns, which is a separate row from the footer row for the
724:             * <code>UIData</code> footer facet.
725:             * @param facesContext the <code>FacesContext</code>.
726:             * @param writer the <code>ResponseWriter</code>.
727:             * @param component the <code>UIComponent</code> for whom a table is being rendered.
728:             * @param footerStyleClass the styleClass of the footerStyleClass
729:             * @throws IOException if an exception occurs.
730:             */
731:            protected void renderColumnFooterRow(FacesContext facesContext,
732:                    ResponseWriter writer, UIComponent component,
733:                    String footerStyleClass) throws IOException {
734:                renderColumnHeaderOrFooterRow(facesContext, writer, component,
735:                        footerStyleClass, false);
736:            }
737:
738:            private void renderTableHeaderOrFooterRow(
739:                    FacesContext facesContext, ResponseWriter writer,
740:                    UIComponent component, UIComponent facet,
741:                    String styleClass, String colElementName, int colspan,
742:                    boolean isHeader) throws IOException {
743:                HtmlRendererUtils.writePrettyLineSeparator(facesContext);
744:                writer.startElement(HTML.TR_ELEM, component);
745:                writer.startElement(colElementName, component);
746:                if (colElementName.equals(HTML.TH_ELEM) && isHeader) {
747:                    writer.writeAttribute(HTML.SCOPE_ATTR,
748:                            HTML.SCOPE_COLGROUP_VALUE, null);
749:                }
750:
751:                // span all the table's columns
752:                int newsPaperColumns = getNewspaperColumns(component);
753:                int totalColumns = colspan * newsPaperColumns;
754:                if (hasNewspaperTableSpacer(component)) {
755:                    totalColumns = totalColumns + newsPaperColumns - 1;
756:                }
757:                writer.writeAttribute(HTML.COLSPAN_ATTR, new Integer(
758:                        totalColumns), null);
759:                if (styleClass != null) {
760:                    writer.writeAttribute(HTML.CLASS_ATTR, styleClass, null);
761:                }
762:                if (facet != null) {
763:                    RendererUtils.renderChild(facesContext, facet);
764:                }
765:                writer.endElement(colElementName);
766:                writer.endElement(HTML.TR_ELEM);
767:            }
768:
769:            /**
770:             * @param component the UIData component for whom a table is being rendered.
771:             */
772:            private void renderColumnHeaderOrFooterRow(
773:                    FacesContext facesContext, ResponseWriter writer,
774:                    UIComponent component, String styleClass, boolean header)
775:                    throws IOException {
776:                HtmlRendererUtils.writePrettyLineSeparator(facesContext);
777:
778:                writer.startElement(HTML.TR_ELEM, component);
779:                int columnIndex = 0;
780:                int newspaperColumns = getNewspaperColumns(component);
781:                for (int nc = 0; nc < newspaperColumns; nc++) {
782:                    for (Iterator it = getChildren(component).iterator(); it
783:                            .hasNext();) {
784:                        UIComponent uiComponent = (UIComponent) it.next();
785:                        if (uiComponent.isRendered()) {
786:                            if (component instanceof  UIData
787:                                    && uiComponent instanceof  UIColumn)
788:                                beforeColumnHeaderOrFooter(facesContext,
789:                                        (UIData) component, header, columnIndex);
790:
791:                            renderColumnChildHeaderOrFooterRow(facesContext,
792:                                    writer, uiComponent, styleClass, header);
793:
794:                            if (component instanceof  UIData
795:                                    && uiComponent instanceof  UIColumn)
796:                                afterColumnHeaderOrFooter(facesContext,
797:                                        (UIData) component, header, columnIndex);
798:                        }
799:                        columnIndex += 1;
800:                    }
801:
802:                    if (hasNewspaperTableSpacer(component)) {
803:                        // draw the spacer facet
804:                        if (nc < newspaperColumns - 1)
805:                            renderSpacerCell(facesContext, writer, component);
806:                    }
807:                }
808:                writer.endElement(HTML.TR_ELEM);
809:            }
810:
811:            /**
812:             * Renders a spacer between adjacent newspaper columns.
813:             */
814:            protected void renderSpacerCell(FacesContext facesContext,
815:                    ResponseWriter writer, UIComponent component)
816:                    throws IOException {
817:                UIComponent spacer = getNewspaperTableSpacer(component);
818:                if (spacer == null)
819:                    return;
820:
821:                writer.startElement(HTML.TD_ELEM, component);
822:                RendererUtils.renderChild(facesContext, spacer);
823:                writer.endElement(HTML.TD_ELEM);
824:            }
825:
826:            protected void renderColumnChildHeaderOrFooterRow(
827:                    FacesContext facesContext, ResponseWriter writer,
828:                    UIComponent uiComponent, String styleClass, boolean isHeader)
829:                    throws IOException {
830:                if (uiComponent instanceof  UIColumn) {
831:                    // allow column to override style class, new in JSF 1.2
832:                    if (uiComponent instanceof  HtmlColumn) {
833:                        HtmlColumn column = (HtmlColumn) uiComponent;
834:                        if (isHeader && column.getHeaderClass() != null)
835:                            styleClass = column.getHeaderClass();
836:                        else if (!isHeader && column.getFooterClass() != null)
837:                            styleClass = column.getFooterClass();
838:                    }
839:
840:                    if (isHeader) {
841:                        renderColumnHeaderCell(facesContext, writer,
842:                                uiComponent, ((UIColumn) uiComponent)
843:                                        .getHeader(), styleClass, 0);
844:                    } else {
845:                        renderColumnFooterCell(facesContext, writer,
846:                                uiComponent, ((UIColumn) uiComponent)
847:                                        .getFooter(), styleClass, 0);
848:                    }
849:                }
850:            }
851:
852:            /**
853:             * Renders the header facet for the given <code>UIColumn</code>.
854:             * @param facesContext the <code>FacesContext</code>.
855:             * @param writer the <code>ResponseWriter</code>.
856:             * @param uiColumn the <code>UIColumn</code>.
857:             * @param headerStyleClass the styleClass of the header facet.
858:             * @param colspan the colspan for the tableData element in which the header facet
859:             * will be wrapped.
860:             * @throws IOException
861:             */
862:            protected void renderColumnHeaderCell(FacesContext facesContext,
863:                    ResponseWriter writer, UIColumn uiColumn,
864:                    String headerStyleClass, int colspan) throws IOException {
865:                renderColumnHeaderCell(facesContext, writer, uiColumn, uiColumn
866:                        .getHeader(), headerStyleClass, colspan);
867:            }
868:
869:            /**
870:             * Renders a TH cell within a TR within a THEAD section. If the specified
871:             * UIColumn object does have a header facet, then that facet is rendered
872:             * within the cell, otherwise the cell is left blank (though any specified
873:             * style class is still applied to empty cells).
874:             * 
875:             * @param facesContext the <code>FacesContext</code>.
876:             * @param writer the <code>ResponseWriter</code>.
877:             * @param uiComponent the <code>UIComponent</code> to render the facet for.
878:             * @param facet the <code>UIComponent</code> to render as facet.
879:             * @param headerStyleClass the styleClass of the header facet.
880:             * @param colspan the colspan for the tableData element in which the header facet
881:             * will be wrapped.
882:             * @throws IOException
883:             */
884:            protected void renderColumnHeaderCell(FacesContext facesContext,
885:                    ResponseWriter writer, UIComponent uiComponent,
886:                    UIComponent facet, String headerStyleClass, int colspan)
887:                    throws IOException {
888:                writer.startElement(HTML.TH_ELEM, uiComponent);
889:                if (colspan > 1) {
890:                    writer.writeAttribute(HTML.COLSPAN_ATTR, new Integer(
891:                            colspan), null);
892:                }
893:                if (headerStyleClass != null) {
894:                    writer.writeAttribute(HTML.CLASS_ATTR, headerStyleClass,
895:                            null);
896:                }
897:
898:                writer.writeAttribute(HTML.SCOPE_ATTR, "col", null);
899:
900:                if (facet != null) {
901:                    RendererUtils.renderChild(facesContext, facet);
902:                }
903:
904:                writer.endElement(HTML.TH_ELEM);
905:            }
906:
907:            /**
908:             * Renders the footer facet for the given <code>UIColumn</code>.
909:             * @param facesContext the <code>FacesContext</code>.
910:             * @param writer the <code>ResponseWriter</code>.
911:             * @param uiColumn the <code>UIComponent</code>.
912:             * @param footerStyleClass the styleClass of the footer facet.
913:             * @param colspan the colspan for the tableData element in which the footer facet
914:             * will be wrapped.
915:             * @throws IOException
916:             */
917:            protected void renderColumnFooterCell(FacesContext facesContext,
918:                    ResponseWriter writer, UIColumn uiColumn,
919:                    String footerStyleClass, int colspan) throws IOException {
920:                renderColumnFooterCell(facesContext, writer, uiColumn, uiColumn
921:                        .getFooter(), footerStyleClass, colspan);
922:            }
923:
924:            /**
925:             * Renders the footer facet for the given <code>UIColumn</code>.
926:             * @param facesContext the <code>FacesContext</code>.
927:             * @param writer the <code>ResponseWriter</code>.
928:             * @param uiComponent the <code>UIComponent</code> to render the facet for.
929:             * @param facet the <code>UIComponent</code> to render as facet.
930:             * @param footerStyleClass the styleClass of the footer facet.
931:             * @param colspan the colspan for the tableData element in which the footer facet
932:             * will be wrapped.
933:             * @throws IOException
934:             */
935:            protected void renderColumnFooterCell(FacesContext facesContext,
936:                    ResponseWriter writer, UIComponent uiComponent,
937:                    UIComponent facet, String footerStyleClass, int colspan)
938:                    throws IOException {
939:                writer.startElement(HTML.TD_ELEM, uiComponent);
940:                if (colspan > 1) {
941:                    writer.writeAttribute(HTML.COLSPAN_ATTR, new Integer(
942:                            colspan), null);
943:                }
944:                if (footerStyleClass != null) {
945:                    writer.writeAttribute(HTML.CLASS_ATTR, footerStyleClass,
946:                            null);
947:                }
948:                if (facet != null) {
949:                    RendererUtils.renderChild(facesContext, facet);
950:                }
951:                writer.endElement(HTML.TD_ELEM);
952:            }
953:
954:            /**
955:             * Gets the headerClass attribute of the given <code>UIComponent</code>.
956:             * @param component the <code>UIComponent</code>.
957:             * @return the headerClass attribute of the given <code>UIComponent</code>.
958:             */
959:            protected static String getHeaderClass(UIComponent component) {
960:                if (component instanceof  HtmlDataTable) {
961:                    return ((HtmlDataTable) component).getHeaderClass();
962:                } else {
963:                    return (String) component
964:                            .getAttributes()
965:                            .get(
966:                                    org.apache.myfaces.shared_impl.renderkit.JSFAttr.HEADER_CLASS_ATTR);
967:                }
968:            }
969:
970:            /**
971:             * Gets the footerClass attribute of the given <code>UIComponent</code>.
972:             * @param component the <code>UIComponent</code>.
973:             * @return the footerClass attribute of the given <code>UIComponent</code>.
974:             */
975:            protected static String getFooterClass(UIComponent component) {
976:                if (component instanceof  HtmlDataTable) {
977:                    return ((HtmlDataTable) component).getFooterClass();
978:                } else {
979:                    return (String) component
980:                            .getAttributes()
981:                            .get(
982:                                    org.apache.myfaces.shared_impl.renderkit.JSFAttr.FOOTER_CLASS_ATTR);
983:                }
984:            }
985:
986:            public void decode(FacesContext context, UIComponent component) {
987:                super.decode(context, component);
988:            }
989:
990:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.