Author: lukaszlenart Date: Wed Dec 28 21:47:20 2011 New Revision: 1225353 URL: http://svn.apache.org/viewvc?rev=1225353&view=rev Log: WW-3284 - adds new Number tag
Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/Number.java struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/jsp/NumberTag.java struts/struts2/trunk/core/src/site/resources/tags/number.html struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java Modified: struts/struts2/trunk/core/src/test/java/org/apache/struts2/TestAction.java Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/Number.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/Number.java?rev=1225353&view=auto ============================================================================== --- struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/Number.java (added) +++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/Number.java Wed Dec 28 21:47:20 2011 @@ -0,0 +1,404 @@ +/** + * + */ +package org.apache.struts2.components; + +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.util.logging.Logger; +import com.opensymphony.xwork2.util.logging.LoggerFactory; +import org.apache.struts2.views.annotations.StrutsTag; +import org.apache.struts2.views.annotations.StrutsTagAttribute; + +import java.io.IOException; +import java.io.Writer; +import java.math.RoundingMode; +import java.text.NumberFormat; +import java.util.Currency; + +/** + * <!-- START SNIPPET: javadoc --> + * <p/> + * Format Number object in different ways. + * <p> + * The number tag will allow you to format a Number in a quick and easy way, + * based on the java.text.NumberFormat class. There are four basic number types, + * a number, a currency, a percentage and an integer. If a currency is + * specified, the number format will match the given currency. Further + * parameters can be overridden as needed. + * <p/> + * If a type is not defined, it will finally fall back to the default + * NumberFormat.getNumberInstance() formatting. + * <p/> + * <b>Note</b>: If the requested Number object isn't found on the stack, a blank + * will be returned. + * </p> + * <p/> + * Configurable attributes are :- + * <ul> + * <li>name</li> + * <li>currency - you can specify your own currency or as an OGNL expression</li> + * <li>type - if not specified try to find base on struts.number.format property</li> + * <li>groupingUsed - see NumberFormat.isGroupingUsed</li> + * <li>maximumFractionDigits - see NumberFormat.setMaximumFractionDigits</li> + * <li>maximumIntegerDigits - see NumberFormat.setMaximumIntegerDigits</li> + * <li>minimumFractionDigits - see NumberFormat.setMinimumFractionDigits</li> + * <li>minimumIntegerDigits - see NumberFormat.setMinimumIntegerDigits</li> + * <li>parseIntegerOnly - see NumberFormat.isParseIntegerOnly</li> + * <li>roundingMode - see below</li> + * </ul> + * <p/> + * <p/> + * <p/> + * Possible values for rounding mode are :- + * <ul> + * <li>ceiling</li> + * <li>down</li> + * <li>floor</li> + * <li>half-down</li> + * <li>half-even</li> + * <li>half-up</li> + * <li>unnecessary</li> + * <li>up</li> + * </ul> + * <p/> + * <p/> + * <p/> + * <!-- END SNIPPET: javadoc --> + * <p/> + * <p/> + * <b>Examples</b> + * <p/> + * <pre> + * <!-- START SNIPPET: example --> + * <s:number name="invoice.total" type="currency" currency="XYZ" /> + * <s:number name="invoice.quantity" type="number" /> + * <s:number name="invoice.discount" type="percentage" /> + * <s:number name="invoice.terms" type="integer" /> + * <!-- END SNIPPET: example --> + * </pre> + * <p/> + * <code>Number</code> + */ +@StrutsTag(name = "number", tldBodyContent = "empty", tldTagClass = "org.apache.struts2.views.jsp.NumberTag", description = "Render a formatted number.") +public class Number extends ContextBean { + + private static final Logger LOG = LoggerFactory.getLogger(Number.class); + /** + * Property name to fall back when no format is specified + */ + public static final String NUMBERTAG_PROPERTY = "struts.number.format"; + + private String name; + + private String currency; + + private String type; + + private Boolean groupingUsed; + + private Integer maximumFractionDigits; + + private Integer maximumIntegerDigits; + + private Integer minimumFractionDigits; + + private Integer minimumIntegerDigits; + + private Boolean parseIntegerOnly; + + private String roundingMode; + + public Number(ValueStack stack) { + super(stack); + } + + public boolean end(Writer writer, String body) { + java.lang.Number number = findNumberName(); + + if (number != null) { + + NumberFormat format = getNumberFormat(); + findCurrency(format); + setNumberFormatParameters(format); + setRoundingMode(format); + + String msg = format.format(number); + if (msg != null) { + try { + if (getVar() == null) { + writer.write(msg); + } else { + putInContext(msg); + } + } catch (IOException e) { + LOG.error("Could not write out Number tag", e); + } + } + } + return super.end(writer, ""); + } + + // try to find the currency, percentage and integer on the stack + private void findCurrency(NumberFormat format) { + if (currency != null) { + Object currencyValue = findValue(currency); + if (currencyValue != null) { + currency = currencyValue.toString(); + } + try { + format.setCurrency(Currency.getInstance(currency)); + } catch (IllegalArgumentException iae) { + LOG.error("Could not recognise a currency of [" + currency + "]"); + } + } + } + + private void setNumberFormatParameters(NumberFormat format) { + if (groupingUsed != null) { + format.setGroupingUsed(groupingUsed); + } + if (maximumFractionDigits != null) { + format.setMaximumFractionDigits(maximumFractionDigits); + } + if (maximumIntegerDigits != null) { + format.setMaximumIntegerDigits(maximumIntegerDigits); + } + if (minimumFractionDigits != null) { + format.setMinimumFractionDigits(minimumFractionDigits); + } + if (minimumIntegerDigits != null) { + format.setMinimumIntegerDigits(minimumIntegerDigits); + } + if (parseIntegerOnly != null) { + format.setParseIntegerOnly(parseIntegerOnly); + } + } + + private java.lang.Number findNumberName() { + java.lang.Number number = null; + // find the name on the valueStack + try { + // suport Calendar also + Object numberObject = findValue(name); + if (numberObject instanceof java.lang.Number) { + number = (java.lang.Number) numberObject; + } + } catch (Exception e) { + LOG.error("Could not convert object with key [" + name + "] to a java.lang.Number instance"); + } + return number; + } + + private void setRoundingMode(NumberFormat format) { + if (roundingMode != null) { + roundingMode = findString(roundingMode); + if ("ceiling".equals(roundingMode)) { + format.setRoundingMode(RoundingMode.CEILING); + } else if ("down".equals(roundingMode)) { + format.setRoundingMode(RoundingMode.DOWN); + } else if ("floor".equals(roundingMode)) { + format.setRoundingMode(RoundingMode.FLOOR); + } else if ("half-down".equals(roundingMode)) { + format.setRoundingMode(RoundingMode.HALF_DOWN); + } else if ("half-even".equals(roundingMode)) { + format.setRoundingMode(RoundingMode.HALF_EVEN); + } else if ("half-up".equals(roundingMode)) { + format.setRoundingMode(RoundingMode.HALF_UP); + } else if ("unnecessary".equals(roundingMode)) { + format.setRoundingMode(RoundingMode.UNNECESSARY); + } else if ("up".equals(roundingMode)) { + format.setRoundingMode(RoundingMode.UP); + } else { + LOG.error("Could not recognise a roundingMode of [" + roundingMode + "]"); + } + } + } + + private NumberFormat getNumberFormat() { + NumberFormat format = null; + if (type == null) { + try { + type = findString(NUMBERTAG_PROPERTY); + } catch (Exception e) { + LOG.error("Could not find [" + NUMBERTAG_PROPERTY + "] on the stack!", e); + } + } + if (type != null) { + type = findString(type); + if ("currency".equals(type)) { + format = NumberFormat.getCurrencyInstance(ActionContext.getContext().getLocale()); + } else if ("integer".equals(type)) { + format = NumberFormat.getIntegerInstance(ActionContext.getContext().getLocale()); + } else if ("number".equals(type)) { + format = NumberFormat.getNumberInstance(ActionContext.getContext().getLocale()); + } else if ("percent".equals(type)) { + format = NumberFormat.getPercentInstance(ActionContext.getContext().getLocale()); + } + } + if (format == null) { + format = NumberFormat.getInstance(ActionContext.getContext().getLocale()); + } + return format; + } + + @StrutsTagAttribute(description = "Type of number formatter (currency, integer, number or percent, default is number)", rtexprvalue = false) + public void setType(String type) { + this.type = type; + } + + @StrutsTagAttribute(description = "The currency to use for a currency format", type = "String", defaultValue = "") + public void setCurrency(String currency) { + this.currency = currency; + } + + /** + * @return Returns the name. + */ + public String getName() { + return name; + } + + @StrutsTagAttribute(description = "The number value to format", required = true) + public void setName(String name) { + this.name = name; + } + + /** + * @return Returns the format. + */ + public String getType() { + return type; + } + + /** + * @return Returns the currency. + */ + public String getCurrency() { + return currency; + } + + @StrutsTagAttribute(description = "Whether grouping is used", type = "Boolean") + public void setGroupingUsed(Boolean groupingUsed) { + this.groupingUsed = groupingUsed; + } + + /** + * @return Returns the grouping used. + */ + public Boolean isGroupingUsed() { + return groupingUsed; + } + + /** + * @return the maximumFractionDigits + */ + public Integer getMaximumFractionDigits() { + return maximumFractionDigits; + } + + /** + * @param maximumFractionDigits the maximumFractionDigits to set + */ + @StrutsTagAttribute(description = "Maximum fraction digits", type = "Integer") + public void setMaximumFractionDigits(Integer maximumFractionDigits) { + this.maximumFractionDigits = maximumFractionDigits; + } + + /** + * @return the maximumIntegerDigits + */ + public Integer getMaximumIntegerDigits() { + return maximumIntegerDigits; + } + + /** + * @param maximumIntegerDigits the maximumIntegerDigits to set + */ + @StrutsTagAttribute(description = "Maximum integer digits", type = "Integer") + public void setMaximumIntegerDigits(Integer maximumIntegerDigits) { + this.maximumIntegerDigits = maximumIntegerDigits; + } + + /** + * @return the minimumFractionDigits + */ + public Integer getMinimumFractionDigits() { + return minimumFractionDigits; + } + + /** + * @param minimumFractionDigits the minimumFractionDigits to set + */ + @StrutsTagAttribute(description = "Minimum fraction digits", type = "Integer") + public void setMinimumFractionDigits(Integer minimumFractionDigits) { + this.minimumFractionDigits = minimumFractionDigits; + } + + /** + * @return the minimumIntegerDigits + */ + public Integer getMinimumIntegerDigits() { + return minimumIntegerDigits; + } + + /** + * @param minimumIntegerDigits the minimumIntegerDigits to set + */ + @StrutsTagAttribute(description = "Maximum integer digits", type = "Integer") + public void setMinimumIntegerDigits(Integer minimumIntegerDigits) { + this.minimumIntegerDigits = minimumIntegerDigits; + } + + /** + * @return the parseIntegerOnly + */ + public Boolean isParseIntegerOnly() { + return parseIntegerOnly; + } + + /** + * @param parseIntegerOnly the parseIntegerOnly to set + */ + @StrutsTagAttribute(description = "Parse integer only", type = "Boolean") + public void setParseIntegerOnly(Boolean parseIntegerOnly) { + this.parseIntegerOnly = parseIntegerOnly; + } + + /** + * @return the roundingMode + */ + public String getRoundingMode() { + return roundingMode; + } + + /** + * @param roundingMode the roundingMode to set + */ + @StrutsTagAttribute(description = "The rounding mode to use", type = "String") + public void setRoundingMode(String roundingMode) { + this.roundingMode = roundingMode; + } + +} Added: struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/jsp/NumberTag.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/jsp/NumberTag.java?rev=1225353&view=auto ============================================================================== --- struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/jsp/NumberTag.java (added) +++ struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/jsp/NumberTag.java Wed Dec 28 21:47:20 2011 @@ -0,0 +1,139 @@ +package org.apache.struts2.views.jsp; + +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import com.opensymphony.xwork2.util.ValueStack; +import org.apache.struts2.components.Component; +import org.apache.struts2.components.Number; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @see Number + */ +public class NumberTag extends ContextBeanTag { + + private static final long serialVersionUID = -6216963123295613440L; + + private String name; + private String currency; + private String type; + private Boolean groupingUsed; + private Integer maximumFractionDigits; + private Integer maximumIntegerDigits; + private Integer minimumFractionDigits; + private Integer minimumIntegerDigits; + private Boolean parseIntegerOnly; + private String roundingMode; + + public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { + return new Number(stack); + } + + protected void populateParams() { + super.populateParams(); + Number n = (Number) component; + n.setName(name); + n.setCurrency(currency); + n.setType(type); + n.setGroupingUsed(groupingUsed); + n.setMaximumFractionDigits(maximumFractionDigits); + n.setMaximumIntegerDigits(maximumIntegerDigits); + n.setMinimumFractionDigits(minimumFractionDigits); + n.setMinimumIntegerDigits(minimumIntegerDigits); + n.setParseIntegerOnly(parseIntegerOnly); + n.setRoundingMode(roundingMode); + + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = name; + } + + /** + * @param currency the currency to set + */ + public void setCurrency(String currency) { + this.currency = currency; + } + + /** + * @param type the type to set + */ + public void setType(String type) { + this.type = type; + } + + /** + * @param groupingUsed the groupingUsed to set + */ + public void setGroupingUsed(Boolean groupingUsed) { + this.groupingUsed = groupingUsed; + } + + /** + * @param maximumFractionDigits the maximumFractionDigits to set + */ + public void setMaximumFractionDigits(Integer maximumFractionDigits) { + this.maximumFractionDigits = maximumFractionDigits; + } + + /** + * @param maximumIntegerDigits the maximumIntegerDigits to set + */ + public void setMaximumIntegerDigits(Integer maximumIntegerDigits) { + this.maximumIntegerDigits = maximumIntegerDigits; + } + + /** + * @param minimumFractionDigits the minimumFractionDigits to set + */ + public void setMinimumFractionDigits(Integer minimumFractionDigits) { + this.minimumFractionDigits = minimumFractionDigits; + } + + /** + * @param minimumIntegerDigits the minimumIntegerDigits to set + */ + public void setMinimumIntegerDigits(Integer minimumIntegerDigits) { + this.minimumIntegerDigits = minimumIntegerDigits; + } + + /** + * @param parseIntegerOnly the parseIntegerOnly to set + */ + public void setParseIntegerOnly(Boolean parseIntegerOnly) { + this.parseIntegerOnly = parseIntegerOnly; + } + + /** + * @param roundingMode the roundingMode to set + */ + public void setRoundingMode(String roundingMode) { + this.roundingMode = roundingMode; + } + +} Added: struts/struts2/trunk/core/src/site/resources/tags/number.html URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/site/resources/tags/number.html?rev=1225353&view=auto ============================================================================== --- struts/struts2/trunk/core/src/site/resources/tags/number.html (added) +++ struts/struts2/trunk/core/src/site/resources/tags/number.html Wed Dec 28 21:47:20 2011 @@ -0,0 +1,136 @@ +<!-- +This file is generated during the build by processing Component class annotations. +Please do not edit it directly. +--> +<html> + <head> + <title>number</title> + </head> + + <body> + <h1>Tag Name: number</h1> + <h2>Description</h2> + <p> + <!-- START SNIPPET: tagdescription --> + Render a formatted number. + <!-- END SNIPPET: tagdescription --> + </p> + + <h2>Attributes</h2> + <!-- START SNIPPET: tagattributes --> + <table width="100%"> + <tr> + <td colspan="6"><h4>Dynamic Attributes Allowed:</h4> false</td> + </tr> + <tr> + <td colspan="6"> </td> + </tr> + <tr> + <th align="left" valign="top"><h4>Name</h4></th> + <th align="left" valign="top"><h4>Required</h4></th> + <th align="left" valign="top"><h4>Default</h4></th> + <th align="left" valign="top"><h4>Evaluated</h4></th> + <th align="left" valign="top"><h4>Type</h4></th> + <th align="left" valign="top"><h4>Description</h4></th> + </tr> + <tr> + <td align="left" valign="top">currency</td> + <td align="left" valign="top">false</td> + <td align="left" valign="top"></td> + <td align="left" valign="top">false</td> + <td align="left" valign="top">String</td> + <td align="left" valign="top">The currency to use for a currency format</td> + </tr> + <tr> + <td align="left" valign="top">groupingUsed</td> + <td align="left" valign="top">false</td> + <td align="left" valign="top"></td> + <td align="left" valign="top">false</td> + <td align="left" valign="top">Boolean</td> + <td align="left" valign="top">Whether grouping is used</td> + </tr> + <tr> + <td align="left" valign="top">id</td> + <td align="left" valign="top">false</td> + <td align="left" valign="top"></td> + <td align="left" valign="top">false</td> + <td align="left" valign="top">String</td> + <td align="left" valign="top">Deprecated. Use 'var' instead</td> + </tr> + <tr> + <td align="left" valign="top">maximumFractionDigits</td> + <td align="left" valign="top">false</td> + <td align="left" valign="top"></td> + <td align="left" valign="top">false</td> + <td align="left" valign="top">Integer</td> + <td align="left" valign="top">Maximum fraction digits</td> + </tr> + <tr> + <td align="left" valign="top">maximumIntegerDigits</td> + <td align="left" valign="top">false</td> + <td align="left" valign="top"></td> + <td align="left" valign="top">false</td> + <td align="left" valign="top">Integer</td> + <td align="left" valign="top">Maximum integer digits</td> + </tr> + <tr> + <td align="left" valign="top">minimumFractionDigits</td> + <td align="left" valign="top">false</td> + <td align="left" valign="top"></td> + <td align="left" valign="top">false</td> + <td align="left" valign="top">Integer</td> + <td align="left" valign="top">Minimum fraction digits</td> + </tr> + <tr> + <td align="left" valign="top">minimumIntegerDigits</td> + <td align="left" valign="top">false</td> + <td align="left" valign="top"></td> + <td align="left" valign="top">false</td> + <td align="left" valign="top">Integer</td> + <td align="left" valign="top">Maximum integer digits</td> + </tr> + <tr> + <td align="left" valign="top">name</td> + <td align="left" valign="top"><strong>true</strong></td> + <td align="left" valign="top"></td> + <td align="left" valign="top">false</td> + <td align="left" valign="top">String</td> + <td align="left" valign="top">The number value to format</td> + </tr> + <tr> + <td align="left" valign="top">parseIntegerOnly</td> + <td align="left" valign="top">false</td> + <td align="left" valign="top"></td> + <td align="left" valign="top">false</td> + <td align="left" valign="top">Boolean</td> + <td align="left" valign="top">Parse integer only</td> + </tr> + <tr> + <td align="left" valign="top">roundingMode</td> + <td align="left" valign="top">false</td> + <td align="left" valign="top"></td> + <td align="left" valign="top">false</td> + <td align="left" valign="top">String</td> + <td align="left" valign="top">The rounding mode to use</td> + </tr> + <tr> + <td align="left" valign="top">type</td> + <td align="left" valign="top">false</td> + <td align="left" valign="top"></td> + <td align="left" valign="top">false</td> + <td align="left" valign="top">String</td> + <td align="left" valign="top">Type of number formatter (currency, integer, number or percent, default is number)</td> + </tr> + <tr> + <td align="left" valign="top">var</td> + <td align="left" valign="top">false</td> + <td align="left" valign="top"></td> + <td align="left" valign="top">false</td> + <td align="left" valign="top">String</td> + <td align="left" valign="top">Name used to reference the value pushed into the Value Stack</td> + </tr> + </table> + <!-- END SNIPPET: tagattributes --> + </body> +</html> + Modified: struts/struts2/trunk/core/src/test/java/org/apache/struts2/TestAction.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/TestAction.java?rev=1225353&r1=1225352&r2=1225353&view=diff ============================================================================== --- struts/struts2/trunk/core/src/test/java/org/apache/struts2/TestAction.java (original) +++ struts/struts2/trunk/core/src/test/java/org/apache/struts2/TestAction.java Wed Dec 28 21:47:20 2011 @@ -21,13 +21,16 @@ package org.apache.struts2; -import java.util.*; - -import org.apache.struts2.views.jsp.ui.User; - import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.util.ValueStack; +import org.apache.struts2.views.jsp.ui.User; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** @@ -48,6 +51,7 @@ public class TestAction extends ActionSu private List list2; private List list3; private SomeEnum status = SomeEnum.COMPLETED; + private Float floatNumber; private final Map<String, String> texts = new HashMap<String, String>(); @@ -197,4 +201,11 @@ public class TestAction extends ActionSu return Arrays.asList(SomeEnum.values()); } + public Float getFloatNumber() { + return floatNumber; + } + + public void setFloatNumber(Float floatNumber) { + this.floatNumber = floatNumber; + } } Added: struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java?rev=1225353&view=auto ============================================================================== --- struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java (added) +++ struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java Wed Dec 28 21:47:20 2011 @@ -0,0 +1,99 @@ +package org.apache.struts2.views.jsp; + +import com.opensymphony.xwork2.ActionContext; +import org.apache.struts2.TestAction; + +import java.math.RoundingMode; +import java.text.NumberFormat; +import java.util.Locale; + +public class NumberTagTest extends AbstractTagTest { + + public void testSimpleFloatFormat() throws Exception { + // given + context.put(ActionContext.LOCALE, Locale.US); + + TestAction testAction = (TestAction) action; + testAction.setFloatNumber(120.0f); + + NumberTag tag = new NumberTag(); + tag.setPageContext(pageContext); + tag.setName("floatNumber"); + + // when + tag.doStartTag(); + tag.doEndTag(); + + // then + assertEquals("120", writer.toString()); + } + + public void testSimpleCurrencyUSFormat() throws Exception { + // given + context.put(ActionContext.LOCALE, Locale.US); + + TestAction testAction = (TestAction) action; + testAction.setFloatNumber(120.0f); + + NumberTag tag = new NumberTag(); + tag.setPageContext(pageContext); + tag.setName("floatNumber"); + tag.setType("currency"); + + // when + tag.doStartTag(); + tag.doEndTag(); + + // then + assertEquals("$120.00", writer.toString()); + } + + public void testSimpleCurrencyPLFormat() throws Exception { + // given + context.put(ActionContext.LOCALE, new Locale("pl", "PL")); + + TestAction testAction = (TestAction) action; + testAction.setFloatNumber(120.0f); + + NumberTag tag = new NumberTag(); + tag.setPageContext(pageContext); + tag.setName("floatNumber"); + tag.setType("currency"); + + // when + tag.doStartTag(); + tag.doEndTag(); + + // then + NumberFormat format = NumberFormat.getCurrencyInstance((Locale) context.get(ActionContext.LOCALE)); + format.setRoundingMode(RoundingMode.CEILING); + String expected = format.format(120.0f); + + assertEquals(expected, writer.toString()); + } + + public void testSimpleRoundingCeiling() throws Exception { + // given + context.put(ActionContext.LOCALE, Locale.US); + + TestAction testAction = (TestAction) action; + testAction.setFloatNumber(120.45f); + + NumberTag tag = new NumberTag(); + tag.setPageContext(pageContext); + tag.setName("floatNumber"); + tag.setRoundingMode("ceiling"); + + // when + tag.doStartTag(); + tag.doEndTag(); + + // then + NumberFormat format = NumberFormat.getInstance((Locale) context.get(ActionContext.LOCALE)); + format.setRoundingMode(RoundingMode.CEILING); + String expected = format.format(120.45f); + + assertEquals(expected, writer.toString()); + } + +}