/*
* Copyright 2004 original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.extremecomponents.table.tag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import org.apache.commons.lang.StringUtils;
import org.extremecomponents.table.bean.Column;
import org.extremecomponents.table.core.TableModel;
import org.extremecomponents.table.core.TableModelUtils;
import org.extremecomponents.table.interceptor.ColumnInterceptor;
import org.extremecomponents.util.ExceptionUtils;
/**
* @author Jeff Johnston
* @jsp.tag name="column" display-name="ColumnTag" body-content="JSP"
* description="The container which holds all the column specific
* information. A copy of each column will be fed to the Model."
*/
public class ColumnTag extends BodyTagSupport implements ColumnInterceptor {
private String alias;
private String calc;
private String calcTitle;
private String cell;
private Object filterOptions;
private String filterable;
private String filterCell;
private String filterClass;
private String filterStyle;
private String format;
private String headerCell;
private String headerClass;
private String headerStyle;
private String interceptor;
private String parse;
private String property;
private String sortable;
private String style;
private String styleClass;
private String title;
private Object value;
private String viewsAllowed;
private String viewsDenied;
private String width;
private String escapeAutoFormat;
/**
* @jsp.attribute description="Used to uniquely identify the column when the
* same property is used for more than one column."
* required="false" rtexprvalue="true"
*/
public void setAlias(String alias) {
this.alias = alias;
}
/**
* @jsp.attribute description="A fully qualified class name to a
* custom Calc implementation. Could also be a named type
* in the preferences. Used to do math on a column."
* required="false" rtexprvalue="true"
*/
public void setCalc(String calc) {
this.calc = calc;
}
/**
* @jsp.attribute description="The title of the calc."
* required="false" rtexprvalue="true"
*/
public void setCalcTitle(String totalTitle) {
this.calcTitle = totalTitle;
}
/**
* @jsp.attribute description="Display for the column. The valid values are
* display, currency, rowCount, and date. The default value is
* display. The cell can also be a fully qualified class name
* to a custom Cell. Be sure to implement the Cell interface
* or extend AbstractCell if making a custom cell."
* required="false" rtexprvalue="true"
*/
public void setCell(String cell) {
this.cell = cell;
}
/**
* @jsp.attribute description="Specify whether auto format of value will be
* skipped. False by default, and is only effective if
* autoformatting is implement in the view."
* required="false" rtexprvalue="true"
*/
public void setEscapeAutoFormat(String escapeAutoFormat) {
this.escapeAutoFormat = escapeAutoFormat;
}
/**
* @jsp.attribute description="Specify whether or not the column should be
* filterable. Acceptable values are true or false. The default
* is to use the value for the table filterable attribute."
* required="false" rtexprvalue="true"
*/
public void setFilterable(String filterable) {
this.filterable = filterable;
}
/**
* @jsp.attribute description="Displays the filter column. The valid values
* are filter and droplist. The default is filter. The cell
* can also be a fully qualified class name to a custom
* cell." required="false" rtexprvalue="true"
*/
public void setFilterCell(String filterCell) {
this.filterCell = filterCell;
}
/**
* @jsp.attribute description="The css class style sheet used to define what
* the table filter column looks like." required="false"
* rtexprvalue="true"
*/
public void setFilterClass(String filterClass) {
this.filterClass = filterClass;
}
/**
* @jsp.attribute description="The object that contains the collection of elements
* that implement the Option interface."
* required="false" rtexprvalue="true"
*/
public void setFilterOptions(Object filterOptions) {
this.filterOptions = filterOptions;
}
/**
* @jsp.attribute description="The css class style sheet to use for the filter column."
* required="false" rtexprvalue="true"
*/
public void setFilterStyle(String filterStyle) {
this.filterStyle = filterStyle;
}
/**
* @jsp.attribute description="The format to use for the cell. For
* instance if used with a date cell then the format can be
* MM/dd/yyyy." required="false" rtexprvalue="true"
*/
public void setFormat(String format) {
this.format = format;
}
/**
* @jsp.attribute description="Display for the header column. The default is
* header. The cell can also be a fully qualified class name
* to a custom cell." required="false" rtexprvalue="true"
*/
public void setHeaderCell(String headerCell) {
this.headerCell = headerCell;
}
/**
* @jsp.attribute description="The css class style sheet used to define what
* the table header column looks like." required="false"
* rtexprvalue="true"
*/
public void setHeaderClass(String headerClass) {
this.headerClass = headerClass;
}
/**
* @jsp.attribute description="The css class style sheet to use for the header column."
* required="false" rtexprvalue="true"
*/
public void setHeaderStyle(String headerStyle) {
this.headerStyle = headerStyle;
}
/**
* @jsp.attribute description="A fully qualified class name to a custom
* InterceptColumn implementation. Could also be a named type
* in the preferences. Used to add or modify column attributes."
* required="false" rtexprvalue="true"
*/
public void setInterceptor(String interceptor) {
this.interceptor = interceptor;
}
/**
* @jsp.attribute description="Used if the format needs to be interpreted.
* For instance, a date needs to be parsed in the specific
* format, such as MM-dd-yyyy."
* required="false" rtexprvalue="true"
*/
public void setParse(String parse) {
this.parse = parse;
}
/**
* @jsp.attribute description="The bean attribute to use for the column."
* required="false" rtexprvalue="true"
*/
public void setProperty(String property) {
this.property = property;
}
/**
* @jsp.attribute description="Specify whether or not the column should be
* sortable. The acceptable values are true or false. The default
* is to use the value for the table sortable attribute."
* required="false" rtexprvalue="true"
*/
public void setSortable(String sortable) {
this.sortable = sortable;
}
/**
* @jsp.attribute description="The css inline style sheet." required="false"
* rtexprvalue="true"
*/
public void setStyle(String style) {
this.style = style;
}
/**
* @jsp.attribute description="The css class style sheet." required="false"
* rtexprvalue="true"
*/
public void setStyleClass(String styleClass) {
this.styleClass = styleClass;
}
/**
* @jsp.attribute description="The display for the table
* column header. If the title is not specified then it will
* default to the name of the property, changing the
* camelcase syntax to separate words." required="false"
* rtexprvalue="true"
*/
public void setTitle(String title) {
this.title = title;
}
/**
* @jsp.attribute description="The value for the column. If the value
* attribute is not specifed then it will be retrieved
* automatically using the property attribute. The value
* can also be defined within the column body."
* required="false" rtexprvalue="true"
*/
public void setValue(Object value) {
this.value = value;
}
/**
* @jsp.attribute description="The comma separated list of views that this
* column will be used in." required="false"
* rtexprvalue="true"
*/
public void setViewsAllowed(String viewsAllowed) {
this.viewsAllowed = viewsAllowed;
}
/**
* @jsp.attribute description="The comma separated list of views that this
* column will not be used in." required="false"
* rtexprvalue="true"
*/
public void setViewsDenied(String viewsDenied) {
this.viewsDenied = viewsDenied;
}
/**
* @jsp.attribute description="Specify the column width." required="false"
* rtexprvalue="true"
*/
public void setWidth(String width) {
this.width = width;
}
/**
* Get the value for the column. First look to see if it displayed in the
* body of the column. If it is not in the body, then use the value
* attribute. If the value attribute is not specified then use the property
* attribute to find the value in the bean. Note: Weblogic will always
* return a bodyContent so do additional checking.
*/
protected Object getColumnValue(Object propertyValue) throws JspException {
Object result = value;
if (result == null && bodyContent != null) {
result = getBodyContent().getString();
}
if (result != null) {
result = TagUtils.evaluateExpressionAsObject("result", result, pageContext);
}
if (result == null || (result != null && result instanceof String && StringUtils.isBlank(result.toString()))) {
result = propertyValue;
}
return result;
}
public int doStartTag() throws JspException {
try {
TableModel model = TagUtils.getModel(this);
ColumnTag parentTag = TagUtils.checkColumnParent(this);
boolean hasParent = parentTag != null;
Column parent = null;
if (hasParent) {
parent = model.getColumnHandler().getColumnByAlias(TableModelUtils.getAlias(parentTag.getAlias(), parentTag.getProperty()));
}
if (!TagUtils.isIteratingBody(this)) {
Column column = new Column(model);
column.setAlias(TagUtils.evaluateExpressionAsString("alias", this.alias, pageContext));
column.setCalc(TagUtils.evaluateExpressionAsString("calc", this.calc, pageContext));
column.setCalcTitle(TagUtils.evaluateExpressionAsString("calcTitle", calcTitle, pageContext));
column.setCell(TagUtils.evaluateExpressionAsString("cell", this.cell, pageContext));
column.setEscapeAutoFormat(TagUtils.evaluateExpressionAsBoolean("escapeAutoFormat", this.escapeAutoFormat, pageContext));
column.setFilterable(TagUtils.evaluateExpressionAsBoolean("filterable", this.filterable, pageContext));
column.setFilterCell(TagUtils.evaluateExpressionAsString("filterCell", this.filterCell, pageContext));
column.setFilterClass(TagUtils.evaluateExpressionAsString("filterClass", this.filterClass, pageContext));
column.setFilterOptions(TagUtils.evaluateExpressionAsObject("filterOptions", this.filterOptions, pageContext));
column.setFilterStyle(TagUtils.evaluateExpressionAsString("filterStyle", this.filterStyle, pageContext));
column.setFormat(TagUtils.evaluateExpressionAsString("format", this.format, pageContext));
column.setHeaderCell(TagUtils.evaluateExpressionAsString("headerCell", this.headerCell, pageContext));
column.setHeaderClass(TagUtils.evaluateExpressionAsString("headerClass", this.headerClass, pageContext));
column.setHeaderStyle(TagUtils.evaluateExpressionAsString("headerStyle", this.headerStyle, pageContext));
column.setInterceptor(TagUtils.evaluateExpressionAsString("interceptor", this.interceptor, pageContext));
column.setParse(TagUtils.evaluateExpressionAsString("parse", this.parse, pageContext));
column.setProperty(TagUtils.evaluateExpressionAsString("property", this.property, pageContext));
column.setSortable(TagUtils.evaluateExpressionAsBoolean("sortable", this.sortable, pageContext));
column.setStyle(TagUtils.evaluateExpressionAsString("style", this.style, pageContext));
column.setStyleClass(TagUtils.evaluateExpressionAsString("styleClass", this.styleClass, pageContext));
column.setTitle(TagUtils.evaluateExpressionAsString("title", this.title, pageContext));
column.setViewsAllowed(TagUtils.evaluateExpressionAsString("viewsToAllow", this.viewsAllowed, pageContext));
column.setViewsDenied(TagUtils.evaluateExpressionAsString("viewsToDeny", this.viewsDenied, pageContext));
column.setWidth(TagUtils.evaluateExpressionAsString("width", this.width, pageContext));
if (hasParent) column.setParent(parent);
addColumnAttributes(model, column);
model.getColumnHandler().addColumn(column);
}
} catch (Exception e) {
throw new JspException("ColumnTag.doEndTag() Problem: " + ExceptionUtils.formatStackTrace(e));
}
return EVAL_BODY_BUFFERED;
}
public String getAlias() {
return alias;
}
public String getProperty() {
return property;
}
/**
* Must make a copy of the column because this tag may be reused. Send the
* copy up to the Model.
*/
public int doEndTag() throws JspException {
try {
TableModel model = TagUtils.getModel(this);
if (TagUtils.isIteratingBody(this)) {
String alias = TagUtils.evaluateExpressionAsString("alias", this.alias, pageContext);
String property = TagUtils.evaluateExpressionAsString("property", this.property, pageContext);
Column column = model.getColumnHandler().getColumnByAlias(TableModelUtils.getAlias(alias, property));
if (column != null) { // null if view not allowed
if (column.getChildren() == null) {
Object bean = TagUtils.getModel(this).getCurrentRowBean();
Object propertyValue = TableModelUtils.getColumnPropertyValue(bean, property);
column.setValue(getColumnValue(propertyValue));
column.setPropertyValue(propertyValue);
modifyColumnAttributes(model, column);
model.getColumnHandler().modifyColumnAttributes(column);
model.getViewHandler().addColumnValueToView(column);
}
}
}
} catch (Exception e) {
throw new JspException("ColumnTag.doEndTag() Problem: " + ExceptionUtils.formatStackTrace(e));
}
return EVAL_PAGE;
}
public void addColumnAttributes(TableModel model, Column column) {
}
public void modifyColumnAttributes(TableModel model, Column column) {
}
public void release() {
alias = null;
calc = null;
calcTitle = null;
cell = null;
escapeAutoFormat = null;
filterable = null;
filterCell = null;
filterClass = null;
filterStyle = null;
format = null;
headerCell = null;
headerClass = null;
headerStyle = null;
interceptor = null;
parse = null;
property = null;
sortable = null;
style = null;
styleClass = null;
title = null;
value = null;
viewsAllowed = null;
viewsDenied = null;
width = null;
super.release();
}
}