You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2011/12/28 22:47:20 UTC
svn commit: r1225353 - in /struts/struts2/trunk/core/src:
main/java/org/apache/struts2/components/
main/java/org/apache/struts2/views/jsp/ site/resources/tags/
test/java/org/apache/struts2/ test/java/org/apache/struts2/views/jsp/
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());
+ }
+
+}