/* * Copyright (c) 1998-2011 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source 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; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * Free SoftwareFoundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */ package com.caucho.jstl.rt; import com.caucho.jsp.BodyContentImpl; import com.caucho.jsp.PageContextImpl; import com.caucho.util.L10N; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.BodyTagSupport; import java.io.IOException; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.util.Locale; /** * Looks up an i18n message from a bundle and prints it. */ public class FormatNumberTag extends BodyTagSupport { private static L10N L = new L10N(FormatNumberTag.class); private Double _value; private boolean _hasValue; private String _type; private String _pattern; private String _currencyCode; private String _currencySymbol; private boolean _groupingUsed = true; private int _maxIntegerDigits = -1; private int _minIntegerDigits = -1; private int _maxFractionDigits = -1; private int _minFractionDigits = -1; private String _var; private String _scope; /** * Sets the formatting value. * * @param value the value. */ public void setValue(Object value) throws JspException { try { if (value == null || "".equals(value)) { } else if (value instanceof Number) _value = ((Number) value).doubleValue(); else if (value instanceof String) { _value = Double.valueOf((String) value); } else { throw new NumberFormatException(L.l("Expected number at '{0}'", value)); } } catch (NumberFormatException e) { throw new JspException(new IllegalArgumentException(e.getMessage())); } _hasValue = true; } /** * Sets the formatting type. * * @param type the type. */ public void setType(String type) { _type = type; } /** * Sets the number pattern. * * @param pattern the number pattern. */ public void setPattern(String pattern) { _pattern = pattern; } /** * Sets the currency code. * * @param currencyCode the currency code. */ public void setCurrencyCode(String currency) { _currencyCode = currency; } /** * Sets the currency symbol. * * @param currencySymbol the currency symbol. */ public void setCurrencySymbol(String currencySymbol) { _currencySymbol = currencySymbol; } /** * Sets the groupingUsed expression * * @param groupingUsed true if grouping is used */ public void setGroupingUsed(boolean groupingUsed) { _groupingUsed = groupingUsed; } /** * Sets the minimum digits allowed in the integer portion. * * @param minIntegerDigits the digits. */ public void setMinIntegerDigits(int minIntegerDigits) { _minIntegerDigits = minIntegerDigits; } /** * Sets the maximum digits allowed in the integer portion. * * @param maxIntegerDigits the digits. */ public void setMaxIntegerDigits(int maxIntegerDigits) { _maxIntegerDigits = maxIntegerDigits; } /** * Sets the minimum digits allowed in the fraction portion. * * @param minFractionDigits the digits. */ public void setMinFractionDigits(int minFractionDigits) { _minFractionDigits = minFractionDigits; } /** * Sets the maximum digits allowed in the fraction portion. * * @param maxFractionDigits the JSP-EL expression for the digits. */ public void setMaxFractionDigits(int maxFractionDigits) { _maxFractionDigits = maxFractionDigits; } /** * Sets the variable name. * * @param var the variable name to store the value in. */ public void setVar(String var) { _var = var; } /** * Sets the variable scope. * * @param scope the variable scope to store the value in. */ public void setScope(String scope) { _scope = scope; } /** * Process the tag. */ public int doEndTag() throws JspException { try { PageContextImpl pc = (PageContextImpl) pageContext; JspWriter out = pc.getOut(); NumberFormat format = getFormat(); Double rawValue = null; BodyContentImpl body = (BodyContentImpl) getBodyContent(); if (_hasValue) rawValue = _value; else if (body != null) { String value = body.getTrimString(); if (! value.equals("")) rawValue = Double.parseDouble(value); } if (rawValue != null && Double.isNaN(rawValue)) rawValue = 0.0; String value; if (rawValue == null) value = null; else if (format != null) value = format.format(rawValue); else value = String.valueOf(rawValue); if (_var == null) { if (_scope != null) throw new JspException(L.l("fmt:formatDate var must not be null when scope '{0}' is set.", _scope)); if (value != null) out.print(value); } else CoreSetTag.setValue(pageContext, _var, _scope, value); } catch (IOException e) { } return EVAL_PAGE; } protected NumberFormat getFormat() throws JspException { PageContextImpl pc = (PageContextImpl) pageContext; NumberFormat format = null; Locale locale = pc.getLocale(); String type = _type; if (type == null || type.equals("") || type.equals("number") || _pattern != null && ! "".equals(_pattern)) { if (locale != null) format = NumberFormat.getInstance(locale); else format = NumberFormat.getInstance(); DecimalFormat decimalFormat = (DecimalFormat) format; if (_pattern != null) decimalFormat.applyPattern(_pattern); } else if (type.equals("percent")) { if (locale != null) format = NumberFormat.getPercentInstance(locale); else format = NumberFormat.getPercentInstance(); } else if (type.equals("currency")) { if (locale != null) format = NumberFormat.getCurrencyInstance(locale); else format = NumberFormat.getCurrencyInstance(); if ((_currencyCode != null || _currencySymbol != null) && format instanceof DecimalFormat) { DecimalFormat dFormat = (DecimalFormat) format; DecimalFormatSymbols dSymbols; dSymbols = dFormat.getDecimalFormatSymbols(); if (_currencyCode != null && dSymbols != null) dSymbols.setInternationalCurrencySymbol(_currencyCode); else if (_currencySymbol != null && dSymbols != null) dSymbols.setCurrencySymbol(_currencySymbol); dFormat.setDecimalFormatSymbols(dSymbols); } } else throw new JspException(L.l("unknown formatNumber type `{0}'", type)); format.setGroupingUsed(_groupingUsed); if (_minIntegerDigits > 0) format.setMinimumIntegerDigits(_minIntegerDigits); if (_maxIntegerDigits > 0) format.setMaximumIntegerDigits(_maxIntegerDigits); if (_minFractionDigits > 0) format.setMinimumFractionDigits(_minFractionDigits); if (_maxFractionDigits > 0) format.setMaximumFractionDigits(_maxFractionDigits); return format; } }