Save This Page
Home » tomahawk-1.1.6-src » org.apache.myfaces.renderkit.html » ext » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
   10    *   http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    * Unless required by applicable law or agreed to in writing,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied.  See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.
   18    */
   19   
   20   package org.apache.myfaces.renderkit.html.ext;
   21   
   22   import java.io.IOException;
   23   import java.util.Iterator;
   24   import java.util.List;
   25   import java.util.Map;
   26   
   27   import javax.faces.component.UIComponent;
   28   import javax.faces.component.UIData;
   29   import javax.faces.context.FacesContext;
   30   import javax.faces.context.ResponseWriter;
   31   
   32   import org.apache.commons.logging.Log;
   33   import org.apache.commons.logging.LogFactory;
   34   import org.apache.myfaces.component.html.ext.HtmlDataTable;
   35   import org.apache.myfaces.component.NewspaperTable;
   36   import org.apache.myfaces.custom.column.HtmlColumn;
   37   import org.apache.myfaces.custom.column.HtmlSimpleColumn;
   38   import org.apache.myfaces.custom.crosstable.UIColumns;
   39   import org.apache.myfaces.renderkit.html.util.ColumnInfo;
   40   import org.apache.myfaces.renderkit.html.util.RowInfo;
   41   import org.apache.myfaces.renderkit.html.util.TableContext;
   42   //import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase.Styles;
   43   import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
   44   import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
   45   import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
   46   import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
   47   import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase;
   48   import org.apache.myfaces.shared_tomahawk.util.ArrayUtils;
   49   
   50   import javax.faces.component.ValueHolder;
   51   import javax.faces.convert.Converter;
   52   import java.util;
   53   
   54   /**
   55    * Renderer for the Tomahawk extended HtmlDataTable component.
   56    * 
   57    * @author Manfred Geiler (latest modification by $Author: paulsp $)
   58    * @version $Revision: 491565 $ $Date: 2007-01-01 13:54:00 +0100 (Mo, 01 Jän 2007) $
   59    */
   60   public class HtmlTableRenderer extends HtmlTableRendererBase
   61   {
   62       private static final Log log = LogFactory.getLog(HtmlTableRenderer.class);
   63   
   64       /** DetailStamp facet name. */
   65       public static final String DETAIL_STAMP_FACET_NAME = "detailStamp";
   66       private static final String BODY_STYLE_CLASS = "bodyStyleClass";
   67       private static final String BODY_STYLE = "bodyStyle";
   68   
   69       /**
   70        * @param component dataTable
   71        * @return number of layout columns
   72        */
   73       protected int getNewspaperColumns(UIComponent component) {
   74           if (component instanceof NewspaperTable)
   75           {
   76               // the number of slices to break the table up into */
   77               NewspaperTable newspaperTable = (NewspaperTable)component;
   78               return newspaperTable.getNewspaperColumns();
   79           }
   80           return super.getNewspaperColumns(component);
   81       }
   82   
   83       /**
   84        * @param component dataTable
   85        * @return component to display between layout columns
   86        */
   87       protected UIComponent getNewspaperTableSpacer(UIComponent component) {
   88           if (component instanceof NewspaperTable)
   89           {
   90               // the number of slices to break the table up into */
   91               NewspaperTable newspaperTable = (NewspaperTable)component;
   92               return newspaperTable.getSpacer();
   93           }
   94           return super.getNewspaperTableSpacer(component);
   95       }
   96   
   97       /**
   98        * @param component dataTable
   99        * @return whether dataTable has component to display between layout columns
  100        */
  101       protected boolean hasNewspaperTableSpacer(UIComponent component) {
  102           if (null != getNewspaperTableSpacer(component))
  103           {
  104               return true;
  105           }
  106           return super.hasNewspaperTableSpacer(component);
  107       }
  108   
  109       /**
  110        * @param component dataTable
  111        * @return if the orientation of the has newspaper columns is horizontal 
  112        */
  113       protected boolean isNewspaperHorizontalOrientation(UIComponent component) {
  114           if (component instanceof NewspaperTable)
  115           {
  116           	// get the value of the newspaperOrientation attribute, any value besides horizontal
  117           	// means vertical, the default
  118               NewspaperTable newspaperTable = (NewspaperTable)component;
  119               return NewspaperTable.NEWSPAPER_HORIZONTAL_ORIENTATION.equals(newspaperTable.getNewspaperOrientation());
  120           }
  121           return super.isNewspaperHorizontalOrientation(component);
  122       }
  123   
  124       protected void afterRow(FacesContext facesContext, UIData uiData) throws IOException {
  125           super.afterRow(facesContext, uiData);
  126   
  127           renderDetailRow(facesContext, uiData);
  128       }
  129   
  130       /**
  131        *
  132        * @param facesContext
  133        * @param uiData
  134        * @throws IOException
  135        */
  136       private void renderDetailRow(FacesContext facesContext, UIData uiData) throws IOException {
  137           UIComponent detailStampFacet = uiData.getFacet(DETAIL_STAMP_FACET_NAME);
  138   
  139           if(uiData instanceof HtmlDataTable ){
  140               HtmlDataTable htmlDataTable = (HtmlDataTable)uiData;
  141   
  142               if(htmlDataTable.isCurrentDetailExpanded()){
  143                   ResponseWriter writer = facesContext.getResponseWriter();
  144                   writer.startElement(HTML.TR_ELEM,uiData);
  145                   writer.startElement(HTML.TD_ELEM,uiData);
  146                   writer.writeAttribute(HTML.COLSPAN_ATTR,new Integer(uiData.getChildren().size()) ,null);
  147   
  148                   if(detailStampFacet!=null){
  149                       RendererUtils.renderChild(facesContext, detailStampFacet);
  150                   }
  151   
  152                   writer.endElement(HTML.TD_ELEM);
  153                   writer.endElement(HTML.TR_ELEM);
  154               }
  155           }
  156       }
  157   
  158       /**
  159        * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#encodeBegin(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
  160        */
  161       public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException
  162       {
  163           if (uiComponent instanceof HtmlDataTable)
  164           {
  165               HtmlDataTable htmlDataTable = (HtmlDataTable) uiComponent;
  166               if (htmlDataTable.isRenderedIfEmpty() || htmlDataTable.getRowCount() > 0)
  167               {
  168                   super.encodeBegin(facesContext, uiComponent);
  169               }
  170           }
  171           else
  172           {
  173               super.encodeBegin(facesContext, uiComponent);
  174           }
  175       }
  176   
  177       /**
  178        * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#encodeChildren(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
  179        */
  180       public void encodeChildren(FacesContext facesContext, UIComponent component) throws IOException
  181       {
  182           if (component instanceof HtmlDataTable)
  183           {
  184               HtmlDataTable htmlDataTable = (HtmlDataTable) component;
  185               if (htmlDataTable.isRenderedIfEmpty() || htmlDataTable.getRowCount() > 0)
  186               {
  187                   super.encodeChildren(facesContext, component);
  188               }
  189           }
  190           else
  191           {
  192               super.encodeChildren(facesContext, component);
  193           }
  194       }
  195       
  196       private boolean isGroupedTable(UIData uiData)
  197       {
  198           if(uiData instanceof HtmlDataTable)
  199           {
  200               List children = getChildren(uiData);
  201               for (int j = 0, size = getChildCount(uiData); j < size; j++)
  202               {
  203                   UIComponent child = (UIComponent) children.get(j);
  204                   if(child instanceof HtmlSimpleColumn)
  205                   {
  206                       HtmlSimpleColumn column = (HtmlSimpleColumn) child;
  207                       if(column.isGroupBy())return true;
  208                   }
  209               }
  210           }
  211   
  212           return false;  //To change body of created methods use File | Settings | File Templates.
  213       }
  214   
  215       protected void beforeBody(FacesContext facesContext, UIData uiData) throws IOException
  216       {
  217           if(isGroupedTable(uiData))
  218           {
  219               createColumnInfos((HtmlDataTable) uiData, facesContext);
  220           }
  221           super.beforeBody(facesContext,uiData);
  222       }
  223   
  224       private void createColumnInfos(HtmlDataTable htmlDataTable, FacesContext facesContext)
  225           throws IOException
  226       {
  227           int first = htmlDataTable.getFirst();
  228           int rows = htmlDataTable.getRows();
  229           int last;
  230           int currentRowSpan=-1;
  231           int currentRowInfoIndex=-1;
  232   
  233           TableContext tableContext=htmlDataTable.getTableContext();
  234           RowInfo rowInfo=null;
  235           ColumnInfo columnInfo=null;
  236           HtmlSimpleColumn currentColumn=null;
  237           Map groupHashTable = new HashMap();
  238   
  239           if (rows <= 0)
  240           {
  241               last = htmlDataTable.getRowCount();
  242           }
  243           else
  244           {
  245               last = first + rows;
  246           }
  247   
  248   
  249           //Loop over the Children Columns to find the Columns with groupBy Attribute true
  250           List children = getChildren(htmlDataTable);
  251           int nChildren = getChildCount(htmlDataTable);
  252   
  253           for (int j = 0, size = nChildren; j < size; j++)
  254           {
  255               UIComponent child = (UIComponent) children.get(j);
  256               if(child instanceof HtmlSimpleColumn)
  257               {
  258                   currentColumn = (HtmlSimpleColumn) child;
  259                   if(currentColumn.isGroupBy())
  260                   {
  261                       groupHashTable.put(new Integer(j),"");
  262                   }
  263               }
  264           }
  265   
  266           boolean groupEndReached = false;
  267   
  268           for (int rowIndex = first; last==-1 || rowIndex < last; rowIndex++)
  269           {
  270               htmlDataTable.setRowIndex(rowIndex);
  271               rowInfo = new RowInfo();
  272               //scrolled past the last row
  273               if (!htmlDataTable.isRowAvailable())
  274                   break;
  275   
  276               Set groupIndexList = groupHashTable.keySet();
  277               StringBuffer currentColumnContent = null;
  278               for(Iterator it = groupIndexList.iterator(); it.hasNext(); )
  279               {
  280                   currentColumnContent = new StringBuffer();
  281                   Integer currentIndex=(Integer) it.next();
  282                   currentColumn = (HtmlSimpleColumn) children.get(currentIndex.intValue());
  283                   List currentColumnChildren = currentColumn.getChildren();
  284                   for (int j = 0, size = currentColumnChildren.size(); j < size; j++)
  285                   {
  286                       UIComponent currentColumnChild = (UIComponent) currentColumnChildren.get(j);
  287                       if (currentColumnChild.isRendered() && currentColumnChild instanceof ValueHolder)
  288                       {
  289                           Object value = ((ValueHolder) currentColumnChild).getValue();
  290                           if (value != null) {
  291                               Converter converter =
  292                                   HtmlRendererUtils.findUIOutputConverterFailSafe(facesContext, currentColumnChild);
  293                               currentColumnContent.append(
  294                                   RendererUtils.getConvertedStringValue(facesContext, currentColumnChild,
  295                                                                         converter, value)); // TODO converter
  296                           }
  297                       }
  298                   }
  299                   if (currentColumnContent.toString().compareTo(
  300                       (groupHashTable.get(currentIndex)).toString())!=0 &&
  301                       currentRowInfoIndex > -1)
  302                   {
  303                       groupEndReached = true;
  304                       groupHashTable.put(currentIndex,currentColumnContent);
  305                   }
  306                   else if(currentRowInfoIndex == -1)
  307                   {
  308                       groupHashTable.put(currentIndex,currentColumnContent);
  309                   }
  310               }
  311               currentRowSpan++;
  312   
  313   
  314               for (int j = 0, size = nChildren; j < size; j++)
  315               {
  316                   columnInfo = new ColumnInfo();
  317                   if(groupHashTable.containsKey(new Integer(j)))  // Column is groupBy
  318                   {
  319                       if(currentRowSpan > 0)
  320                       {
  321                           if(groupEndReached)
  322                           {
  323                               ((ColumnInfo)
  324                                   ((RowInfo)
  325                                       tableContext.getRowInfos().get(currentRowInfoIndex-currentRowSpan+1)).
  326                                       getColumnInfos().get(j)).
  327                                   setRowSpan(currentRowSpan);
  328                               columnInfo.setStyle(htmlDataTable.getRowGroupStyle());
  329                               columnInfo.setStyleClass(htmlDataTable.getRowGroupStyleClass());
  330                           }
  331                           else
  332                           {
  333                               columnInfo.setRendered(false);
  334                           }
  335                       }
  336                       else
  337                       {
  338                           columnInfo.setStyle(htmlDataTable.getRowGroupStyle());
  339                           columnInfo.setStyleClass(htmlDataTable.getRowGroupStyleClass());
  340                       }
  341   
  342                   }
  343                   else    // Column  is not group by
  344                   {
  345                       if(groupEndReached)
  346                       {
  347                           ((ColumnInfo)
  348                               ((RowInfo)
  349                                   tableContext.getRowInfos().get(currentRowInfoIndex)).
  350                                   getColumnInfos().get(j)).
  351                               setStyle(htmlDataTable.getRowGroupStyle());
  352                           ((ColumnInfo)
  353                               ((RowInfo)
  354                                   tableContext.getRowInfos().get(currentRowInfoIndex)).
  355                                   getColumnInfos().get(j)).
  356                               setStyleClass(htmlDataTable.getRowGroupStyleClass());
  357                       }
  358                   }
  359                   rowInfo.getColumnInfos().add(columnInfo);
  360               }
  361               if(groupEndReached)
  362               {
  363                   currentRowSpan=0;
  364                   groupEndReached = false;
  365               }
  366               tableContext.getRowInfos().add(rowInfo);
  367               currentRowInfoIndex++;
  368           }
  369           for (int j = 0, size = nChildren; j < size; j++)
  370           {
  371               if(groupHashTable.containsKey(new Integer(j)))  // Column is groupBy
  372               {
  373                   ((ColumnInfo)
  374                       ((RowInfo)
  375                           tableContext.getRowInfos().get(currentRowInfoIndex-currentRowSpan)).
  376                           getColumnInfos().get(j)).
  377                       setRowSpan(currentRowSpan+1);
  378               }
  379               else    // Column  is not group by
  380               {
  381                   ((ColumnInfo)
  382                       ((RowInfo)
  383                           tableContext.getRowInfos().get(currentRowInfoIndex)).
  384                           getColumnInfos().get(j)).
  385                       setStyle(htmlDataTable.getRowGroupStyle());
  386                   ((ColumnInfo)
  387                       ((RowInfo)
  388                           tableContext.getRowInfos().get(currentRowInfoIndex)).
  389                           getColumnInfos().get(j)).
  390                       setStyleClass(htmlDataTable.getRowGroupStyleClass());
  391               }
  392           }
  393   
  394           htmlDataTable.setRowIndex(-1);
  395       }
  396   
  397   
  398       /**
  399        * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#encodeEnd(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
  400        */
  401       public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException
  402       {
  403           if (uiComponent instanceof HtmlDataTable)
  404           {
  405               HtmlDataTable htmlDataTable = (HtmlDataTable) uiComponent;
  406               if (htmlDataTable.isRenderedIfEmpty() || htmlDataTable.getRowCount() > 0)
  407               {
  408                   super.encodeEnd(facesContext, uiComponent);                               
  409               }
  410           }
  411           else
  412           {
  413               super.encodeEnd(facesContext, uiComponent);
  414           }
  415       }
  416   
  417       protected void renderRowStart(FacesContext facesContext,
  418                                     ResponseWriter writer, UIData uiData, Styles styles, int rowStyleIndex)
  419           throws IOException
  420       {
  421           super.renderRowStart(facesContext, writer, uiData, styles, rowStyleIndex);
  422   
  423           // get event handlers from component
  424           HtmlDataTable table = (HtmlDataTable) uiData;
  425   
  426           renderRowAttribute(writer, HTML.ONCLICK_ATTR, table.getRowOnClick());
  427           renderRowAttribute(writer, HTML.ONDBLCLICK_ATTR, table.getRowOnDblClick());
  428           renderRowAttribute(writer, HTML.ONKEYDOWN_ATTR, table.getRowOnKeyDown());
  429           renderRowAttribute(writer, HTML.ONKEYPRESS_ATTR, table.getRowOnKeyPress());
  430           renderRowAttribute(writer, HTML.ONKEYUP_ATTR, table.getRowOnKeyUp());
  431           renderRowAttribute(writer, HTML.ONMOUSEDOWN_ATTR, table.getRowOnMouseDown());
  432           renderRowAttribute(writer, HTML.ONMOUSEMOVE_ATTR, table.getRowOnMouseMove());
  433           renderRowAttribute(writer, HTML.ONMOUSEOUT_ATTR, table.getRowOnMouseOut());
  434           renderRowAttribute(writer, HTML.ONMOUSEOVER_ATTR, table.getRowOnMouseOver());
  435           renderRowAttribute(writer, HTML.ONMOUSEUP_ATTR, table.getRowOnMouseUp());
  436       }
  437   
  438       /**
  439        * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#renderRowStyle(javax.faces.context.FacesContext, javax.faces.context.ResponseWriter, javax.faces.component.UIData, java.util.Iterator)
  440        */
  441       protected void renderRowStyle(FacesContext facesContext, ResponseWriter writer, UIData uiData, Styles styles, int rowStyleIndex) throws IOException
  442       {
  443           String rowStyleClass;
  444           String rowStyle;
  445           if (uiData instanceof HtmlDataTable)
  446           {
  447               HtmlDataTable datatable = (HtmlDataTable) uiData;
  448               rowStyleClass = datatable.getRowStyleClass();
  449               rowStyle = datatable.getRowStyle();
  450           }
  451           else
  452           {
  453               rowStyleClass = (String) uiData.getAttributes().get(JSFAttr.ROW_STYLECLASS_ATTR);
  454               rowStyle = (String) uiData.getAttributes().get(JSFAttr.ROW_STYLE_ATTR);
  455           }
  456           if(rowStyleClass == null)
  457           {
  458               super.renderRowStyle(facesContext, writer, uiData, styles, rowStyleIndex);
  459           }
  460           else
  461           {
  462               writer.writeAttribute(HTML.CLASS_ATTR, rowStyleClass, null);
  463           }
  464           if(rowStyle != null)
  465           {
  466               writer.writeAttribute(HTML.STYLE_ATTR, rowStyle, null);
  467           }
  468       }
  469   
  470       protected void renderRowAttribute(ResponseWriter writer,
  471                                         String htmlAttribute, Object value) throws IOException
  472       {
  473           if (value != null)
  474           {
  475               writer.writeAttribute(htmlAttribute, value, null);
  476           }
  477       }       
  478   
  479       /**
  480        * Render the specified column object using the current row data.
  481        * <p>
  482        * When the component is a UIColumn object, the inherited method is
  483        * invoked to render a single table cell.
  484        * <p>
  485        * In addition to the inherited functionality, support is implemented
  486        * here for UIColumns children. When a UIColumns child is encountered:
  487        * <pre>
  488        * For each dynamic column in that UIColumns child:
  489        *   * Select the column (which sets variable named by the var attribute
  490        *     to refer to the current column object) 
  491        *   * Call this.renderColumnBody passing the UIColumns object.
  492        * </pre>
  493        * The renderColumnBody method eventually:
  494        * <ul>
  495        * <li>emits TD
  496        * <li>calls encodeBegin on the UIColumns (which does nothing)
  497        * <li>calls rendering methods on all children of the UIColumns
  498        * <li>calls encodeEnd on the UIColumns (which does nothing)
  499        * <li> emits /TD
  500        * </ul>
  501        * If the children of the UIColumns access the variable named by the var
  502        * attribute on the UIColumns object, then they end up rendering content
  503        * that is extracted from the current column object.  
  504        * 
  505        * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#encodeColumnChild(javax.faces.context.FacesContext, javax.faces.context.ResponseWriter, javax.faces.component.UIData, javax.faces.component.UIComponent, java.util.Iterator)
  506        */
  507       protected void encodeColumnChild(FacesContext facesContext,
  508                                        ResponseWriter writer, UIData uiData,
  509                                        UIComponent component, Styles styles, int columnStyleIndex)
  510           throws IOException
  511       {
  512           super.encodeColumnChild(facesContext, writer, uiData, component,
  513                                   styles, columnStyleIndex);
  514           if (component instanceof UIColumns)
  515           {
  516               UIColumns columns = (UIColumns) component;
  517               for (int k = 0, colSize = columns.getRowCount(); k < colSize; k++)
  518               {
  519                   columns.setRowIndex(k);
  520                   renderColumnBody(facesContext, writer, uiData, component,
  521                                   styles, columnStyleIndex);
  522               }
  523               columns.setRowIndex(-1);
  524           }               
  525       }
  526   
  527       /**
  528        * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#renderColumnBody(javax.faces.context.FacesContext, javax.faces.context.ResponseWriter, javax.faces.component.UIData, javax.faces.component.UIComponent, java.util.Iterator)
  529        */
  530       protected void renderColumnBody(FacesContext facesContext,
  531                                       ResponseWriter writer, UIData uiData,
  532                                       UIComponent component, Styles styles, int columnStyleIndex)
  533           throws IOException
  534       {
  535           if (isGroupedTable(uiData)){
  536   
  537               HtmlDataTable htmlDataTable = (HtmlDataTable) uiData;
  538               List tableChildren = htmlDataTable.getChildren();
  539   
  540               int first = htmlDataTable.getFirst();
  541               int rowInfoIndex= htmlDataTable.getRowIndex()-first;
  542               int columnInfoIndex = tableChildren.indexOf(component);
  543   
  544               RowInfo rowInfo = (RowInfo) htmlDataTable.getTableContext().getRowInfos().get(rowInfoIndex);
  545               ColumnInfo columnInfo= (ColumnInfo) rowInfo.getColumnInfos().get(columnInfoIndex);
  546   
  547               if(!columnInfo.isRendered()) return;
  548   
  549               if (component instanceof HtmlColumn && amISpannedOver(null, component))
  550                   return;
  551               writer.startElement(HTML.TD_ELEM, uiData);
  552               String styleClass = ((HtmlColumn) component).getStyleClass();
  553               if(columnInfo.getStyleClass()!= null)
  554               {
  555                   styleClass = columnInfo.getStyleClass();
  556               }
  557   
  558               if(styles.hasColumnStyle())
  559               {
  560                   if (styleClass == null)
  561                   {
  562                       styleClass = styles.getColumnStyle(columnStyleIndex);
  563                   }
  564               }
  565               if (styleClass != null)
  566               {
  567                   writer.writeAttribute(HTML.CLASS_ATTR, styleClass, null);
  568               }
  569   
  570               if (columnInfo.getStyle() != null)
  571               {
  572                   writer.writeAttribute(HTML.STYLE_ATTR, columnInfo.getStyle(), null);
  573               }
  574   
  575               if (columnInfo.getRowSpan() > 1)
  576               {
  577                   writer.writeAttribute("rowspan", new Integer(columnInfo.getRowSpan()).toString(), null);
  578                   if (columnInfo.getStyle() == null)
  579                   {
  580                       writer.writeAttribute(HTML.STYLE_ATTR, "vertical-align:top", null);
  581                   }
  582               }
  583   
  584               renderHtmlColumnAttributes(writer, component, null);
  585   
  586               RendererUtils.renderChild(facesContext, component);
  587               writer.endElement(HTML.TD_ELEM);
  588           }
  589           else if (component instanceof HtmlColumn)
  590           {
  591               if (amISpannedOver(null, component))
  592                   return;
  593               writer.startElement(HTML.TD_ELEM, uiData);
  594               String styleClass = ((HtmlColumn) component).getStyleClass();
  595               if(styles.hasColumnStyle())
  596               {
  597                   if (styleClass == null)
  598                   {
  599                       styleClass = styles.getColumnStyle(columnStyleIndex);
  600                   }
  601               }
  602               if (styleClass != null)
  603               {
  604                   writer.writeAttribute(HTML.CLASS_ATTR, styleClass, null);
  605               }
  606               renderHtmlColumnAttributes(writer, component, null);
  607   
  608               RendererUtils.renderChild(facesContext, component);
  609               writer.endElement(HTML.TD_ELEM);
  610           }
  611           else
  612           {
  613               super.renderColumnBody(facesContext, writer, uiData, component,
  614                                       styles, columnStyleIndex);
  615           }
  616       }
  617   
  618       /**
  619        * Render the header or footer of the specified column object.
  620        * <p>
  621        * When the component is a UIColumn object, the inherited method is
  622        * invoked to render a single header cell.
  623        * <p>
  624        * In addition to the inherited functionality, support is implemented
  625        * here for UIColumns children. When a UIColumns child is encountered:
  626        * <pre>
  627        * For each dynamic column in that UIColumns child:
  628        *   * Select the column (which sets variable named by the var attribute
  629        *     to refer to the current column object) 
  630        *   * Call this.renderColumnHeaderCell or this.renderColumnFooterCell
  631        *     passing the header or footer facet of the UIColumns object.
  632        * </pre>
  633        * If the facet of the UIColumns accesses the variable named by the var
  634        * attribute on the UIColumns object, then it ends up rendering content
  635        * that is extracted from the current column object.
  636        *   
  637        * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#renderColumnChildHeaderOrFooterRow(javax.faces.context.FacesContext, javax.faces.context.ResponseWriter, javax.faces.component.UIComponent, java.lang.String, boolean)
  638        */
  639       protected void renderColumnChildHeaderOrFooterRow(
  640           FacesContext facesContext, ResponseWriter writer,
  641           UIComponent uiComponent, String styleClass, boolean header)
  642           throws IOException
  643       {
  644           super.renderColumnChildHeaderOrFooterRow(facesContext, writer,
  645                                                    uiComponent, styleClass, header);
  646           if (uiComponent instanceof UIColumns)
  647           {
  648               UIColumns columns = (UIColumns) uiComponent;
  649               for (int i = 0, size = columns.getRowCount(); i < size; i++)
  650               {
  651                   columns.setRowIndex(i);
  652                   if (header)
  653                   {
  654                       renderColumnHeaderCell(facesContext, writer, columns,
  655                                              columns.getHeader(), styleClass, 0);
  656                   }
  657                   else
  658                   {
  659                       renderColumnFooterCell(facesContext, writer, columns,
  660                                              columns.getFooter(), styleClass, 0);
  661                   }
  662               }
  663               columns.setRowIndex(-1);
  664           }
  665       }
  666   
  667       /**
  668        * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#renderColumnHeaderCell(javax.faces.context.FacesContext, javax.faces.context.ResponseWriter, javax.faces.component.UIComponent, javax.faces.component.UIComponent, java.lang.String, int)
  669        */
  670       protected void renderColumnHeaderCell(FacesContext facesContext,
  671                                             ResponseWriter writer, UIComponent uiComponent,
  672                                             UIComponent facet, String headerStyleClass, int colspan)
  673           throws IOException
  674       {
  675           if (uiComponent instanceof HtmlColumn)
  676           {
  677               if (amISpannedOver("header", uiComponent))
  678                   return;
  679               writer.startElement(HTML.TH_ELEM, uiComponent);
  680               if (colspan > 1)
  681               {
  682                   writer.writeAttribute(HTML.COLSPAN_ATTR, new Integer(colspan),
  683                                         null);
  684               }
  685               String styleClass = ((HtmlColumn) uiComponent)
  686                   .getHeaderstyleClass();
  687               if (styleClass == null)
  688               {
  689                   styleClass = headerStyleClass;
  690               }
  691               if (styleClass != null)
  692               {
  693                   writer.writeAttribute(HTML.CLASS_ATTR, styleClass, null);
  694               }
  695               renderHtmlColumnAttributes(writer, uiComponent, "header");
  696               if (facet != null)
  697               {
  698                   RendererUtils.renderChild(facesContext, facet);
  699               }
  700               writer.endElement(HTML.TH_ELEM);
  701           }
  702           else
  703           {
  704               super.renderColumnHeaderCell(facesContext, writer, uiComponent,
  705                                            facet, headerStyleClass, colspan);
  706           }
  707       }
  708   
  709       /**
  710        * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#renderColumnFooterCell(javax.faces.context.FacesContext, javax.faces.context.ResponseWriter, javax.faces.component.UIComponent, javax.faces.component.UIComponent, java.lang.String, int)
  711        */
  712       protected void renderColumnFooterCell(FacesContext facesContext,
  713                                             ResponseWriter writer, UIComponent uiComponent,
  714                                             UIComponent facet, String footerStyleClass, int colspan)
  715           throws IOException
  716       {
  717           if (uiComponent instanceof HtmlColumn)
  718           {
  719               if (amISpannedOver("footer", uiComponent))
  720                   return;
  721               writer.startElement(HTML.TD_ELEM, uiComponent);
  722               if (colspan > 1)
  723               {
  724                   writer.writeAttribute(HTML.COLSPAN_ATTR, new Integer(colspan),
  725                                         null);
  726               }
  727               String styleClass = ((HtmlColumn) uiComponent)
  728                   .getFooterstyleClass();
  729               if (styleClass == null)
  730               {
  731                   styleClass = footerStyleClass;
  732               }
  733               if (styleClass != null)
  734               {
  735                   writer.writeAttribute(HTML.CLASS_ATTR, styleClass, null);
  736               }
  737               renderHtmlColumnAttributes(writer, uiComponent, "footer");
  738               if (facet != null)
  739               {
  740                   RendererUtils.renderChild(facesContext, facet);
  741               }
  742               writer.endElement(HTML.TD_ELEM);
  743           }
  744           else
  745           {
  746               super.renderColumnFooterCell(facesContext, writer, uiComponent,
  747                                            facet, footerStyleClass, colspan);
  748           }
  749       }
  750   
  751       protected void renderHtmlColumnAttributes(ResponseWriter writer,
  752                                                 UIComponent uiComponent, String prefix) throws IOException
  753       {
  754           String[] attrs = (String[]) ArrayUtils.concat(HTML.COMMON_PASSTROUGH_ATTRIBUTES_WITHOUT_STYLE, new String[] {HTML.COLSPAN_ATTR});
  755           for (int i = 0, size = attrs.length; i < size; i++)
  756           {
  757               String attributeName = attrs[i];
  758               String compAttrName = prefix != null ? prefix + attributeName : attributeName;
  759               HtmlRendererUtils.renderHTMLAttribute(writer, uiComponent,
  760                                                     compAttrName, attributeName);
  761           }
  762           String compAttrName = prefix != null ? prefix + HTML.STYLE_ATTR : HTML.STYLE_ATTR;
  763           HtmlRendererUtils.renderHTMLAttribute(writer, uiComponent,
  764                                                 compAttrName, HTML.STYLE_ATTR);
  765   
  766           HtmlRendererUtils.renderHTMLAttribute(writer, uiComponent,
  767                                                 HTML.WIDTH_ATTR, HTML.WIDTH_ATTR);
  768       }
  769   
  770       /**
  771        * Return the number of columns spanned by the specified component.
  772        * <p>
  773        * For normal components, use the inherited implementation.
  774        * For UIColumns children, return the number of dynamic columns rendered
  775        * by that child.
  776        * 
  777        * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase
  778        *   #determineChildColSpan(javax.faces.component.UIComponent)
  779        */
  780       protected int determineChildColSpan(UIComponent uiComponent)
  781       {
  782           int result = super.determineChildColSpan(uiComponent);
  783           if (uiComponent instanceof UIColumns)
  784           {
  785               result += ((UIColumns) uiComponent).getRowCount();
  786           }
  787           return result;
  788       }
  789   
  790       /**
  791        * Return true if the specified component has a facet that needs to be
  792        * rendered in a THEAD or TFOOT section.
  793        * 
  794        * @see org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase#hasFacet(boolean, javax.faces.component.UIComponent)
  795        */
  796       protected boolean hasFacet(boolean header, UIComponent uiComponent)
  797       {
  798           boolean result = super.hasFacet(header, uiComponent);
  799           if (!result && uiComponent instanceof UIColumns)
  800           {
  801               // Why is this necessary? It seems to me that the inherited
  802               // implementation will work fine with a UIColumns component...
  803               UIColumns columns = (UIColumns) uiComponent;
  804               result = header ? columns.getHeader() != null : columns.getFooter() != null;
  805           }
  806           return result;
  807       }
  808   
  809       /**
  810        * Renders the column footer.
  811        * Rendering will be supressed if all of the facets have rendered="false"   
  812        */
  813       protected void renderColumnFooterRow(FacesContext facesContext, ResponseWriter writer, UIComponent component, String footerStyleClass) throws IOException
  814       {
  815           if (determineRenderFacet(component, false))
  816           {
  817               super.renderColumnFooterRow(facesContext, writer, component, footerStyleClass);
  818           }
  819       }
  820   
  821       /**
  822        * Renders the column header.
  823        * Rendering will be supressed if all of the facets have rendered="false"   
  824        */
  825       protected void renderColumnHeaderRow(FacesContext facesContext, ResponseWriter writer, UIComponent component, String headerStyleClass) throws IOException
  826       {
  827           if (determineRenderFacet(component, true))
  828           {
  829               super.renderColumnHeaderRow(facesContext, writer, component, headerStyleClass);
  830           }
  831       }
  832   
  833       /**
  834        * determine if the header or footer should be rendered.
  835        */
  836       protected boolean determineRenderFacet(UIComponent component, boolean header)
  837       {
  838           for (Iterator it = getChildren(component).iterator(); it.hasNext();)
  839           {
  840               UIComponent uiComponent = (UIComponent) it.next();
  841               if(uiComponent.isRendered() && determineChildColSpan(uiComponent) > 0)
  842               {
  843                   UIComponent facet = header ? (UIComponent) uiComponent.getFacets().get(HEADER_FACET_NAME)
  844                       : (UIComponent) uiComponent.getFacets().get(FOOTER_FACET_NAME);
  845   
  846                   if (facet != null && facet.isRendered())
  847                   {
  848                       return true;
  849                   }
  850               }
  851           }
  852   
  853           return false;
  854       }
  855       
  856       protected void beforeColumn(FacesContext facesContext, UIData uiData, int columnIndex) throws IOException
  857       {        
  858           super.beforeColumn(facesContext, uiData, columnIndex);
  859           
  860           if (uiData instanceof HtmlDataTable)
  861           {
  862               HtmlDataTable dataTable = (HtmlDataTable)uiData;
  863               
  864               putSortedReqScopeParam(facesContext, dataTable, columnIndex);
  865           }
  866       }
  867       
  868       protected void beforeColumnHeaderOrFooter(FacesContext facesContext, UIData uiData, boolean header, int columnIndex) throws IOException
  869       {        
  870           super.beforeColumnHeaderOrFooter(facesContext, uiData, header, columnIndex);
  871           
  872           if (header && uiData instanceof HtmlDataTable)
  873           {
  874               HtmlDataTable dataTable = (HtmlDataTable)uiData;
  875               
  876               putSortedReqScopeParam(facesContext, dataTable, columnIndex);
  877           }
  878       }
  879       
  880       protected void putSortedReqScopeParam(FacesContext facesContext, HtmlDataTable dataTable, int columnIndex)
  881       {
  882           String sortedColumnVar = dataTable.getSortedColumnVar();
  883           Map requestMap = facesContext.getExternalContext().getRequestMap();
  884   
  885           if (columnIndex == dataTable.getSortColumnIndex())
  886           {                
  887               if (sortedColumnVar != null)
  888                   requestMap.put(sortedColumnVar, Boolean.TRUE);
  889           }
  890           else if (sortedColumnVar != null)
  891               requestMap.remove(sortedColumnVar);
  892       }
  893   
  894       /**
  895        * specify if the header, footer or <td> is spanned over (not shown) because
  896        * of a colspan in a cell in a previous column
  897        * 
  898        * @param prefix header, footer or null
  899        * @param uiComponent
  900        */
  901       protected boolean amISpannedOver(String prefix, UIComponent component) {
  902           UIComponent table = component.getParent();
  903           int span = 0;
  904           for (Iterator it = table.getChildren().iterator(); it.hasNext();) {
  905               UIComponent columnComponent = (UIComponent) it.next();
  906               if (!(columnComponent instanceof HtmlColumn))
  907                  continue;
  908               if (span > 0)
  909                   span--;
  910               if (columnComponent == component)
  911                   return span > 0;
  912               if (span == 0) {
  913                   try {
  914                       if (prefix == null && ((HtmlColumn)columnComponent).getColspan() != null)
  915                           span = Integer.parseInt(((HtmlColumn)columnComponent).getColspan());
  916                       if ("header".equals(prefix) && ((HtmlColumn)columnComponent).getHeadercolspan() != null)
  917                           span = Integer.parseInt(((HtmlColumn)columnComponent).getHeadercolspan());
  918                       if ("footer".equals(prefix) && ((HtmlColumn)columnComponent).getFootercolspan() != null)
  919                           span = Integer.parseInt(((HtmlColumn)columnComponent).getFootercolspan());
  920                   }
  921                   catch (NumberFormatException ex) {
  922                       log.warn("Invalid " + ((prefix == null) ? "" : prefix) + "colspan attribute ignored");
  923                   }
  924               }
  925           }
  926           return false;
  927       }
  928   
  929   
  930       /**
  931        * Perform any operations necessary in the TBODY start tag.
  932        *
  933        * @param facesContext the <code>FacesContext</code>.
  934        * @param uiData the <code>UIData</code> being rendered.
  935        */
  936       protected void inBodyStart(FacesContext facesContext, UIData uiData) throws IOException
  937       {
  938           String bodyStyleClass;
  939           String bodyStyle;
  940   
  941           if(uiData instanceof HtmlDataTable) {
  942               bodyStyleClass = ((HtmlDataTable)uiData).getBodyStyleClass();
  943               bodyStyle = ((HtmlDataTable)uiData).getBodyStyle();
  944           } else {
  945               bodyStyleClass = (String)uiData.getAttributes().get(BODY_STYLE_CLASS);
  946               bodyStyle = (String)uiData.getAttributes().get(BODY_STYLE);
  947           }
  948   
  949           ResponseWriter writer = facesContext.getResponseWriter();
  950           if (bodyStyleClass != null)
  951           {
  952               writer.writeAttribute(HTML.CLASS_ATTR, bodyStyleClass,
  953                       BODY_STYLE_CLASS);
  954           }
  955           if (bodyStyle != null)
  956           {
  957               writer.writeAttribute(HTML.STYLE_ATTR, bodyStyle, BODY_STYLE);
  958           }
  959       }
  960   
  961   
  962   
  963   }

Save This Page
Home » tomahawk-1.1.6-src » org.apache.myfaces.renderkit.html » ext » [javadoc | source]