001: /*
002: * Copyright 2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.myfaces.shared_impl.renderkit.html;
017:
018: import org.apache.commons.logging.Log;
019: import org.apache.commons.logging.LogFactory;
020: import org.apache.myfaces.shared_impl.renderkit.JSFAttr;
021: import org.apache.myfaces.shared_impl.renderkit.RendererUtils;
022: import org.apache.myfaces.shared_impl.util.ArrayUtils;
023: import org.apache.myfaces.shared_impl.util.StringUtils;
024:
025: import javax.faces.component.UIComponent;
026: import javax.faces.component.UIPanel;
027: import javax.faces.component.html.HtmlPanelGrid;
028: import javax.faces.context.FacesContext;
029: import javax.faces.context.ResponseWriter;
030: import java.io.IOException;
031: import java.util.Iterator;
032:
033: /**
034: * @author Martin Marinschek
035: * @version $Revision: 533392 $ $Date: 2007-04-28 19:03:51 +0200 (Sa, 28 Apr 2007) $
036: * <p/>
037: * $Log: $
038: */
039: public class HtmlGridRendererBase extends HtmlRenderer {
040: private static final Log log = LogFactory
041: .getLog(HtmlGridRendererBase.class);
042:
043: public boolean getRendersChildren() {
044: return true;
045: }
046:
047: public void encodeBegin(FacesContext facesContext,
048: UIComponent component) throws IOException {
049: // all work done in encodeEnd()
050: }
051:
052: public void encodeChildren(FacesContext context,
053: UIComponent component) throws IOException {
054: // all work done in encodeEnd()
055: }
056:
057: public void encodeEnd(FacesContext facesContext,
058: UIComponent component) throws IOException {
059: RendererUtils.checkParamValidity(facesContext, component,
060: UIPanel.class);
061:
062: int columns;
063: if (component instanceof HtmlPanelGrid) {
064: columns = ((HtmlPanelGrid) component).getColumns();
065: } else {
066: Integer i = (Integer) component
067: .getAttributes()
068: .get(
069: org.apache.myfaces.shared_impl.renderkit.JSFAttr.COLUMNS_ATTR);
070: columns = i != null ? i.intValue() : 0;
071: }
072:
073: if (columns <= 0) {
074: if (log.isErrorEnabled()) {
075: log.error("Wrong columns attribute for PanelGrid "
076: + component.getClientId(facesContext) + ": "
077: + columns);
078: }
079: columns = 1;
080: }
081:
082: ResponseWriter writer = facesContext.getResponseWriter();
083: writer.startElement(HTML.TABLE_ELEM, component);
084: HtmlRendererUtils.writeIdIfNecessary(writer, component,
085: facesContext);
086: HtmlRendererUtils.renderHTMLAttributes(writer, component,
087: HTML.TABLE_PASSTHROUGH_ATTRIBUTES);
088:
089: writer.flush();
090:
091: HtmlRendererUtils.renderTableCaption(facesContext, writer,
092: component);
093:
094: // theader and tfooter are rendered before the tbody
095: renderHeaderOrFooter(facesContext, writer, component, columns,
096: true); //Header facet
097: renderHeaderOrFooter(facesContext, writer, component, columns,
098: false); //Footer facet
099:
100: renderChildren(facesContext, writer, component, columns);
101:
102: writer.endElement(HTML.TABLE_ELEM);
103: }
104:
105: protected void renderHeaderOrFooter(FacesContext context,
106: ResponseWriter writer, UIComponent component, int columns,
107: boolean header) throws IOException {
108: UIComponent facet = component.getFacet(header ? "header"
109: : "footer");
110: if (facet == null)
111: return;
112:
113: HtmlRendererUtils.writePrettyLineSeparator(context);
114: writer
115: .startElement(
116: header ? org.apache.myfaces.shared_impl.renderkit.html.HTML.THEAD_ELEM
117: : HTML.TFOOT_ELEM, component);
118: writer.startElement(HTML.TR_ELEM, component);
119: writer.startElement(header ? HTML.TH_ELEM : HTML.TD_ELEM,
120: component);
121:
122: String styleClass = (component instanceof HtmlPanelGrid) ? (header ? ((HtmlPanelGrid) component)
123: .getHeaderClass()
124: : ((HtmlPanelGrid) component).getFooterClass())
125: : (header ? (String) component.getAttributes().get(
126: JSFAttr.HEADER_CLASS_ATTR)
127: : (String) component
128: .getAttributes()
129: .get(
130: org.apache.myfaces.shared_impl.renderkit.JSFAttr.FOOTER_CLASS_ATTR));
131: if (styleClass != null) {
132: writer
133: .writeAttribute(
134: HTML.CLASS_ATTR,
135: styleClass,
136: header ? JSFAttr.HEADER_CLASS_ATTR
137: : org.apache.myfaces.shared_impl.renderkit.JSFAttr.FOOTER_CLASS_ATTR);
138: }
139:
140: if (header) {
141: writer.writeAttribute(HTML.SCOPE_ATTR,
142: HTML.SCOPE_COLGROUP_VALUE, null);
143: }
144:
145: writer.writeAttribute(HTML.COLSPAN_ATTR, Integer
146: .toString(columns), null);
147:
148: HtmlRendererUtils.writePrettyLineSeparator(context);
149: RendererUtils.renderChild(context, facet);
150:
151: HtmlRendererUtils.writePrettyLineSeparator(context);
152: writer.endElement(header ? HTML.TH_ELEM : HTML.TD_ELEM);
153: writer.endElement(HTML.TR_ELEM);
154: writer.endElement(header ? HTML.THEAD_ELEM : HTML.TFOOT_ELEM);
155: }
156:
157: protected void renderChildren(FacesContext context,
158: ResponseWriter writer, UIComponent component, int columns)
159: throws IOException {
160: writer.startElement(HTML.TBODY_ELEM, component);
161:
162: String columnClasses;
163: String rowClasses;
164: if (component instanceof HtmlPanelGrid) {
165: columnClasses = ((HtmlPanelGrid) component)
166: .getColumnClasses();
167: rowClasses = ((HtmlPanelGrid) component).getRowClasses();
168: } else {
169: columnClasses = (String) component
170: .getAttributes()
171: .get(
172: org.apache.myfaces.shared_impl.renderkit.JSFAttr.COLUMN_CLASSES_ATTR);
173: rowClasses = (String) component.getAttributes().get(
174: JSFAttr.ROW_CLASSES_ATTR);
175: }
176:
177: String[] columnClassesArray = (columnClasses == null) ? ArrayUtils.EMPTY_STRING_ARRAY
178: : StringUtils.trim(StringUtils.splitShortString(
179: columnClasses, ','));
180: int columnClassesCount = columnClassesArray.length;
181:
182: String[] rowClassesArray = (rowClasses == null) ? org.apache.myfaces.shared_impl.util.ArrayUtils.EMPTY_STRING_ARRAY
183: : StringUtils.trim(StringUtils.splitShortString(
184: rowClasses, ','));
185: int rowClassesCount = rowClassesArray.length;
186:
187: int childCount = getChildCount(component);
188: if (childCount > 0) {
189: int columnIndex = 0;
190: int rowClassIndex = 0;
191: boolean rowStarted = false;
192: for (Iterator it = getChildren(component).iterator(); it
193: .hasNext();) {
194: UIComponent child = (UIComponent) it.next();
195: if (child.isRendered()) {
196: if (columnIndex == 0) {
197: //start of new/next row
198: if (rowStarted) {
199: //do we have to close the last row?
200: writer.endElement(HTML.TR_ELEM);
201: HtmlRendererUtils
202: .writePrettyLineSeparator(context);
203: }
204: writer.startElement(HTML.TR_ELEM, component);
205: if (rowClassIndex < rowClassesCount) {
206: writer.writeAttribute(HTML.CLASS_ATTR,
207: rowClassesArray[rowClassIndex],
208: null);
209: }
210: rowStarted = true;
211: rowClassIndex++;
212: if (rowClassIndex == rowClassesCount) {
213: rowClassIndex = 0;
214: }
215: }
216:
217: writer.startElement(HTML.TD_ELEM, component);
218: if (columnIndex < columnClassesCount) {
219: writer.writeAttribute(HTML.CLASS_ATTR,
220: columnClassesArray[columnIndex], null);
221: }
222: RendererUtils.renderChild(context, child);
223: writer.endElement(HTML.TD_ELEM);
224:
225: columnIndex++;
226: if (columnIndex >= columns) {
227: columnIndex = 0;
228: }
229: }
230: }
231:
232: if (rowStarted) {
233: if (columnIndex > 0) {
234: if (log.isWarnEnabled())
235: log
236: .warn("PanelGrid "
237: + component
238: .getClientId(context)
239: + " has not enough children. Child count should be a multiple of the columns attribute.");
240: //Render empty columns, so that table is correct
241: for (; columnIndex < columns; columnIndex++) {
242: writer.startElement(HTML.TD_ELEM, component);
243: if (columnIndex < columnClassesCount) {
244: writer.writeAttribute(HTML.CLASS_ATTR,
245: columnClassesArray[columnIndex],
246: null);
247: }
248: writer.endElement(HTML.TD_ELEM);
249: }
250: }
251: writer.endElement(HTML.TR_ELEM);
252: HtmlRendererUtils.writePrettyLineSeparator(context);
253: }
254: }
255:
256: writer.endElement(HTML.TBODY_ELEM);
257: }
258:
259: }
|