org.richfaces.renderkit.AbstractTableBaseRenderer Maven / Gradle / Ivy
The newest version!
/*
* JBoss, Home of Professional Open Source
* Copyright ${year}, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.richfaces.renderkit;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import javax.faces.component.UIColumn;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import org.richfaces.component.Row;
import org.richfaces.component.UIDataTableBase;
/**
* @author Anton Belevich
*
*/
public abstract class AbstractTableBaseRenderer extends SortingFilteringRowsRenderer {
public static final String ROW_CLASS_KEY = "rowClass";
public static final String BREAK_ROW_BEFORE = "breakRowBefore";
public static final String COLUMN_CLASS = "userColumnClass";
public static final String ROW_CLASS = "userRowClass";
protected static final String FIRST_ROW_CLASS_KEY = "firstRowClass";
protected static final String CELL_CLASS_KEY = "cellClass";
private static final String CELL_ELEMENT_KEY = "cellElement";
public void encodeColumn(FacesContext context, ResponseWriter writer, UIColumn component, RowHolder rowHolder)
throws IOException {
String parentId = rowHolder.getParentClientId();
if (component instanceof org.richfaces.component.AbstractColumn) {
Map attributes = component.getAttributes();
if (Boolean.TRUE.equals(attributes.get(BREAK_ROW_BEFORE)) && rowHolder.getProcessCell() != 0) {
encodeRowEnd(writer);
rowHolder.nextRow();
rowHolder.setRowStart(true);
}
}
if (rowHolder.isRowStart()) {
int currentRow = rowHolder.getCurrentRow();
String[] rowClasses = getRowClasses(rowHolder);
if (rowClasses.length > 0) {
int indeStyleClass = currentRow % rowClasses.length;
String rowClass = rowClasses[indeStyleClass];
component.getAttributes().put(ROW_CLASS, rowClass);
}
if (rowHolder.getCurrentRow() == 0) {
encodeFirstRowStart(writer, context, parentId, currentRow, component);
} else {
encodeRowStart(writer, context, parentId, currentRow, component);
}
if (rowHolder.getRow() instanceof UIDataTableBase) {
renderRowHandlers(context, (UIDataTableBase) rowHolder.getRow());
}
rowHolder.setRowStart(false);
}
encodeColumnStart(writer, context, parentId, component);
renderChildren(context, component);
encodeColumnEnd(writer, context, parentId);
rowHolder.nextCell();
}
public void encodeColumnStart(ResponseWriter writer, FacesContext context, String parentId, UIComponent component)
throws IOException {
writer.startElement(getCellElement(context, parentId), component);
writer.writeAttribute(HtmlConstants.ID_ATTRIBUTE, component.getContainerClientId(context), HtmlConstants.ID_ATTRIBUTE);
String cellClass = getCellClass(context, parentId);
cellClass = concatClasses(cellClass, component.getAttributes().get(COLUMN_CLASS));
encodeStyleClass(writer, context, component, HtmlConstants.STYLE_CLASS_ATTR, cellClass);
encodeStyle(writer, context, component, null);
if (component instanceof org.richfaces.component.AbstractColumn) {
Map attributes = component.getAttributes();
Integer rowspan = (Integer) attributes.get(HtmlConstants.ROWSPAN_ATTRIBUTE);
if (rowspan != null && rowspan != Integer.MIN_VALUE) {
writer.writeAttribute(HtmlConstants.ROWSPAN_ATTRIBUTE, rowspan, null);
}
Integer colspan = (Integer) attributes.get(HtmlConstants.COLSPAN_ATTRIBUTE);
if (colspan != null && colspan != Integer.MIN_VALUE) {
writer.writeAttribute(HtmlConstants.COLSPAN_ATTRIBUTE, colspan, null);
}
}
}
public void encodeColumnEnd(ResponseWriter writer, FacesContext context, String parentId) throws IOException {
writer.endElement(getCellElement(context, parentId));
}
public void encodeFirstRowStart(ResponseWriter writer, FacesContext context, String parentId, int currentRow,
UIComponent component) throws IOException {
writer.startElement(HtmlConstants.TR_ELEMENT, component);
writer.writeAttribute(HtmlConstants.ID_ATTRIBUTE, parentId + ":" + currentRow, null);
String styleClass = concatClasses(getRowClass(context, parentId), getFirstRowClass(context, parentId), component
.getAttributes().get(ROW_CLASS));
if (styleClass.length() > 0) {
writer.writeAttribute(HtmlConstants.CLASS_ATTRIBUTE, styleClass, null);
}
}
public void encodeFirstRowEnd(ResponseWriter writer) throws IOException {
writer.endElement(HtmlConstants.TR_ELEMENT);
}
public void encodeRowStart(ResponseWriter writer, FacesContext context, String parentId, int currentRow,
UIComponent component) throws IOException {
writer.startElement(HtmlConstants.TR_ELEMENT, component);
writer.writeAttribute(HtmlConstants.ID_ATTRIBUTE, parentId + ":" + currentRow, null);
String styleClass = concatClasses(getRowClass(context, parentId), component.getAttributes().get(ROW_CLASS));
if (styleClass.length() > 0) {
writer.writeAttribute(HtmlConstants.CLASS_ATTRIBUTE, styleClass, null);
}
}
public void encodeRowEnd(ResponseWriter writer) throws IOException {
writer.endElement(HtmlConstants.TR_ELEMENT);
}
protected String getFirstRowClass(FacesContext context, String id) {
return get(context, id + FIRST_ROW_CLASS_KEY);
}
protected String getRowClass(FacesContext context, String id) {
return get(context, id + ROW_CLASS_KEY);
}
protected String getCellClass(FacesContext context, String id) {
return get(context, id + CELL_CLASS_KEY);
}
protected String getCellElement(FacesContext context, String id) {
String elementName = get(context, id + CELL_ELEMENT_KEY);
if (elementName == null) {
elementName = HtmlConstants.TD_ELEM;
}
return elementName;
}
protected void setCellElement(FacesContext context, String id, String element) {
put(context, id + CELL_ELEMENT_KEY, element);
}
protected void saveRowStyles(FacesContext context, String id, String firstRowClass, String rowClass, String cellClass) {
put(context, id + FIRST_ROW_CLASS_KEY, firstRowClass);
put(context, id + ROW_CLASS_KEY, rowClass);
put(context, id + CELL_CLASS_KEY, cellClass);
}
public void encodeStyleClass(ResponseWriter writer, FacesContext context, UIComponent component,
String styleClassAttribute, String styleClass) throws IOException {
boolean isEmpty = isEmptyAttr(component, styleClassAttribute);
if (isEmpty && !(styleClass != null && styleClass.trim().length() != 0)) {
return;
}
String componentStyleClass = isEmpty ? styleClass : styleClass + " "
+ component.getAttributes().get(styleClassAttribute);
writer.writeAttribute(HtmlConstants.CLASS_ATTRIBUTE, componentStyleClass, null);
}
protected boolean isEmptyAttr(UIComponent component, String attribute) {
if (attribute == null) {
return true;
}
String value = (String) component.getAttributes().get(attribute);
return !(value != null && value.trim().length() != 0);
}
protected void encodeStyle(ResponseWriter writer, FacesContext context, UIComponent component, String predefinedStyles)
throws IOException {
StringBuffer toEncode = new StringBuffer();
if (!isEmptyAttr(component, HtmlConstants.STYLE_ATTRIBUTE)) {
String style = ((String) component.getAttributes().get(HtmlConstants.STYLE_ATTRIBUTE)).trim();
style = style.endsWith(";") ? style : style + ";";
toEncode.append(style);
}
if (!isEmpty(predefinedStyles)) {
String style = predefinedStyles.endsWith(";") ? predefinedStyles : predefinedStyles + ";";
toEncode.append(style);
}
if (toEncode.length() > 0) {
writer.writeAttribute(HtmlConstants.STYLE_ATTRIBUTE, toEncode.toString(), null);
}
}
protected boolean isEmpty(String style) {
return !((style != null) && (style.trim().length() != 0));
}
protected int getColumnsCount(Iterator col) {
int count = 0;
int currentLength = 0;
while (col.hasNext()) {
UIComponent component = (UIComponent) col.next();
if (component.isRendered()) {
if (component instanceof Row) {
// Store max calculated value of previsous rows.
if (currentLength > count) {
count = currentLength;
}
// Calculate number of columns in row.
currentLength = getColumnsCount(((Row) component).columns());
// Store max calculated value
if (currentLength > count) {
count = currentLength;
}
currentLength = 0;
} else if (component instanceof org.richfaces.component.AbstractColumn) {
// For new row, save length of previsous.
Map attributes = component.getAttributes();
if (Boolean.TRUE.equals(attributes.get(BREAK_ROW_BEFORE))) {
if (currentLength > count) {
count = currentLength;
}
currentLength = 0;
}
Integer colspan = (Integer) attributes.get(HtmlConstants.COLSPAN_ATTRIBUTE);
// Append colspan of this column
if (null != colspan && colspan.intValue() != Integer.MIN_VALUE) {
currentLength += colspan.intValue();
} else {
currentLength++;
}
} else if (component instanceof UIColumn) {
// UIColumn always have colspan == 1.
currentLength++;
}
}
}
if (currentLength > count) {
count = currentLength;
}
return count;
}
@Override
public void encodeFakeRow(FacesContext facesContext, RowHolderBase rowHolder) throws IOException {
UIComponent component = (UIComponent) rowHolder.getRow();
ResponseWriter writer = facesContext.getResponseWriter();
writer.startElement(HtmlConstants.TR_ELEMENT, component);
writer.writeAttribute(HtmlConstants.STYLE_ATTRIBUTE, "display:none", null);
writer.startElement(HtmlConstants.TD_ELEM, component);
writer.endElement(HtmlConstants.TD_ELEM);
writer.endElement(HtmlConstants.TR_ELEMENT);
}
}