/*
* 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.
*/
package org.rhq.enterprise.gui.legacy.taglib;
import org.rhq.core.domain.measurement.MeasurementUnits;
import org.rhq.core.server.MeasurementConverter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.util.RequestUtils;
import org.apache.taglibs.standard.tag.el.core.ExpressionUtil;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.Locale;
/**
* This is a locale aware tag for displaying metrics and units. Suppose you have a metricDisplaySummary.setMin(9234289)
* and metricDisplaySummary.setUnit("bytes") set in the bean, this tag allows you to say: <spider:metric
* metric="${metricDisplaySummary.min}" unit="${metricDisplaySummary.unit}" /> and get this output: <span>9,018
* KB</span> This class assumes that any re-scaling of the metric value and unit string as well as any localization of
* the unit string was performed prior to the data being parameterized for this tag. To assure that the locale of the
* unit string agrees with the locale of the metric, use the jakarta-struts key org.apache.struts.Globals.LOCALE_KEY
*/
public class MetricDisplayTag extends TagSupport {
private static final String TAG_NAME = "metric";
public static Log log = LogFactory.getLog(MetricDisplayTag.class.getName());
private Double metricVal;
private String unitVal;
private String spanVal;
private String defaultKeyVal;
// tag attributes
private String metric_el;
private String unit_el;
private String span_el;
private String longDate_el;
private String defaultKey_el;
// internal bookkeeping attributes
private boolean metricIsSet = false;
private boolean unitIsSet = false;
private boolean spanIsSet = false;
private boolean defaultKeyIsSet = false;
protected String locale = org.apache.struts.Globals.LOCALE_KEY;
protected String bundle = org.apache.struts.Globals.MESSAGES_KEY;
/* (non-Javadoc)
* @see javax.servlet.jsp.tagext.Tag#doEndTag()
*/
@Override
public int doEndTag() throws JspException {
Locale userLocale = RequestUtils.retrieveUserLocale(pageContext, locale);
if (unitIsSet) {
setUnitVal((String) evalAttr("unit", unit_el, String.class));
}
if (defaultKeyIsSet) {
setDefaultKeyVal((String) evalAttr("defaultKey", defaultKey_el, String.class));
}
// if the metric value is empty, converting to a Double will
// give a value of 0.0. this makes it impossible for us to
// distinguish further down the line whether the metric was
// actually collected with a value of 0.0 or whether it was
// not collected at all. therefore, we'll let metricVal be
// null if the metric was not collected, and we'll check for
// null later when handling the not-avail case.
// PR: 7588
String mval = (String) evalAttr("metric", metric_el, String.class);
if ((mval != null) && !mval.equals("")) {
setMetricVal(new Double(mval));
}
StringBuffer sb = new StringBuffer("<span");
if (spanIsSet && (getSpan().length() > 0)) {
setSpanVal((String) evalAttr("span", span_el, String.class));
sb.append(" class=\"");
sb.append(getSpanVal());
sb.append("\"");
}
sb.append(">");
if ((getMetricVal() == null) || (Double.isNaN(getMetricVal().doubleValue()) && defaultKeyIsSet)) {
sb.append(RequestUtils.message(pageContext, bundle, userLocale.toString(), getDefaultKeyVal()));
}
// XXXX remove duplication with the metric decorator
// and the UnitsConvert/UnitsFormat stuff
else if (getUnitVal().equals("ms")) {
NumberFormat f = NumberFormat.getNumberInstance(userLocale);
f.setMinimumFractionDigits(3);
f.setMaximumFractionDigits(3);
String formatted = f.format(getMetricVal().doubleValue() / 1000);
String[] args = new String[] { formatted };
sb.append(RequestUtils.message(pageContext, bundle, userLocale.toString(), "metric.tag.units.s.arg", args));
} else {
MeasurementUnits units = MeasurementUnits.valueOf(getUnitVal());
Double dataValue = getMetricVal();
String formattedValue = MeasurementConverter.format(dataValue, units, true);
sb.append(formattedValue);
}
sb.append("</span>");
try {
pageContext.getOut().print(sb.toString());
} catch (IOException e) {
log.debug("could not write output: ", e);
throw new JspException("Could not access metrics tag");
}
release();
return EVAL_PAGE;
}
public void validate() throws JspException {
}
/* (non-Javadoc)
* @see javax.servlet.jsp.tagext.Tag#release()
*/
@Override
public void release() {
super.release();
metric_el = null;
unit_el = null;
span_el = null;
defaultKey_el = null;
metricVal = null;
unitVal = null;
spanVal = null;
defaultKeyVal = null;
metricIsSet = false;
unitIsSet = false;
spanIsSet = false;
defaultKeyIsSet = false;
}
/* (non-Javadoc)
* @see javax.servlet.jsp.tagext.Tag#doStartTag()
*/
@Override
public int doStartTag() throws JspException {
validate();
return super.doStartTag();
}
/**
* Returns the metric.
*
* @return String
*/
public String getMetric() {
return metric_el;
}
/**
* Sets the metric.
*
* @param metric The metric to set
*/
public void setMetric(String metric) {
metricIsSet = true;
this.metric_el = metric;
}
/**
* Returns the span.
*
* @return String
*/
public String getSpan() {
return span_el;
}
/**
* Sets the defaultKey.
*
* @param defaultKey The defaultKey to set
*/
public void setDefaultKey(String defaultKey) {
defaultKeyIsSet = true;
this.defaultKey_el = defaultKey;
}
/**
* Returns the defaultKey.
*
* @return String
*/
public String getDefaultKey() {
return defaultKey_el;
}
/**
* Sets the span.
*
* @param span The span to set
*/
public void setSpan(String span) {
spanIsSet = true;
this.span_el = span;
}
/**
* Returns the unit.
*
* @return String
*/
public String getUnit() {
return unit_el;
}
/**
* @param longDate
*/
public void setLongDate(String longDate) {
this.longDate_el = longDate;
}
/**
* Returns the flag for whether or not the metric is a long/date
*
* @return String
*/
public String getLongDate() {
return longDate_el;
}
/**
* Sets the unit.
*
* @param unit The unit to set
*/
public void setUnit(String unit) {
unitIsSet = true;
this.unit_el = unit;
}
// private stuph
private Object evalAttr(String attributeName, String expression, Class expectedType) throws JspException {
return ExpressionUtil.evalNotNull(TAG_NAME, attributeName, expression, expectedType, this, pageContext);
}
private Double getMetricVal() {
return metricVal;
}
private String getSpanVal() {
return spanVal;
}
private String getDefaultKeyVal() {
return defaultKeyVal;
}
private String getUnitVal() {
return unitVal;
}
private void setMetricVal(Double metricVal) {
this.metricVal = metricVal;
}
private void setSpanVal(String spanVal) {
this.spanVal = spanVal;
}
private void setDefaultKeyVal(String defaultKeyVal) {
this.defaultKeyVal = defaultKeyVal;
}
private void setUnitVal(String unitVal) {
this.unitVal = unitVal;
}
}