/* * RHQ Management Platform * Copyright (C) 2005-2008 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /** * Todo: - provide filters in some way? Instead of just getting some bit of data also provide a way to feed that data * through some other object that will reformat it in some way (like converting dates to another format) - update * documentation, HTML column attributes are not set. - specify groupings. - error checking, value or property must be * set. */ package org.rhq.enterprise.gui.legacy.taglib.display; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.BodyTagSupport; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * This tag works hand in hand with the SmartListTag to display a list of objects. This describes a column of data in * the SmartListTag. There can be any (reasonable) number of columns that make up the list. * * <p>This tag does no work itself, it is simply a container of information. The TableTag does all the work based on the * information provided in the attributes of this tag. * * <p>Usage: * * <p><display:column property="title" title="College Title" width="33%" href="/osiris/pubs/college/edit.page" * paramId="OID" paramProperty="OID" /> Attributes: * * <p>property - the property method that is called to retrieve the information to be displayed in this column. This * method is called on the current object in the iteration for the given row. The property format is in typical struts * format for properties (required) showHideProperty - the property that is called to retrieve the information to be * displayed as a hidden layer. The data in this property will be displayed beneath the data specified in the property * field when the show/hide buttons are manipulated. title - the title displayed for this column. if this is omitted * then the property name is used for the title of the column (optional) nulls - by default, null values don't appear in * the list, by setting viewNulls to 'true', then null values will appear as "null" in the list (mostly useful for * debugging) (optional) width - the width of the column (gets passed along to the html td tag). (optional) group - the * grouping level (starting at 1 and incrementing) of this column (indicates if successive contain the same values, then * they should not be displayed). The level indicates that if a lower level no longer matches, then the matching for * this higher level should start over as well. If this attribute is not included, then no grouping is performed. * (optional) decorator - a class that should be used to "decorate" the underlying object being displayed. If a * decorator is specified for the entire table, then this decorator will decorate that decorator. (optional) autolink - * if set to true, then any email addresses and URLs found in the content of the column are automatically converted into * a hypertext link. href - if this attribute is provided, then the data that is shown for this column is wrapped inside * a <a href>tag with the url provided through this attribute. Typically you would use this attribute along with one of * the struts-like param attributes below to create a dynamic link so that each row creates a different URL based on the * data that is being viewed. (optional) paramId - The name of the request parameter that will be dynamically added to * the generated href URL. The corresponding value is defined by the paramProperty and (optional) paramName attributes, * optionally scoped by the paramScope attribute. (optional) paramName - The name of a JSP bean that is a String * containing the value for the request parameter named by paramId (if paramProperty is not specified), or a JSP bean * whose property getter is called to return a String (if paramProperty is specified). The JSP bean is constrained to * the bean scope specified by the paramScope property, if it is specified. If paramName is omitted, then it is assumed * that the current object being iterated on is the target bean. (optional) paramProperty - The name of a property of * the bean specified by the paramName attribute (or the current object being iterated on if paramName is not provided), * whose return value must be a String containing the value of the request parameter (named by the paramId attribute) * that will be dynamically added to this href URL. (optional) paramScope - The scope within which to search for the * bean specified by the paramName attribute. If not specified, all scopes are searched. If paramName is not provided, * then the current object being iterated on is assumed to be the target bean. (optional) maxLength - If this attribute * is provided, then the column's displayed is limited to this number of characters. An elipse (...) is appended to the * end if this column is linked, and the user can mouseover the elipse to get the full text. (optional) maxWords - If * this attribute is provided, then the column's displayed is limited to this number of words. An elipse (...) is * appended to the end if this column is linked, and the user can mouseover the elipse to get the full text. (optional) */ public class ColumnTag extends BodyTagSupport implements Cloneable { private final Log log = LogFactory.getLog(ColumnTag.class.getName()); private String property; private String showHideProperty; private String title; private String nulls; private String sort; private String autolink; private String group; private boolean isShowHideColumn; private String href; private String paramId; private String paramName; private String paramProperty; private String paramScope; private int maxLength; private int maxWords; private String width; private String align; private String background; private String bgcolor; private String height; private String nowrap; private String valign; private String clazz; private String headerClazz; private String onClick; private Object value; private String doubleQuote; private ColumnDecorator decorator; // -------------------------------------------------------- Accessor methods public void setProperty(String v) { this.property = v; } public String getOnClick() { return onClick; } public void setOnClick(String onClick) { this.onClick = onClick; } public void setShowHideProperty(String v) { this.showHideProperty = v; } public void setTitle(String v) { this.title = v; } public void setNulls(String v) { this.nulls = v; } public void setSort(String v) { this.sort = v; } public void setAutolink(String v) { this.autolink = v; } public void setGroup(String v) { this.group = v; } public void setIsShowHideColumn(boolean v) { this.isShowHideColumn = v; } public void setHref(String v) { this.href = v; } public void setParamId(String v) { this.paramId = v; } public void setParamName(String v) { this.paramName = v; } public void setParamProperty(String v) { this.paramProperty = v; } public void setParamScope(String v) { this.paramScope = v; } public void setMaxLength(int v) { this.maxLength = v; } public void setMaxWords(int v) { this.maxWords = v; } public void setWidth(String v) { this.width = v; } public void setAlign(String v) { this.align = v; } public void setBackground(String v) { this.background = v; } public void setBgcolor(String v) { this.bgcolor = v; } public void setHeight(String v) { this.height = v; } public void setNowrap(String v) { this.nowrap = v; } public void setValign(String v) { this.valign = v; } public void setStyleClass(String v) { this.clazz = v; } public void setHeaderStyleClass(String v) { this.headerClazz = v; } public void setValue(Object v) { this.value = v; } public void setDoubleQuote(String v) { this.doubleQuote = v; } public void setDecorator(ColumnDecorator v) { this.decorator = v; } public String getProperty() { return this.property; } public String getShowHideProperty() { return this.showHideProperty; } public String getTitle() { return this.title; } public String getNulls() { return this.nulls; } public String getSort() { return this.sort; } public String getAutolink() { return this.autolink; } public String getGroup() { return this.group; } public boolean getIsShowHideColumn() { return this.isShowHideColumn; } public String getHref() { return this.href; } public String getParamId() { return this.paramId; } public String getParamName() { return this.paramName; } public String getParamProperty() { return this.paramProperty; } public String getParamScope() { return this.paramScope; } public int getMaxLength() { return this.maxLength; } public int getMaxWords() { return this.maxWords; } public String getWidth() { return this.width; } public String getAlign() { return this.align; } public String getBackground() { return this.background; } public String getBgcolor() { return this.bgcolor; } public String getHeight() { return this.height; } public String getNowrap() { return this.nowrap; } public String getValign() { return this.valign; } public String getStyleClass() { return this.clazz; } public String getHeaderStyleClass() { return this.headerClazz; } public Object getValue() { return this.value; } public String getDoubleQuote() { return this.doubleQuote; } public ColumnDecorator getDecorator() { return this.decorator; } public String getDecoratorClass() { return this.decorator.getClass().getName(); } public void setDecoratorClass(String decoratorClass) throws JspException { try { setDecorator((ColumnDecorator) Class.forName(decoratorClass).newInstance()); } catch (Exception e) { throw new JspException(e); } } // --------------------------------------------------------- Tag API methods /** * Passes attribute information up to the parent TableTag. * * <p>When we hit the end of the tag, we simply let our parent (which better be a TableTag) know what the user wants * to do with this column. We do that by simple registering this tag with the parent. This tag's only job is to hold * the configuration information to describe this particular column. The TableTag does all the work. * * @throws JspException if this tag is being used outside of a <display:list...> tag. */ @Override public int doEndTag() throws JspException { Class clazz = TableTag.class; Object parent = findAncestorWithClass(this, clazz); if (parent == null) { throw new JspException("Can not use column tag outside of a " + "TableTag. Invalid parent = null"); } if (!(parent instanceof TableTag)) { throw new JspException("Can not use column tag outside of a " + "TableTag. Invalid parent = " + parent.getClass().getName()); } // Need to clone the ColumnTag before passing it to the TableTag as // the ColumnTags can be reused by some containers, and since we are // using the ColumnTags as basically containers of data, we need to // save the original values, and not the values that are being changed // as the tag is being reused... ColumnTag copy; try { copy = (ColumnTag) this.clone(); } catch (CloneNotSupportedException e) { log.debug("clone exception ", e); throw new JspException("could not clone: ", e); } this.release(); ((TableTag) parent).addColumn(copy); return super.doEndTag(); } @Override public int doStartTag() throws JspException { return (EVAL_BODY_INCLUDE); } /** * called by the jsp framework to release state. */ @Override public void release() { decorator = null; super.release(); } /** * Takes all the column pass-through arguments and bundles them up as a string that gets tacked on to the end of the * td tag declaration. * * @return the td tag attributes * @throws JspException */ protected String getCellAttributes() throws JspException { StringBuffer results = new StringBuffer(); if (this.clazz != null) { results.append(" class=\""); results.append(this.clazz); results.append("\""); } else { results.append(" class=\"tableCell\""); } if (this.width != null) { results.append(" width=\""); results.append(this.width); results.append("\""); } if (this.align != null) { results.append(" align=\""); results.append(this.align); results.append("\""); } else { results.append(" align=\"left\""); } if (this.background != null) { results.append(" background=\""); results.append(this.background); results.append("\""); } if (this.bgcolor != null) { results.append(" bgcolor=\""); results.append(this.bgcolor); results.append("\""); } if (this.height != null) { results.append(" height=\""); results.append(this.height); results.append("\""); } if (this.nowrap != null) { results.append(" nowrap"); } if (this.valign != null) { results.append(" valign=\""); results.append(this.valign); results.append("\""); } else { results.append(" valign=\"top\""); } if (this.onClick != null) { results.append(" onclick=\""); // TableTag tt = (TableTag) getParent(); // int i = onClick.indexOf("_property:"); // if (i >= 0) { // int pos = onClick.indexOf(":", i); // int pos2 = onClick.indexOf(":", pos + 1); // // TODO add some error checking // String prop = onClick.substring(pos + 1, pos2); // Object o = tt.lookup(pageContext, "smartRow", prop, null, true); // String rep = o.toString(); // oc = onClick.replace("_property:" + prop + ":", rep); // results.append(oc); // } else { // results.append(onClick); // } results.append(replacePropertyIfPossible(onClick, pageContext)); results.append("\""); } return results.toString(); } public String replacePropertyIfPossible(String input, PageContext pageContext) { int i = input.indexOf("_property:"); if (i >= 0) { String oc = input; TableTag tt = (TableTag) getParent(); int pos = input.indexOf(":", i); int pos2 = input.indexOf(":", pos + 1); // TODO add some error checking String prop = input.substring(pos + 1, pos2); String rep; try { Object o = tt.lookup(pageContext, "smartRow", prop, null, true); rep = o.toString(); oc = input.replace("_property:" + prop + ":", rep); } catch (JspException e) { log.warn("Can't replace the _property on " + input + ": " + e.getMessage()); } return oc; } else return input; } /** * Returns a String representation of this Tag that is suitable for printing while debugging. Where the placeholders * in brackets are replaced with their appropriate instance variables */ @Override public String toString() { StringBuffer sb = new StringBuffer("ColumnTag("); sb.append("title=").append(title); sb.append(",property=").append(property); sb.append(",href=").append(href); sb.append(",decorator=").append(decorator); sb.append(")"); return sb.toString(); } }