Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/myfaces/renderkit/html/HtmlGridRendererBase.java


1   /**
2    * Copyright 2004 by Irian Marinschek & Spiegl Software OEG
3    */
4   package org.apache.myfaces.renderkit.html;
5   
6   import org.apache.commons.logging.Log;
7   import org.apache.commons.logging.LogFactory;
8   import org.apache.myfaces.renderkit.RendererUtils;
9   import org.apache.myfaces.renderkit.JSFAttr;
10  import org.apache.myfaces.util.ArrayUtils;
11  import org.apache.myfaces.util.StringUtils;
12  
13  import javax.faces.context.FacesContext;
14  import javax.faces.context.ResponseWriter;
15  import javax.faces.component.UIComponent;
16  import javax.faces.component.UIPanel;
17  import javax.faces.component.html.HtmlPanelGrid;
18  import java.io.IOException;
19  import java.util.Iterator;
20  
21  /**
22   * @author Martin Marinschek
23   * @version $Revision: $ $Date: $
24   *          <p/>
25   *          $Log: $
26   */
27  public class HtmlGridRendererBase
28          extends HtmlRenderer
29  {
30      private static final Log log = LogFactory.getLog(HtmlGridRendererBase.class);
31  
32      public boolean getRendersChildren()
33      {
34          return true;
35      }
36  
37      public void encodeBegin(FacesContext facesContext, UIComponent component)
38              throws IOException
39      {
40          // all work done in encodeEnd()
41      }
42  
43      public void encodeChildren(FacesContext context, UIComponent component)
44          throws IOException
45      {
46          // all work done in encodeEnd()
47      }
48  
49      public void encodeEnd(FacesContext facesContext, UIComponent component)
50              throws IOException
51      {
52          RendererUtils.checkParamValidity(facesContext, component, UIPanel.class);
53  
54          int columns;
55          if (component instanceof HtmlPanelGrid)
56          {
57              columns = ((HtmlPanelGrid)component).getColumns();
58          }
59          else
60          {
61              Integer i = (Integer)component.getAttributes().get(JSFAttr.COLUMNS_ATTR);
62              columns = i != null ? i.intValue() : 0;
63          }
64  
65          if (columns <= 0)
66          {
67              if (log.isErrorEnabled())
68              {
69                  log.error("Wrong columns attribute for PanelGrid " + component.getClientId(facesContext) + ": " + columns);
70              }
71              columns = 1;
72          }
73  
74          ResponseWriter writer = facesContext.getResponseWriter();
75          writer.startElement(HTML.TABLE_ELEM, component);
76          HtmlRendererUtils.writeIdIfNecessary(writer, component, facesContext);
77          HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.TABLE_PASSTHROUGH_ATTRIBUTES);
78  
79          writer.flush();
80  
81          // theader and tfooter are rendered before the tbody 
82          renderHeaderOrFooter(facesContext, writer, component, columns, true);   //Header facet
83          renderHeaderOrFooter(facesContext, writer, component, columns, false);  //Footer facet
84          
85          renderChildren(facesContext, writer, component, columns);
86  
87          writer.endElement(HTML.TABLE_ELEM);
88      }
89  
90  
91      private void renderHeaderOrFooter(FacesContext context,
92                                        ResponseWriter writer,
93                                        UIComponent component,
94                                        int columns,
95                                        boolean header)
96          throws IOException
97      {
98          UIComponent facet = component.getFacet(header ? "header" : "footer");
99          if (facet == null) return;
100 
101         HtmlRendererUtils.writePrettyLineSeparator(context);
102         writer.startElement(header ? HTML.THEAD_ELEM : HTML.TFOOT_ELEM, component);
103         writer.startElement(HTML.TR_ELEM, component);
104         writer.startElement(header ? HTML.TH_ELEM : HTML.TD_ELEM, component);
105 
106         String styleClass = (component instanceof HtmlPanelGrid)
107             ? (header ?
108                          ((HtmlPanelGrid)component).getHeaderClass() :
109                          ((HtmlPanelGrid)component).getFooterClass())
110             : (header ?
111                          (String)component.getAttributes().get(JSFAttr.HEADER_CLASS_ATTR) :
112                          (String)component.getAttributes().get(JSFAttr.FOOTER_CLASS_ATTR));
113         if (styleClass != null)
114         {
115             writer.writeAttribute(HTML.CLASS_ATTR, styleClass,
116                                   header ? JSFAttr.HEADER_CLASS_ATTR : JSFAttr.FOOTER_CLASS_ATTR);
117         }
118 
119         if (header)
120         {
121             writer.writeAttribute(HTML.SCOPE_ATTR, HTML.SCOPE_COLGROUP_VALUE, null);
122         }
123 
124         writer.writeAttribute(HTML.COLSPAN_ATTR, Integer.toString(columns), null);
125 
126         HtmlRendererUtils.writePrettyLineSeparator(context);
127         RendererUtils.renderChild(context, facet);
128 
129         HtmlRendererUtils.writePrettyLineSeparator(context);
130         writer.endElement(header ? HTML.TH_ELEM : HTML.TD_ELEM);
131         writer.endElement(HTML.TR_ELEM);
132         writer.endElement(header ? HTML.THEAD_ELEM : HTML.TFOOT_ELEM);
133     }
134 
135 
136     private void renderChildren(FacesContext context,
137                                 ResponseWriter writer,
138                                 UIComponent component,
139                                 int columns)
140         throws IOException
141     {
142         writer.startElement(HTML.TBODY_ELEM, component);
143 
144         String columnClasses;
145         String rowClasses;
146         if (component instanceof HtmlPanelGrid)
147         {
148             columnClasses = ((HtmlPanelGrid)component).getColumnClasses();
149             rowClasses =  ((HtmlPanelGrid)component).getRowClasses();
150         }
151         else
152         {
153             columnClasses = (String)component.getAttributes().get(JSFAttr.COLUMN_CLASSES_ATTR);
154             rowClasses = (String)component.getAttributes().get(JSFAttr.ROW_CLASSES_ATTR);
155         }
156 
157         String[] columnClassesArray = (columnClasses == null)
158             ? ArrayUtils.EMPTY_STRING_ARRAY
159             : StringUtils.trim(StringUtils.splitShortString(columnClasses, ','));
160         int columnClassesCount = columnClassesArray.length;
161 
162         String[] rowClassesArray = (rowClasses == null)
163             ? ArrayUtils.EMPTY_STRING_ARRAY
164             : StringUtils.trim(StringUtils.splitShortString(rowClasses, ','));
165         int rowClassesCount = rowClassesArray.length;
166 
167         int childCount = component.getChildCount();
168         if (childCount > 0)
169         {
170             int columnIndex = 0;
171             int rowClassIndex = 0;
172             boolean rowStarted = false;
173             for (Iterator it = component.getChildren().iterator(); it.hasNext(); )
174             {
175                 UIComponent child = (UIComponent)it.next();
176                 if (child.isRendered())
177                 {
178                     if (columnIndex == 0)
179                     {
180                         //start of new/next row
181                         if (rowStarted)
182                         {
183                             //do we have to close the last row?
184                             writer.endElement(HTML.TR_ELEM);
185                             HtmlRendererUtils.writePrettyLineSeparator(context);
186                         }
187                         writer.startElement(HTML.TR_ELEM, component);
188                         if (rowClassIndex < rowClassesCount) {
189                             writer.writeAttribute(HTML.CLASS_ATTR, rowClassesArray[rowClassIndex], null);
190                         }
191                         rowStarted = true;
192                         rowClassIndex++;
193                         if (rowClassIndex == rowClassesCount) {
194                             rowClassIndex = 0;
195                         }
196                     }
197 
198                     writer.startElement(HTML.TD_ELEM, component);
199                     if (columnIndex < columnClassesCount)
200                     {
201                         writer.writeAttribute(HTML.CLASS_ATTR, columnClassesArray[columnIndex], null);
202                     }
203                     RendererUtils.renderChild(context, child);
204                     writer.endElement(HTML.TD_ELEM);
205 
206                     columnIndex++;
207                     if (columnIndex >= columns) {
208                         columnIndex = 0;
209                     }
210                 }
211             }
212 
213             if (rowStarted)
214             {
215                 if (columnIndex > 0)
216                 {
217                     if (log.isWarnEnabled()) log.warn("PanelGrid " + component.getClientId(context) + " has not enough children. Child count should be a multiple of the columns attribute.");
218                     //Render empty columns, so that table is correct
219                     for ( ; columnIndex < columns; columnIndex++)
220                     {
221                         writer.startElement(HTML.TD_ELEM, component);
222                         if (columnIndex < columnClassesCount)
223                         {
224                             writer.writeAttribute(HTML.CLASS_ATTR, columnClassesArray[columnIndex], null);
225                         }
226                         writer.endElement(HTML.TD_ELEM);
227                     }
228                 }
229                 writer.endElement(HTML.TR_ELEM);
230                 HtmlRendererUtils.writePrettyLineSeparator(context);
231             }
232         }
233 
234         writer.endElement(HTML.TBODY_ELEM);
235     }
236 
237 }