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