View Javadoc

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  package org.apache.myfaces.renderkit.html.ext;
20  
21  import java.io.IOException;
22  import java.util.List;
23  import java.util.logging.Logger;
24  
25  import javax.faces.component.UIColumn;
26  import javax.faces.component.UIComponent;
27  import javax.faces.component.UIData;
28  import javax.faces.context.FacesContext;
29  import javax.faces.context.ResponseWriter;
30  import javax.faces.convert.ConverterException;
31  
32  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
33  import org.apache.myfaces.component.html.ext.HtmlDataTable;
34  import org.apache.myfaces.component.html.ext.HtmlTableRow;
35  import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
36  import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
37  import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
38  import org.apache.myfaces.shared_tomahawk.util.ArrayUtils;
39  import org.apache.myfaces.shared_tomahawk.util.StringUtils;
40  
41  @JSFRenderer(renderKitId = "HTML_BASIC", family = "org.apache.myfaces.HtmlTableRow", type = "org.apache.myfaces.HtmlTableRow")
42  public class HtmlTableRowRenderer extends HtmlTableRenderer
43  {
44      private static final Logger log = Logger.getLogger(HtmlTableRowRenderer.class.getName());
45      
46      private static final Integer[] ZERO_INT_ARRAY = new Integer[]{0};
47      
48      @Override
49      public void encodeEnd(FacesContext facesContext, UIComponent component)
50              throws IOException
51      {
52          //super.encodeEnd(facesContext, component);
53          RendererUtils.checkParamValidity(facesContext, component, HtmlTableRow.class);
54          
55          ResponseWriter writer = facesContext.getResponseWriter();
56          UIData uiData = (UIData) component.getParent();
57  
58          if (uiData instanceof HtmlDataTable)
59          {
60              HtmlDataTable htmlDataTable = (HtmlDataTable) uiData;
61  
62              int rowCount = uiData.getRowCount();
63  
64              // begin the table
65              // get the CSS styles
66              Styles styles = getStyles(uiData);
67  
68              int first = uiData.getFirst();
69              int rows = uiData.getRows();
70              int last;
71  
72              if (rows <= 0)
73              {
74                 last = rowCount;
75              }
76              else
77              {
78                 last = first + rows;
79                 if (last > rowCount)
80                 {
81                     last = rowCount;
82                 }
83              }
84  
85              int newspaperColumns = getNewspaperColumns(uiData);
86              int newspaperRows;
87              if((last - first) % newspaperColumns == 0)
88                  newspaperRows = (last - first) / newspaperColumns;
89              else newspaperRows = ((last - first) / newspaperColumns) + 1;
90              boolean newspaperHorizontalOrientation = isNewspaperHorizontalOrientation(uiData);
91  
92              // get the row indizes for which a new TBODY element should be created
93              Integer[] bodyrows = null;
94              String bodyrowsAttr = (String) uiData.getAttributes().get(JSFAttr.BODYROWS_ATTR);
95              if(bodyrowsAttr != null && !"".equals(bodyrowsAttr)) 
96              {   
97                  String[] bodyrowsString = StringUtils.trim(StringUtils.splitShortString(bodyrowsAttr, ','));
98                  // parsing with no exception handling, because of JSF-spec: 
99                  // "If present, this must be a comma separated list of integers."
100                 bodyrows = new Integer[bodyrowsString.length];
101                 for(int i = 0; i < bodyrowsString.length; i++) 
102                 {
103                     bodyrows[i] = new Integer(bodyrowsString[i]);
104                 }
105                 
106             }
107             else
108             {
109                 bodyrows = ZERO_INT_ARRAY;
110             }
111             //int bodyrowsCount = 0;
112             
113             int savedRow = uiData.getRowIndex();
114 
115             //(startRow - first) - ((startRow - first) % newspaperColums)
116             
117             int nr = newspaperHorizontalOrientation ? 
118                     (savedRow-first)/newspaperColumns :
119                      savedRow-first; //(savedRow-first) % newspaperRows;
120                     
121             // walk through the newspaper rows
122             //for(int nr = 0; nr < newspaperRows; nr++)
123             //{
124             boolean rowStartRendered = false;
125             // walk through the newspaper columns
126             for(int nc = 0; nc < newspaperColumns; nc++) {
127 
128                 // the current row in the 'real' table
129                 int currentRow;
130                 if (newspaperHorizontalOrientation)
131                     currentRow = nr * newspaperColumns + nc + first;
132                 else
133                     currentRow = nc * newspaperRows + nr + first;
134                 
135                 // if this row is not to be rendered
136                 if(currentRow >= last) continue;
137 
138                 // bail if any row does not exist
139                 uiData.setRowIndex(currentRow);
140                 if(!uiData.isRowAvailable()) {
141                     log.severe("Row is not available. Rowindex = " + currentRow);
142                     break;
143                 }
144     
145                 if (nc == 0) {
146                     // first column in table, start new row
147                     //beforeRow(facesContext, uiData);
148 
149                     // is the current row listed in the bodyrows attribute
150                     if(ArrayUtils.contains(bodyrows, currentRow))  
151                     {
152                         // close any preopened TBODY element first
153                         /*
154                         if(bodyrowsCount != 0) 
155                         {
156                             HtmlRendererUtils.writePrettyLineSeparator(facesContext);
157                             writer.endElement(HTML.TBODY_ELEM);
158                         }
159                         HtmlRendererUtils.writePrettyLineSeparator(facesContext);
160                         writer.startElement(HTML.TBODY_ELEM, uiData); 
161                         // Do not attach bodyrowsCount to the first TBODY element, because of backward compatibility
162                         writer.writeAttribute(HTML.ID_ATTR, uiData.getClientId(facesContext) + ":tbody_element" + 
163                             (bodyrowsCount == 0 ? "" : bodyrowsCount), null);
164                         bodyrowsCount++;
165                         */
166                     }
167                     
168                     HtmlRendererUtils.writePrettyLineSeparator(facesContext);
169                     renderRowStart(facesContext, writer, uiData, styles, nr);
170                     rowStartRendered = true;
171                 }
172 
173                 List children = getChildren(uiData);
174                 for (int j = 0, size = getChildCount(uiData); j < size; j++)
175                 {
176                     UIComponent child = (UIComponent) children.get(j);
177                     if (child.isRendered())
178                     {
179                         boolean columnRendering = child instanceof UIColumn;
180                         
181                         if (columnRendering)
182                             beforeColumn(facesContext, uiData, j);
183                            
184                         encodeColumnChild(facesContext, writer, uiData, child, styles, nc * uiData.getChildCount() + j);                    
185                        
186                         if (columnRendering)
187                             afterColumn(facesContext, uiData, j);
188                     }
189                 }
190 
191                 if (hasNewspaperTableSpacer(uiData))
192                 {
193                     // draw the spacer facet
194                     if(nc < newspaperColumns - 1) renderSpacerCell(facesContext, writer, uiData);
195                 }
196             }
197             if (rowStartRendered)
198             {
199                 renderRowEnd(facesContext, writer, uiData);
200                 //afterRow(facesContext, uiData);
201             }
202             //}
203             
204             if (uiData.getRowIndex() != savedRow)
205             {
206                 uiData.setRowIndex(savedRow);
207             }
208         }
209     }
210     
211     @Override
212     public boolean getRendersChildren()
213     {
214         return true;
215     }
216     
217     public void encodeChildren(FacesContext context, UIComponent component) throws IOException
218     {
219     }
220     
221     public void decode(FacesContext context, UIComponent component)
222     {
223         if (context == null)
224             throw new NullPointerException("context");
225         if (component == null)
226             throw new NullPointerException("component");
227     }
228 
229     public void encodeBegin(FacesContext context, UIComponent component) throws IOException
230     {
231         if (context == null)
232             throw new NullPointerException("context");
233         if (component == null)
234             throw new NullPointerException("component");
235     }
236 
237     public String convertClientId(FacesContext context, String clientId)
238     {
239         if (context == null)
240             throw new NullPointerException("context");
241         if (clientId == null)
242             throw new NullPointerException("clientId");
243         return clientId;
244     }
245 
246     public Object getConvertedValue(FacesContext context, UIComponent component, Object submittedValue)
247         throws ConverterException
248     {
249         if (context == null)
250             throw new NullPointerException("context");
251         if (component == null)
252             throw new NullPointerException("component");
253         return submittedValue;
254     }
255 }