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