1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.custom.newspaper;
20
21 import javax.faces.component.UIComponent;
22 import javax.faces.context.FacesContext;
23 import javax.faces.component.behavior.ClientBehavior;
24 import javax.faces.component.behavior.ClientBehaviorHolder;
25 import javax.faces.component.html.HtmlDataTable;
26 import javax.faces.context.ResponseWriter;
27 import javax.faces.component.UIColumn;
28 import javax.faces.component.UIData;
29 import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
30 import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
31 import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
32 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
33 import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTableRendererBase;
34 import org.apache.myfaces.shared_tomahawk.renderkit.html.util.ResourceUtils;
35 import org.apache.myfaces.shared_tomahawk.util.ArrayUtils;
36 import org.apache.myfaces.shared_tomahawk.util.StringUtils;
37
38 import java.io.IOException;
39 import java.util.Iterator;
40 import java.util.List;
41 import java.util.Map;
42
43 import org.apache.commons.logging.Log;
44 import org.apache.commons.logging.LogFactory;
45
46
47
48
49
50
51
52
53
54
55
56 public class HtmlNewspaperTableRenderer
57 extends HtmlTableRendererBase
58 {
59 private static final Log log = LogFactory.getLog(HtmlNewspaperTableRenderer.class);
60
61 public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException {
62 RendererUtils.checkParamValidity(facesContext, uiComponent, UIData.class);
63 ResponseWriter writer = facesContext.getResponseWriter();
64 HtmlNewspaperTable newspaperTable = (HtmlNewspaperTable)uiComponent;
65
66 Map<String, List<ClientBehavior>> behaviors = null;
67 if (uiComponent instanceof ClientBehaviorHolder)
68 {
69 behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
70 if (!behaviors.isEmpty())
71 {
72 ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, facesContext.getResponseWriter());
73 }
74 }
75
76
77 HtmlRendererUtils.writePrettyLineSeparator(facesContext);
78 writer.startElement(HTML.TABLE_ELEM, newspaperTable);
79 writer.writeAttribute(HTML.ID_ATTR, newspaperTable.getClientId(facesContext), null);
80
81 if (behaviors != null && !behaviors.isEmpty())
82 {
83 HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, newspaperTable, behaviors);
84 HtmlRendererUtils.renderHTMLAttributes(writer, newspaperTable, HTML.TABLE_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS);
85
86 }
87 else
88 {
89 HtmlRendererUtils.renderHTMLAttributes(writer, newspaperTable, HTML.TABLE_PASSTHROUGH_ATTRIBUTES);
90 }
91
92
93 renderFacet(facesContext, writer, newspaperTable, true);
94 }
95
96 public void encodeChildren(FacesContext facesContext, UIComponent uiComponent) throws IOException {
97 RendererUtils.checkParamValidity(facesContext, uiComponent, UIData.class);
98 ResponseWriter writer = facesContext.getResponseWriter();
99 HtmlNewspaperTable newspaperTable = (HtmlNewspaperTable)uiComponent;
100
101
102 HtmlRendererUtils.writePrettyLineSeparator(facesContext);
103 writer.startElement(HTML.TBODY_ELEM, newspaperTable);
104
105
106 Styles styles = getStyles(newspaperTable);
107
108
109 int first = newspaperTable.getFirst();
110 int rows = newspaperTable.getRows();
111 int rowCount = newspaperTable.getRowCount();
112 if(rows <= 0) {
113 rows = rowCount - first;
114 }
115 int last = first + rows;
116 if(last > rowCount) last = rowCount;
117
118
119 int newspaperColumns = newspaperTable.getNewspaperColumns();
120 int newspaperRows;
121 if((last - first) % newspaperColumns == 0) newspaperRows = (last - first) / newspaperColumns;
122 else newspaperRows = ((last - first) / newspaperColumns) + 1;
123
124
125 for(int nr = 0; nr < newspaperRows; nr++) {
126
127
128 HtmlRendererUtils.writePrettyLineSeparator(facesContext);
129 writer.startElement(HTML.TR_ELEM, newspaperTable);
130 if(styles.hasRowStyle()) {
131 String rowStyle = styles.getRowStyle(nr);
132 writer.writeAttribute(HTML.CLASS_ATTR, rowStyle, null);
133 }
134
135
136 for(int nc = 0; nc < newspaperColumns; nc++) {
137
138
139 int currentRow = nc * newspaperRows + nr + first;
140
141
142 if(currentRow >= last) continue;
143
144
145 newspaperTable.setRowIndex(currentRow);
146 if(!newspaperTable.isRowAvailable()) {
147 log.error("Row is not available. Rowindex = " + currentRow);
148 return;
149 }
150
151
152 List children = newspaperTable.getChildren();
153 for(int j = 0; j < newspaperTable.getChildCount(); j++) {
154
155 UIComponent child = (UIComponent)children.get(j);
156 if(!(child instanceof UIColumn)) continue;
157 if(!child.isRendered()) continue;
158
159 writer.startElement(HTML.TD_ELEM, newspaperTable);
160 if(styles.hasColumnStyle()) writer.writeAttribute(HTML.CLASS_ATTR, styles.getColumnStyle(nc * newspaperTable.getChildCount() + j), null);
161 RendererUtils.renderChild(facesContext, child);
162 writer.endElement(HTML.TD_ELEM);
163 }
164
165
166 if(nc < newspaperColumns - 1) renderSpacerCell(facesContext, writer, newspaperTable);
167 }
168
169 writer.endElement(HTML.TR_ELEM);
170 }
171
172
173 writer.endElement(HTML.TBODY_ELEM);
174 }
175
176
177
178
179 private int getNewspaperColumns() {
180 return 3;
181 }
182
183 public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException {
184 RendererUtils.checkParamValidity(facesContext, uiComponent, UIData.class);
185 ResponseWriter writer = facesContext.getResponseWriter();
186 HtmlNewspaperTable newspaperTable = (HtmlNewspaperTable)uiComponent;
187
188
189 renderFacet(facesContext, writer, newspaperTable, false);
190
191
192 writer.endElement(HTML.TABLE_ELEM);
193 HtmlRendererUtils.writePrettyLineSeparator(facesContext);
194 }
195
196
197
198
199
200 private int countColumns(HtmlNewspaperTable newspaperTable) {
201 int columnCount = 0;
202 for(Iterator it = newspaperTable.getChildren().iterator(); it.hasNext(); ) {
203 UIComponent uiComponent = (UIComponent)it.next();
204 if (uiComponent instanceof UIColumn && ((UIColumn)uiComponent).isRendered()) {
205 columnCount++;
206 }
207 }
208 return columnCount;
209 }
210
211
212
213
214 private boolean hasFacet(HtmlNewspaperTable newspaperTable, boolean header) {
215 for(Iterator it = newspaperTable.getChildren().iterator(); it.hasNext(); ) {
216
217 UIComponent uiComponent = (UIComponent)it.next();
218 if(!(uiComponent instanceof UIColumn)) continue;
219 UIColumn column = (UIColumn)uiComponent;
220 if(!column.isRendered()) continue;
221
222
223 if(header && ((UIColumn)uiComponent).getHeader() != null) return true;
224 if(!header && ((UIColumn)uiComponent).getFooter() != null) return true;
225 }
226 return false;
227 }
228
229
230
231
232 private void renderFacet(FacesContext facesContext, ResponseWriter writer, HtmlNewspaperTable newspaperTable, boolean header) throws IOException {
233 int columnCount = countColumns(newspaperTable);
234 boolean hasColumnFacet = hasFacet(newspaperTable, header);
235 UIComponent facet = header ? newspaperTable.getHeader() : newspaperTable.getFooter();
236
237
238 if(facet == null && !hasColumnFacet) return;
239
240
241 HtmlRendererUtils.writePrettyLineSeparator(facesContext);
242 String elemName = header ? HTML.THEAD_ELEM : HTML.TFOOT_ELEM;
243 writer.startElement(elemName, newspaperTable);
244
245
246 String styleClass;
247 if(header) styleClass = getHeaderClass(newspaperTable);
248 else styleClass = getFooterClass(newspaperTable);
249
250
251 if(header) {
252 if (facet != null) renderTableHeaderOrFooterRow(facesContext, writer, newspaperTable, facet, styleClass, HTML.TD_ELEM, columnCount);
253 if (hasColumnFacet) renderColumnHeaderOrFooterRow(facesContext, writer, newspaperTable, styleClass, header);
254
255 } else {
256 if (hasColumnFacet) renderColumnHeaderOrFooterRow(facesContext, writer, newspaperTable, styleClass, header);
257 if (facet != null) renderTableHeaderOrFooterRow(facesContext, writer, newspaperTable, facet, styleClass, HTML.TD_ELEM, columnCount);
258 }
259
260
261 writer.endElement(elemName);
262 }
263
264
265
266
267
268 private void renderTableHeaderOrFooterRow(FacesContext facesContext, ResponseWriter writer,
269 HtmlNewspaperTable newspaperTable, UIComponent facet, String styleClass, String colElementName, int tableColumns)
270 throws IOException {
271
272
273 HtmlRendererUtils.writePrettyLineSeparator(facesContext);
274 writer.startElement(HTML.TR_ELEM, newspaperTable);
275 writer.startElement(colElementName, newspaperTable);
276 if(styleClass != null) writer.writeAttribute(HTML.CLASS_ATTR, styleClass, null);
277 if(colElementName.equals(HTML.TH_ELEM)) writer.writeAttribute(HTML.SCOPE_ATTR, HTML.SCOPE_COLGROUP_VALUE, null);
278
279
280 int totalColumns = newspaperTable.getNewspaperColumns() * tableColumns;
281 if(newspaperTable.getSpacer() != null) totalColumns = totalColumns + getNewspaperColumns() - 1;
282 writer.writeAttribute(HTML.COLSPAN_ATTR, new Integer(totalColumns), null);
283
284
285 if(facet != null) RendererUtils.renderChild(facesContext, facet);
286
287
288 writer.endElement(colElementName);
289 writer.endElement(HTML.TR_ELEM);
290 }
291
292
293
294
295
296 private void renderColumnHeaderOrFooterRow(FacesContext facesContext,
297 ResponseWriter writer, HtmlNewspaperTable newspaperTable, String styleClass, boolean header)
298 throws IOException {
299
300 HtmlRendererUtils.writePrettyLineSeparator(facesContext);
301 writer.startElement(HTML.TR_ELEM, newspaperTable);
302 int newspaperColumns = newspaperTable.getNewspaperColumns();
303 for(int nc = 0; nc < newspaperColumns; nc++) {
304 for(Iterator it = newspaperTable.getChildren().iterator(); it.hasNext(); ) {
305 UIComponent uiComponent = (UIComponent)it.next();
306 if(!(uiComponent instanceof UIColumn)) continue;
307 UIColumn column = (UIColumn)uiComponent;
308 if(!column.isRendered()) continue;
309
310 UIComponent facet = null;
311 if(header) facet = column.getHeader();
312 else facet = column.getFooter();
313
314 renderColumnHeaderOrFooterCell(facesContext, writer, column, styleClass, facet);
315 }
316
317
318 if(nc < newspaperColumns - 1) renderSpacerCell(facesContext, writer, newspaperTable);
319 }
320 writer.endElement(HTML.TR_ELEM);
321 }
322
323
324
325
326 private void renderColumnHeaderOrFooterCell(FacesContext facesContext, ResponseWriter writer,
327 UIColumn uiColumn, String styleClass, UIComponent facet) throws IOException {
328
329 writer.startElement(HTML.TH_ELEM, uiColumn);
330 if(styleClass != null) writer.writeAttribute(HTML.CLASS_ATTR, styleClass, null);
331 if(facet != null) RendererUtils.renderChild(facesContext, facet);
332 writer.endElement(HTML.TH_ELEM);
333 }
334
335
336
337
338 private void renderSpacerCell(FacesContext facesContext, ResponseWriter writer,
339 HtmlNewspaperTable newspaperTable) throws IOException {
340 if(newspaperTable.getSpacer() == null) return;
341
342 writer.startElement(HTML.TD_ELEM, newspaperTable);
343 RendererUtils.renderChild(facesContext, newspaperTable.getSpacer());
344 writer.endElement(HTML.TD_ELEM);
345 }
346
347
348
349
350 private static String getHeaderClass(HtmlNewspaperTable newspaperTable) {
351 if(newspaperTable instanceof HtmlDataTable) {
352 return ((HtmlDataTable)newspaperTable).getHeaderClass();
353 } else {
354 return (String)newspaperTable.getAttributes().get(JSFAttr.HEADER_CLASS_ATTR);
355 }
356 }
357
358
359
360 private static String getFooterClass(HtmlNewspaperTable newspaperTable) {
361 if(newspaperTable instanceof HtmlDataTable) {
362 return ((HtmlDataTable)newspaperTable).getFooterClass();
363 } else {
364 return (String)newspaperTable.getAttributes().get(JSFAttr.FOOTER_CLASS_ATTR);
365 }
366 }
367
368
369
370
371 public static Styles getStyles(HtmlNewspaperTable newspaperTable) {
372 String rowClasses;
373 String columnClasses;
374 if(newspaperTable instanceof HtmlDataTable) {
375 rowClasses = ((HtmlDataTable)newspaperTable).getRowClasses();
376 columnClasses = ((HtmlDataTable)newspaperTable).getColumnClasses();
377 } else {
378 rowClasses = (String)newspaperTable.getAttributes().get(JSFAttr.ROW_CLASSES_ATTR);
379 columnClasses = (String)newspaperTable.getAttributes().get(JSFAttr.COLUMN_CLASSES_ATTR);
380 }
381 return new Styles(rowClasses, columnClasses);
382 }
383
384
385
386
387 private static class Styles {
388
389 private String[] _columnStyle;
390 private String[] _rowStyle;
391
392 Styles(String rowStyles, String columnStyles) {
393 _rowStyle = (rowStyles == null)
394 ? ArrayUtils.EMPTY_STRING_ARRAY
395 : StringUtils.trim(
396 StringUtils.splitShortString(rowStyles, ','));
397 _columnStyle = (columnStyles == null)
398 ? ArrayUtils.EMPTY_STRING_ARRAY
399 : StringUtils.trim(
400 StringUtils.splitShortString(columnStyles, ','));
401 }
402
403 public String getRowStyle(int idx) {
404 if(!hasRowStyle()) {
405 return null;
406 }
407 return _rowStyle[idx % _rowStyle.length];
408 }
409
410 public String getColumnStyle(int idx) {
411 if(!hasColumnStyle()) {
412 return null;
413 }
414 return _columnStyle[idx % _columnStyle.length];
415 }
416
417 public boolean hasRowStyle() {
418 return _rowStyle.length > 0;
419 }
420
421 public boolean hasColumnStyle() {
422 return _columnStyle.length > 0;
423 }
424 }
425 }