/* * 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; } }