You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2010/06/17 04:01:40 UTC
svn commit: r955454 - in
/myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/newspaper:
./ HtmlNewspaperTableRenderer.java
Author: lu4242
Date: Thu Jun 17 02:01:40 2010
New Revision: 955454
URL: http://svn.apache.org/viewvc?rev=955454&view=rev
Log:
TOMAHAWK-1474 Behavior support for components that contains event aware properties in jsf 2.0 module
Added:
myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/newspaper/
myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/newspaper/HtmlNewspaperTableRenderer.java
Added: myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/newspaper/HtmlNewspaperTableRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/newspaper/HtmlNewspaperTableRenderer.java?rev=955454&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/newspaper/HtmlNewspaperTableRenderer.java (added)
+++ myfaces/tomahawk/trunk/core20/src/main/java/org/apache/myfaces/custom/newspaper/HtmlNewspaperTableRenderer.java Thu Jun 17 02:01:40 2010
@@ -0,0 +1,425 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.custom.newspaper;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorHolder;
+import javax.faces.component.html.HtmlDataTable;
+import javax.faces.context.ResponseWriter;
+import javax.faces.component.UIColumn;
+import javax.faces.component.UIData;
+import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
+import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.util.ResourceUtils;
+import org.apache.myfaces.shared_tomahawk.util.ArrayUtils;
+import org.apache.myfaces.shared_tomahawk.util.StringUtils;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Renderer for a table in multiple balanced columns.
+ *
+ * @JSFRenderer
+ * renderKitId = "HTML_BASIC"
+ * family = "javax.faces.Data"
+ * type = "org.apache.myfaces.HtmlNewspaperTable"
+ *
+ * @author <a href="mailto:jesse@odel.on.ca">Jesse Wilson</a>
+ */
+public class HtmlNewspaperTableRenderer
+ extends HtmlTableRendererBase
+{
+ private static final Log log = LogFactory.getLog(HtmlNewspaperTableRenderer.class);
+
+ public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException {
+ RendererUtils.checkParamValidity(facesContext, uiComponent, UIData.class);
+ ResponseWriter writer = facesContext.getResponseWriter();
+ HtmlNewspaperTable newspaperTable = (HtmlNewspaperTable)uiComponent;
+
+ Map<String, List<ClientBehavior>> behaviors = null;
+ if (uiComponent instanceof ClientBehaviorHolder)
+ {
+ behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
+ if (!behaviors.isEmpty())
+ {
+ ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, facesContext.getResponseWriter());
+ }
+ }
+
+ // write out the table start tag
+ HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+ writer.startElement(HTML.TABLE_ELEM, newspaperTable);
+ writer.writeAttribute(HTML.ID_ATTR, newspaperTable.getClientId(facesContext), null);
+
+ if (behaviors != null && !behaviors.isEmpty())
+ {
+ HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, newspaperTable, behaviors);
+ HtmlRendererUtils.renderHTMLAttributes(writer, newspaperTable, HTML.TABLE_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS);
+
+ }
+ else
+ {
+ HtmlRendererUtils.renderHTMLAttributes(writer, newspaperTable, HTML.TABLE_PASSTHROUGH_ATTRIBUTES);
+ }
+
+ // render the header
+ renderFacet(facesContext, writer, newspaperTable, true);
+ }
+
+ public void encodeChildren(FacesContext facesContext, UIComponent uiComponent) throws IOException {
+ RendererUtils.checkParamValidity(facesContext, uiComponent, UIData.class);
+ ResponseWriter writer = facesContext.getResponseWriter();
+ HtmlNewspaperTable newspaperTable = (HtmlNewspaperTable)uiComponent;
+
+ // begin the table
+ HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+ writer.startElement(HTML.TBODY_ELEM, newspaperTable);
+
+ // get the CSS styles
+ Styles styles = getStyles(newspaperTable);
+
+ // count the number of actual rows
+ int first = newspaperTable.getFirst();
+ int rows = newspaperTable.getRows();
+ int rowCount = newspaperTable.getRowCount();
+ if(rows <= 0) {
+ rows = rowCount - first;
+ }
+ int last = first + rows;
+ if(last > rowCount) last = rowCount;
+
+ // the number of slices to break the table up into */
+ int newspaperColumns = newspaperTable.getNewspaperColumns();
+ int newspaperRows;
+ if((last - first) % newspaperColumns == 0) newspaperRows = (last - first) / newspaperColumns;
+ else newspaperRows = ((last - first) / newspaperColumns) + 1;
+
+ // walk through the newspaper rows
+ for(int nr = 0; nr < newspaperRows; nr++) {
+
+ // write the row start
+ HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+ writer.startElement(HTML.TR_ELEM, newspaperTable);
+ if(styles.hasRowStyle()) {
+ String rowStyle = styles.getRowStyle(nr);
+ writer.writeAttribute(HTML.CLASS_ATTR, rowStyle, null);
+ }
+
+ // walk through the newspaper columns
+ for(int nc = 0; nc < newspaperColumns; nc++) {
+
+ // the current row in the 'real' table
+ int currentRow = nc * newspaperRows + nr + first;
+
+ // if this row is not to be rendered
+ if(currentRow >= last) continue;
+
+ // bail if any row does not exist
+ newspaperTable.setRowIndex(currentRow);
+ if(!newspaperTable.isRowAvailable()) {
+ log.error("Row is not available. Rowindex = " + currentRow);
+ return;
+ }
+
+ // write each cell
+ List children = newspaperTable.getChildren();
+ for(int j = 0; j < newspaperTable.getChildCount(); j++) {
+ // skip this child if its not a rendered column
+ UIComponent child = (UIComponent)children.get(j);
+ if(!(child instanceof UIColumn)) continue;
+ if(!child.isRendered()) continue;
+ // draw the element's cell
+ writer.startElement(HTML.TD_ELEM, newspaperTable);
+ if(styles.hasColumnStyle()) writer.writeAttribute(HTML.CLASS_ATTR, styles.getColumnStyle(nc * newspaperTable.getChildCount() + j), null);
+ RendererUtils.renderChild(facesContext, child);
+ writer.endElement(HTML.TD_ELEM);
+ }
+
+ // draw the spacer facet
+ if(nc < newspaperColumns - 1) renderSpacerCell(facesContext, writer, newspaperTable);
+ }
+ // write the row end
+ writer.endElement(HTML.TR_ELEM);
+ }
+
+ // write the end of the table's body
+ writer.endElement(HTML.TBODY_ELEM);
+ }
+
+ /**
+ * Fetch the number of columns to divide the table into.
+ */
+ private int getNewspaperColumns() {
+ return 3;
+ }
+
+ public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException {
+ RendererUtils.checkParamValidity(facesContext, uiComponent, UIData.class);
+ ResponseWriter writer = facesContext.getResponseWriter();
+ HtmlNewspaperTable newspaperTable = (HtmlNewspaperTable)uiComponent;
+
+ // render the footer
+ renderFacet(facesContext, writer, newspaperTable, false);
+
+ // write out the table end tag
+ writer.endElement(HTML.TABLE_ELEM);
+ HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+ }
+
+
+ /**
+ * Count the number of columns in the speicifed Newspaper table..
+ */
+ private int countColumns(HtmlNewspaperTable newspaperTable) {
+ int columnCount = 0;
+ for(Iterator it = newspaperTable.getChildren().iterator(); it.hasNext(); ) {
+ UIComponent uiComponent = (UIComponent)it.next();
+ if (uiComponent instanceof UIColumn && ((UIColumn)uiComponent).isRendered()) {
+ columnCount++;
+ }
+ }
+ return columnCount;
+ }
+
+ /**
+ * Tests if the specified facet exists for the specified newspaper table.
+ */
+ private boolean hasFacet(HtmlNewspaperTable newspaperTable, boolean header) {
+ for(Iterator it = newspaperTable.getChildren().iterator(); it.hasNext(); ) {
+ // get the column
+ UIComponent uiComponent = (UIComponent)it.next();
+ if(!(uiComponent instanceof UIColumn)) continue;
+ UIColumn column = (UIColumn)uiComponent;
+ if(!column.isRendered()) continue;
+
+ // test the facet
+ if(header && ((UIColumn)uiComponent).getHeader() != null) return true;
+ if(!header && ((UIColumn)uiComponent).getFooter() != null) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Render table headers and footers.
+ */
+ private void renderFacet(FacesContext facesContext, ResponseWriter writer, HtmlNewspaperTable newspaperTable, boolean header) throws IOException {
+ int columnCount = countColumns(newspaperTable);
+ boolean hasColumnFacet = hasFacet(newspaperTable, header);
+ UIComponent facet = header ? newspaperTable.getHeader() : newspaperTable.getFooter();
+
+ // quit if there's nothing to draw
+ if(facet == null && !hasColumnFacet) return;
+
+ // start the row block
+ HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+ String elemName = header ? HTML.THEAD_ELEM : HTML.TFOOT_ELEM;
+ writer.startElement(elemName, newspaperTable);
+
+ // fetch the style
+ String styleClass;
+ if(header) styleClass = getHeaderClass(newspaperTable);
+ else styleClass = getFooterClass(newspaperTable);
+
+ // write the header row and column headers
+ if(header) {
+ if (facet != null) renderTableHeaderOrFooterRow(facesContext, writer, newspaperTable, facet, styleClass, HTML.TD_ELEM, columnCount);
+ if (hasColumnFacet) renderColumnHeaderOrFooterRow(facesContext, writer, newspaperTable, styleClass, header);
+ // write the footer row and column footers
+ } else {
+ if (hasColumnFacet) renderColumnHeaderOrFooterRow(facesContext, writer, newspaperTable, styleClass, header);
+ if (facet != null) renderTableHeaderOrFooterRow(facesContext, writer, newspaperTable, facet, styleClass, HTML.TD_ELEM, columnCount);
+ }
+
+ // end the row block
+ writer.endElement(elemName);
+ }
+
+ /**
+ * Renders the table header or footer row. This is one giant cell that spans
+ * the entire table header or footer.
+ */
+ private void renderTableHeaderOrFooterRow(FacesContext facesContext, ResponseWriter writer,
+ HtmlNewspaperTable newspaperTable, UIComponent facet, String styleClass, String colElementName, int tableColumns)
+ throws IOException {
+
+ // start the row
+ HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+ writer.startElement(HTML.TR_ELEM, newspaperTable);
+ writer.startElement(colElementName, newspaperTable);
+ if(styleClass != null) writer.writeAttribute(HTML.CLASS_ATTR, styleClass, null);
+ if(colElementName.equals(HTML.TH_ELEM)) writer.writeAttribute(HTML.SCOPE_ATTR, HTML.SCOPE_COLGROUP_VALUE, null);
+
+ // span all the table's columns
+ int totalColumns = newspaperTable.getNewspaperColumns() * tableColumns;
+ if(newspaperTable.getSpacer() != null) totalColumns = totalColumns + getNewspaperColumns() - 1;
+ writer.writeAttribute(HTML.COLSPAN_ATTR, new Integer(totalColumns), null);
+
+ // write the actual cell contents
+ if(facet != null) RendererUtils.renderChild(facesContext, facet);
+
+ // finish
+ writer.endElement(colElementName);
+ writer.endElement(HTML.TR_ELEM);
+ }
+
+
+ /**
+ * Renders the column header or footer row.
+ */
+ private void renderColumnHeaderOrFooterRow(FacesContext facesContext,
+ ResponseWriter writer, HtmlNewspaperTable newspaperTable, String styleClass, boolean header)
+ throws IOException {
+
+ HtmlRendererUtils.writePrettyLineSeparator(facesContext);
+ writer.startElement(HTML.TR_ELEM, newspaperTable);
+ int newspaperColumns = newspaperTable.getNewspaperColumns();
+ for(int nc = 0; nc < newspaperColumns; nc++) {
+ for(Iterator it = newspaperTable.getChildren().iterator(); it.hasNext(); ) {
+ UIComponent uiComponent = (UIComponent)it.next();
+ if(!(uiComponent instanceof UIColumn)) continue;
+ UIColumn column = (UIColumn)uiComponent;
+ if(!column.isRendered()) continue;
+ // get the component to render
+ UIComponent facet = null;
+ if(header) facet = column.getHeader();
+ else facet = column.getFooter();
+ // do the rendering of the cells
+ renderColumnHeaderOrFooterCell(facesContext, writer, column, styleClass, facet);
+ }
+
+ // draw the spacer facet
+ if(nc < newspaperColumns - 1) renderSpacerCell(facesContext, writer, newspaperTable);
+ }
+ writer.endElement(HTML.TR_ELEM);
+ }
+
+ /**
+ * Renders a cell in the column header or footer.
+ */
+ private void renderColumnHeaderOrFooterCell(FacesContext facesContext, ResponseWriter writer,
+ UIColumn uiColumn, String styleClass, UIComponent facet) throws IOException {
+
+ writer.startElement(HTML.TH_ELEM, uiColumn);
+ if(styleClass != null) writer.writeAttribute(HTML.CLASS_ATTR, styleClass, null);
+ if(facet != null) RendererUtils.renderChild(facesContext, facet);
+ writer.endElement(HTML.TH_ELEM);
+ }
+
+ /**
+ * Renders a spacer between adjacent newspaper columns.
+ */
+ private void renderSpacerCell(FacesContext facesContext, ResponseWriter writer,
+ HtmlNewspaperTable newspaperTable) throws IOException {
+ if(newspaperTable.getSpacer() == null) return;
+
+ writer.startElement(HTML.TD_ELEM, newspaperTable);
+ RendererUtils.renderChild(facesContext, newspaperTable.getSpacer());
+ writer.endElement(HTML.TD_ELEM);
+ }
+
+ /**
+ * Gets the style class for the table header.
+ */
+ private static String getHeaderClass(HtmlNewspaperTable newspaperTable) {
+ if(newspaperTable instanceof HtmlDataTable) {
+ return ((HtmlDataTable)newspaperTable).getHeaderClass();
+ } else {
+ return (String)newspaperTable.getAttributes().get(JSFAttr.HEADER_CLASS_ATTR);
+ }
+ }
+ /**
+ * Gets the style class for the table footer.
+ */
+ private static String getFooterClass(HtmlNewspaperTable newspaperTable) {
+ if(newspaperTable instanceof HtmlDataTable) {
+ return ((HtmlDataTable)newspaperTable).getFooterClass();
+ } else {
+ return (String)newspaperTable.getAttributes().get(JSFAttr.FOOTER_CLASS_ATTR);
+ }
+ }
+
+ /**
+ * Gets styles for the specified component.
+ */
+ public static Styles getStyles(HtmlNewspaperTable newspaperTable) {
+ String rowClasses;
+ String columnClasses;
+ if(newspaperTable instanceof HtmlDataTable) {
+ rowClasses = ((HtmlDataTable)newspaperTable).getRowClasses();
+ columnClasses = ((HtmlDataTable)newspaperTable).getColumnClasses();
+ } else {
+ rowClasses = (String)newspaperTable.getAttributes().get(JSFAttr.ROW_CLASSES_ATTR);
+ columnClasses = (String)newspaperTable.getAttributes().get(JSFAttr.COLUMN_CLASSES_ATTR);
+ }
+ return new Styles(rowClasses, columnClasses);
+ }
+
+ /**
+ * Class manages the styles from String lists.
+ */
+ private static class Styles {
+
+ private String[] _columnStyle;
+ private String[] _rowStyle;
+
+ Styles(String rowStyles, String columnStyles) {
+ _rowStyle = (rowStyles == null)
+ ? ArrayUtils.EMPTY_STRING_ARRAY
+ : StringUtils.trim(
+ StringUtils.splitShortString(rowStyles, ','));
+ _columnStyle = (columnStyles == null)
+ ? ArrayUtils.EMPTY_STRING_ARRAY
+ : StringUtils.trim(
+ StringUtils.splitShortString(columnStyles, ','));
+ }
+
+ public String getRowStyle(int idx) {
+ if(!hasRowStyle()) {
+ return null;
+ }
+ return _rowStyle[idx % _rowStyle.length];
+ }
+
+ public String getColumnStyle(int idx) {
+ if(!hasColumnStyle()) {
+ return null;
+ }
+ return _columnStyle[idx % _columnStyle.length];
+ }
+
+ public boolean hasRowStyle() {
+ return _rowStyle.length > 0;
+ }
+
+ public boolean hasColumnStyle() {
+ return _columnStyle.length > 0;
+ }
+ }
+}
\ No newline at end of file