Initial support for JSR-354 Money & Currency
Issue: SPR-12209
This commit is contained in:
parent
bc6a98c144
commit
6c169bd644
|
|
@ -460,6 +460,7 @@ project("spring-context") {
|
||||||
optional("javax.inject:javax.inject:1")
|
optional("javax.inject:javax.inject:1")
|
||||||
optional("javax.ejb:ejb-api:3.0")
|
optional("javax.ejb:ejb-api:3.0")
|
||||||
optional("javax.enterprise.concurrent:javax.enterprise.concurrent-api:1.0")
|
optional("javax.enterprise.concurrent:javax.enterprise.concurrent-api:1.0")
|
||||||
|
optional("javax.money:money-api:1.0-RC3")
|
||||||
optional("org.eclipse.persistence:javax.persistence:2.0.0")
|
optional("org.eclipse.persistence:javax.persistence:2.0.0")
|
||||||
optional("javax.validation:validation-api:1.0.0.GA")
|
optional("javax.validation:validation-api:1.0.0.GA")
|
||||||
optional("org.hibernate:hibernate-validator:${hibval4Version}")
|
optional("org.hibernate:hibernate-validator:${hibval4Version}")
|
||||||
|
|
@ -469,6 +470,7 @@ project("spring-context") {
|
||||||
optional("org.beanshell:bsh:2.0b4")
|
optional("org.beanshell:bsh:2.0b4")
|
||||||
optional("org.jruby:jruby:1.7.19")
|
optional("org.jruby:jruby:1.7.19")
|
||||||
testCompile("javax.inject:javax.inject-tck:1")
|
testCompile("javax.inject:javax.inject-tck:1")
|
||||||
|
testCompile("org.javamoney:moneta:1.0-RC3")
|
||||||
testCompile("commons-dbcp:commons-dbcp:1.4")
|
testCompile("commons-dbcp:commons-dbcp:1.4")
|
||||||
testCompile("org.apache.commons:commons-pool2:2.2")
|
testCompile("org.apache.commons:commons-pool2:2.2")
|
||||||
testCompile("org.slf4j:slf4j-api:${slf4jVersion}")
|
testCompile("org.slf4j:slf4j-api:${slf4jVersion}")
|
||||||
|
|
|
||||||
|
|
@ -28,15 +28,19 @@ import java.lang.annotation.Target;
|
||||||
* <p>Supports formatting by style or custom pattern string.
|
* <p>Supports formatting by style or custom pattern string.
|
||||||
* Can be applied to any JDK {@code java.lang.Number} type.
|
* Can be applied to any JDK {@code java.lang.Number} type.
|
||||||
*
|
*
|
||||||
* <p>For style-based formatting, set the {@link #style} attribute to be the desired {@link Style}.
|
* <p>For style-based formatting, set the {@link #style} attribute to be the
|
||||||
* For custom formatting, set the {@link #pattern} attribute to be the number pattern, such as {@code #, ###.##}.
|
* desired {@link Style}. For custom formatting, set the {@link #pattern}
|
||||||
|
* attribute to be the number pattern, such as {@code #, ###.##}.
|
||||||
*
|
*
|
||||||
* <p>Each attribute is mutually exclusive, so only set one attribute per annotation instance
|
* <p>Each attribute is mutually exclusive, so only set one attribute per
|
||||||
* (the one most convenient one for your formatting needs). When the pattern attribute is specified,
|
* annotation instance (the one most convenient one for your formatting needs).
|
||||||
* it takes precedence over the style attribute. When no annotation attributes are specified,
|
* When the {@link #pattern} attribute is specified, it takes precedence over
|
||||||
* the default format applied is style-based with a style of {@link Style#NUMBER}.
|
* the {@link #style} attribute. When no annotation attributes are specified,
|
||||||
|
* the default format applied is style-based for either number of currency,
|
||||||
|
* depending on the annotated field type.
|
||||||
*
|
*
|
||||||
* @author Keith Donald
|
* @author Keith Donald
|
||||||
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see java.text.NumberFormat
|
* @see java.text.NumberFormat
|
||||||
*/
|
*/
|
||||||
|
|
@ -47,11 +51,12 @@ public @interface NumberFormat {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The style pattern to use to format the field.
|
* The style pattern to use to format the field.
|
||||||
* <p>Defaults to {@link Style#NUMBER} for general-purpose number formatter.
|
* <p>Defaults to {@link Style#DEFAULT} for general-purpose number formatting
|
||||||
* Set this attribute when you wish to format your field in accordance with a
|
* for most annotated types, except for money types which default to currency
|
||||||
* common style other than the default style.
|
* formatting. Set this attribute when you wish to format your field in
|
||||||
|
* accordance with a common style other than the default style.
|
||||||
*/
|
*/
|
||||||
Style style() default Style.NUMBER;
|
Style style() default Style.DEFAULT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The custom pattern to use to format the field.
|
* The custom pattern to use to format the field.
|
||||||
|
|
@ -67,6 +72,13 @@ public @interface NumberFormat {
|
||||||
*/
|
*/
|
||||||
public enum Style {
|
public enum Style {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default format for the annotated type: typically number
|
||||||
|
* but possibly currency for a money type.
|
||||||
|
* @since 4.2
|
||||||
|
*/
|
||||||
|
DEFAULT,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The general-purpose number format for the current locale.
|
* The general-purpose number format for the current locale.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ public abstract class AbstractNumberFormatter implements Formatter<Number> {
|
||||||
|
|
||||||
private boolean lenient = false;
|
private boolean lenient = false;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify whether or not parsing is to be lenient. Default is false.
|
* Specify whether or not parsing is to be lenient. Default is false.
|
||||||
* <p>With lenient parsing, the parser may allow inputs that do not precisely match the format.
|
* <p>With lenient parsing, the parser may allow inputs that do not precisely match the format.
|
||||||
|
|
@ -44,6 +45,7 @@ public abstract class AbstractNumberFormatter implements Formatter<Number> {
|
||||||
this.lenient = lenient;
|
this.lenient = lenient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String print(Number number, Locale locale) {
|
public String print(Number number, Locale locale) {
|
||||||
return getNumberFormat(locale).format(number);
|
return getNumberFormat(locale).format(number);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -16,92 +16,16 @@
|
||||||
|
|
||||||
package org.springframework.format.number;
|
package org.springframework.format.number;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.text.NumberFormat;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.util.Currency;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import org.springframework.util.ClassUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A BigDecimal formatter for currency values.
|
* A BigDecimal formatter for currency values.
|
||||||
*
|
*
|
||||||
* <p>Delegates to {@link NumberFormat#getCurrencyInstance(Locale)}.
|
|
||||||
* Configures BigDecimal parsing so there is no loss of precision.
|
|
||||||
* Can apply a specified {@link RoundingMode} to parsed values.
|
|
||||||
*
|
|
||||||
* @author Keith Donald
|
* @author Keith Donald
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 4.2
|
||||||
* @see #setLenient
|
* @deprecated as of Spring 4.2, in favor of the more clearly named
|
||||||
* @see #setRoundingMode
|
* {@link CurrencyStyleFormatter}
|
||||||
*/
|
*/
|
||||||
public class CurrencyFormatter extends AbstractNumberFormatter {
|
@Deprecated
|
||||||
|
public class CurrencyFormatter extends CurrencyStyleFormatter {
|
||||||
private static final boolean roundingModeOnDecimalFormat =
|
|
||||||
ClassUtils.hasMethod(DecimalFormat.class, "setRoundingMode", RoundingMode.class);
|
|
||||||
|
|
||||||
private int fractionDigits = 2;
|
|
||||||
|
|
||||||
private RoundingMode roundingMode;
|
|
||||||
|
|
||||||
private Currency currency;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify the desired number of fraction digits.
|
|
||||||
* Default is 2.
|
|
||||||
*/
|
|
||||||
public void setFractionDigits(int fractionDigits) {
|
|
||||||
this.fractionDigits = fractionDigits;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify the rounding mode to use for decimal parsing.
|
|
||||||
* Default is {@link RoundingMode#UNNECESSARY}.
|
|
||||||
*/
|
|
||||||
public void setRoundingMode(RoundingMode roundingMode) {
|
|
||||||
this.roundingMode = roundingMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify the currency, if known.
|
|
||||||
*/
|
|
||||||
public void setCurrency(Currency currency) {
|
|
||||||
this.currency = currency;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BigDecimal parse(String text, Locale locale) throws ParseException {
|
|
||||||
BigDecimal decimal = (BigDecimal) super.parse(text, locale);
|
|
||||||
if (decimal != null) {
|
|
||||||
if (this.roundingMode != null) {
|
|
||||||
decimal = decimal.setScale(this.fractionDigits, this.roundingMode);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
decimal = decimal.setScale(this.fractionDigits);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return decimal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected NumberFormat getNumberFormat(Locale locale) {
|
|
||||||
DecimalFormat format = (DecimalFormat) NumberFormat.getCurrencyInstance(locale);
|
|
||||||
format.setParseBigDecimal(true);
|
|
||||||
format.setMaximumFractionDigits(this.fractionDigits);
|
|
||||||
format.setMinimumFractionDigits(this.fractionDigits);
|
|
||||||
if (this.roundingMode != null && roundingModeOnDecimalFormat) {
|
|
||||||
format.setRoundingMode(this.roundingMode);
|
|
||||||
}
|
|
||||||
if (this.currency != null) {
|
|
||||||
format.setCurrency(this.currency);
|
|
||||||
}
|
|
||||||
return format;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2015 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.format.number;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.Currency;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A BigDecimal formatter for number values in currency style.
|
||||||
|
*
|
||||||
|
* <p>Delegates to {@link java.text.NumberFormat#getCurrencyInstance(Locale)}.
|
||||||
|
* Configures BigDecimal parsing so there is no loss of precision.
|
||||||
|
* Can apply a specified {@link java.math.RoundingMode} to parsed values.
|
||||||
|
*
|
||||||
|
* @author Keith Donald
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 4.2
|
||||||
|
* @see #setLenient
|
||||||
|
* @see #setRoundingMode
|
||||||
|
*/
|
||||||
|
public class CurrencyStyleFormatter extends AbstractNumberFormatter {
|
||||||
|
|
||||||
|
private int fractionDigits = 2;
|
||||||
|
|
||||||
|
private RoundingMode roundingMode;
|
||||||
|
|
||||||
|
private Currency currency;
|
||||||
|
|
||||||
|
private String pattern;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the desired number of fraction digits.
|
||||||
|
* Default is 2.
|
||||||
|
*/
|
||||||
|
public void setFractionDigits(int fractionDigits) {
|
||||||
|
this.fractionDigits = fractionDigits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the rounding mode to use for decimal parsing.
|
||||||
|
* Default is {@link java.math.RoundingMode#UNNECESSARY}.
|
||||||
|
*/
|
||||||
|
public void setRoundingMode(RoundingMode roundingMode) {
|
||||||
|
this.roundingMode = roundingMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the currency, if known.
|
||||||
|
*/
|
||||||
|
public void setCurrency(Currency currency) {
|
||||||
|
this.currency = currency;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the pattern to use to format number values.
|
||||||
|
* If not specified, the default DecimalFormat pattern is used.
|
||||||
|
* @see java.text.DecimalFormat#applyPattern(String)
|
||||||
|
*/
|
||||||
|
public void setPattern(String pattern) {
|
||||||
|
this.pattern = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigDecimal parse(String text, Locale locale) throws ParseException {
|
||||||
|
BigDecimal decimal = (BigDecimal) super.parse(text, locale);
|
||||||
|
if (decimal != null) {
|
||||||
|
if (this.roundingMode != null) {
|
||||||
|
decimal = decimal.setScale(this.fractionDigits, this.roundingMode);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
decimal = decimal.setScale(this.fractionDigits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberFormat getNumberFormat(Locale locale) {
|
||||||
|
DecimalFormat format = (DecimalFormat) NumberFormat.getCurrencyInstance(locale);
|
||||||
|
format.setParseBigDecimal(true);
|
||||||
|
format.setMaximumFractionDigits(this.fractionDigits);
|
||||||
|
format.setMinimumFractionDigits(this.fractionDigits);
|
||||||
|
if (this.roundingMode != null) {
|
||||||
|
format.setRoundingMode(this.roundingMode);
|
||||||
|
}
|
||||||
|
if (this.currency != null) {
|
||||||
|
format.setCurrency(this.currency);
|
||||||
|
}
|
||||||
|
if (this.pattern != null) {
|
||||||
|
format.applyPattern(this.pattern);
|
||||||
|
}
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -57,18 +57,18 @@ public class NumberFormatAnnotationFormatterFactory extends EmbeddedValueResolut
|
||||||
|
|
||||||
private Formatter<Number> configureFormatterFrom(NumberFormat annotation) {
|
private Formatter<Number> configureFormatterFrom(NumberFormat annotation) {
|
||||||
if (StringUtils.hasLength(annotation.pattern())) {
|
if (StringUtils.hasLength(annotation.pattern())) {
|
||||||
return new NumberFormatter(resolveEmbeddedValue(annotation.pattern()));
|
return new NumberStyleFormatter(resolveEmbeddedValue(annotation.pattern()));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Style style = annotation.style();
|
Style style = annotation.style();
|
||||||
if (style == Style.PERCENT) {
|
if (style == Style.PERCENT) {
|
||||||
return new PercentFormatter();
|
return new PercentStyleFormatter();
|
||||||
}
|
}
|
||||||
else if (style == Style.CURRENCY) {
|
else if (style == Style.CURRENCY) {
|
||||||
return new CurrencyFormatter();
|
return new CurrencyStyleFormatter();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return new NumberFormatter();
|
return new NumberStyleFormatter();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -16,28 +16,17 @@
|
||||||
|
|
||||||
package org.springframework.format.number;
|
package org.springframework.format.number;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.text.NumberFormat;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A general-purpose Number formatter.
|
* A general-purpose Number formatter.
|
||||||
*
|
*
|
||||||
* <p>Delegates to {@link NumberFormat#getInstance(Locale)}.
|
|
||||||
* Configures BigDecimal parsing so there is no loss in precision.
|
|
||||||
* Allows configuration over the decimal number pattern.
|
|
||||||
* The {@link #parse(String, Locale)} routine always returns a BigDecimal.
|
|
||||||
*
|
|
||||||
* @author Keith Donald
|
* @author Keith Donald
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see #setPattern
|
* @deprecated as of Spring 4.2, in favor of the more clearly named
|
||||||
* @see #setLenient
|
* {@link NumberStyleFormatter}
|
||||||
*/
|
*/
|
||||||
public class NumberFormatter extends AbstractNumberFormatter {
|
@Deprecated
|
||||||
|
public class NumberFormatter extends NumberStyleFormatter {
|
||||||
private String pattern;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new NumberFormatter without a pattern.
|
* Create a new NumberFormatter without a pattern.
|
||||||
|
|
@ -51,35 +40,7 @@ public class NumberFormatter extends AbstractNumberFormatter {
|
||||||
* @see #setPattern
|
* @see #setPattern
|
||||||
*/
|
*/
|
||||||
public NumberFormatter(String pattern) {
|
public NumberFormatter(String pattern) {
|
||||||
this.pattern = pattern;
|
super(pattern);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the pattern to use to format number values.
|
|
||||||
* If not specified, the default DecimalFormat pattern is used.
|
|
||||||
* @see DecimalFormat#applyPattern(String)
|
|
||||||
*/
|
|
||||||
public void setPattern(String pattern) {
|
|
||||||
this.pattern = pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NumberFormat getNumberFormat(Locale locale) {
|
|
||||||
NumberFormat format = NumberFormat.getInstance(locale);
|
|
||||||
if (!(format instanceof DecimalFormat)) {
|
|
||||||
if (this.pattern != null) {
|
|
||||||
throw new IllegalStateException("Cannot support pattern for non-DecimalFormat: " + format);
|
|
||||||
}
|
|
||||||
return format;
|
|
||||||
}
|
|
||||||
DecimalFormat decimalFormat = (DecimalFormat) format;
|
|
||||||
decimalFormat.setParseBigDecimal(true);
|
|
||||||
if (this.pattern != null) {
|
|
||||||
decimalFormat.applyPattern(this.pattern);
|
|
||||||
}
|
|
||||||
return decimalFormat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2015 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.format.number;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A general-purpose number formatter using NumberFormat's number style.
|
||||||
|
*
|
||||||
|
* <p>Delegates to {@link java.text.NumberFormat#getInstance(Locale)}.
|
||||||
|
* Configures BigDecimal parsing so there is no loss in precision.
|
||||||
|
* Allows configuration over the decimal number pattern.
|
||||||
|
* The {@link #parse(String, Locale)} routine always returns a BigDecimal.
|
||||||
|
*
|
||||||
|
* @author Keith Donald
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 4.2
|
||||||
|
* @see #setPattern
|
||||||
|
* @see #setLenient
|
||||||
|
*/
|
||||||
|
public class NumberStyleFormatter extends AbstractNumberFormatter {
|
||||||
|
|
||||||
|
private String pattern;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new NumberStyleFormatter without a pattern.
|
||||||
|
*/
|
||||||
|
public NumberStyleFormatter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new NumberStyleFormatter with the specified pattern.
|
||||||
|
* @param pattern the format pattern
|
||||||
|
* @see #setPattern
|
||||||
|
*/
|
||||||
|
public NumberStyleFormatter(String pattern) {
|
||||||
|
this.pattern = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the pattern to use to format number values.
|
||||||
|
* If not specified, the default DecimalFormat pattern is used.
|
||||||
|
* @see java.text.DecimalFormat#applyPattern(String)
|
||||||
|
*/
|
||||||
|
public void setPattern(String pattern) {
|
||||||
|
this.pattern = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NumberFormat getNumberFormat(Locale locale) {
|
||||||
|
NumberFormat format = NumberFormat.getInstance(locale);
|
||||||
|
if (!(format instanceof DecimalFormat)) {
|
||||||
|
if (this.pattern != null) {
|
||||||
|
throw new IllegalStateException("Cannot support pattern for non-DecimalFormat: " + format);
|
||||||
|
}
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
DecimalFormat decimalFormat = (DecimalFormat) format;
|
||||||
|
decimalFormat.setParseBigDecimal(true);
|
||||||
|
if (this.pattern != null) {
|
||||||
|
decimalFormat.applyPattern(this.pattern);
|
||||||
|
}
|
||||||
|
return decimalFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -16,31 +16,16 @@
|
||||||
|
|
||||||
package org.springframework.format.number;
|
package org.springframework.format.number;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
import java.text.NumberFormat;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Number formatter for percent values.
|
* A Number formatter for percent values.
|
||||||
*
|
*
|
||||||
* <p>Delegates to {@link NumberFormat#getPercentInstance(Locale)}.
|
|
||||||
* Configures BigDecimal parsing so there is no loss in precision.
|
|
||||||
* The {@link #parse(String, Locale)} routine always returns a BigDecimal.
|
|
||||||
*
|
|
||||||
* @author Keith Donald
|
* @author Keith Donald
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see #setLenient
|
* @deprecated as of Spring 4.2, in favor of the more clearly named
|
||||||
|
* {@link PercentStyleFormatter}
|
||||||
*/
|
*/
|
||||||
public class PercentFormatter extends AbstractNumberFormatter {
|
@Deprecated
|
||||||
|
public class PercentFormatter extends PercentStyleFormatter {
|
||||||
@Override
|
|
||||||
protected NumberFormat getNumberFormat(Locale locale) {
|
|
||||||
NumberFormat format = NumberFormat.getPercentInstance(locale);
|
|
||||||
if (format instanceof DecimalFormat) {
|
|
||||||
((DecimalFormat) format).setParseBigDecimal(true);
|
|
||||||
}
|
|
||||||
return format;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2015 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.format.number;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A formatter for number values in percent style.
|
||||||
|
*
|
||||||
|
* <p>Delegates to {@link java.text.NumberFormat#getPercentInstance(Locale)}.
|
||||||
|
* Configures BigDecimal parsing so there is no loss in precision.
|
||||||
|
* The {@link #parse(String, Locale)} routine always returns a BigDecimal.
|
||||||
|
*
|
||||||
|
* @author Keith Donald
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 4.2
|
||||||
|
* @see #setLenient
|
||||||
|
*/
|
||||||
|
public class PercentStyleFormatter extends AbstractNumberFormatter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NumberFormat getNumberFormat(Locale locale) {
|
||||||
|
NumberFormat format = NumberFormat.getPercentInstance(locale);
|
||||||
|
if (format instanceof DecimalFormat) {
|
||||||
|
((DecimalFormat) format).setParseBigDecimal(true);
|
||||||
|
}
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2015 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.format.number.money;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import javax.money.CurrencyUnit;
|
||||||
|
import javax.money.MonetaryCurrencies;
|
||||||
|
|
||||||
|
import org.springframework.format.Formatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formatter for JSR-354 {@link javax.money.CurrencyUnit} values,
|
||||||
|
* from and to currency code Strings.
|
||||||
|
*
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 4.2
|
||||||
|
*/
|
||||||
|
public class CurrencyUnitFormatter implements Formatter<CurrencyUnit> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String print(CurrencyUnit object, Locale locale) {
|
||||||
|
return object.getCurrencyCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CurrencyUnit parse(String text, Locale locale) {
|
||||||
|
return MonetaryCurrencies.getCurrency(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2015 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.format.number.money;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Currency;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.money.CurrencyUnit;
|
||||||
|
import javax.money.MonetaryAmount;
|
||||||
|
import javax.money.MonetaryAmounts;
|
||||||
|
import javax.money.MonetaryCurrencies;
|
||||||
|
|
||||||
|
import org.springframework.context.support.EmbeddedValueResolutionSupport;
|
||||||
|
import org.springframework.format.AnnotationFormatterFactory;
|
||||||
|
import org.springframework.format.Formatter;
|
||||||
|
import org.springframework.format.Parser;
|
||||||
|
import org.springframework.format.Printer;
|
||||||
|
import org.springframework.format.annotation.NumberFormat;
|
||||||
|
import org.springframework.format.annotation.NumberFormat.Style;
|
||||||
|
import org.springframework.format.number.CurrencyStyleFormatter;
|
||||||
|
import org.springframework.format.number.NumberStyleFormatter;
|
||||||
|
import org.springframework.format.number.PercentStyleFormatter;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats {@link javax.money.MonetaryAmount} fields annotated
|
||||||
|
* with Spring's common {@link NumberFormat} annotation.
|
||||||
|
*
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 4.2
|
||||||
|
* @see NumberFormat
|
||||||
|
*/
|
||||||
|
public class Jsr354NumberFormatAnnotationFormatterFactory extends EmbeddedValueResolutionSupport
|
||||||
|
implements AnnotationFormatterFactory<NumberFormat> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Set<Class<?>> getFieldTypes() {
|
||||||
|
return (Set) Collections.singleton(MonetaryAmount.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Printer<MonetaryAmount> getPrinter(NumberFormat annotation, Class<?> fieldType) {
|
||||||
|
return configureFormatterFrom(annotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Parser<MonetaryAmount> getParser(NumberFormat annotation, Class<?> fieldType) {
|
||||||
|
return configureFormatterFrom(annotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Formatter<MonetaryAmount> configureFormatterFrom(NumberFormat annotation) {
|
||||||
|
if (StringUtils.hasLength(annotation.pattern())) {
|
||||||
|
return new NumberDecoratingFormatter(null, resolveEmbeddedValue(annotation.pattern()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Style style = annotation.style();
|
||||||
|
if (style == Style.PERCENT) {
|
||||||
|
return new NumberDecoratingFormatter(new PercentStyleFormatter(), null);
|
||||||
|
}
|
||||||
|
else if (style == Style.NUMBER) {
|
||||||
|
return new NumberDecoratingFormatter(new NumberStyleFormatter(), null);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new NumberDecoratingFormatter(null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class NumberDecoratingFormatter implements Formatter<MonetaryAmount> {
|
||||||
|
|
||||||
|
private final Formatter<Number> numberFormatter;
|
||||||
|
|
||||||
|
private final String pattern;
|
||||||
|
|
||||||
|
public NumberDecoratingFormatter(Formatter<Number> numberFormatter, String pattern) {
|
||||||
|
this.numberFormatter = numberFormatter;
|
||||||
|
this.pattern = pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String print(MonetaryAmount object, Locale locale) {
|
||||||
|
Formatter<Number> formatterToUse = this.numberFormatter;
|
||||||
|
if (formatterToUse == null) {
|
||||||
|
CurrencyStyleFormatter formatter = new CurrencyStyleFormatter();
|
||||||
|
formatter.setCurrency(Currency.getInstance(object.getCurrency().getCurrencyCode()));
|
||||||
|
formatter.setPattern(this.pattern);
|
||||||
|
formatterToUse = formatter;
|
||||||
|
}
|
||||||
|
return formatterToUse.print(object.getNumber(), locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MonetaryAmount parse(String text, Locale locale) throws ParseException {
|
||||||
|
Currency currency = Currency.getInstance(locale);
|
||||||
|
Formatter<Number> formatterToUse = this.numberFormatter;
|
||||||
|
if (formatterToUse == null) {
|
||||||
|
CurrencyStyleFormatter formatter = new CurrencyStyleFormatter();
|
||||||
|
formatter.setCurrency(currency);
|
||||||
|
formatter.setPattern(this.pattern);
|
||||||
|
formatterToUse = formatter;
|
||||||
|
}
|
||||||
|
Number numberValue = formatterToUse.parse(text, locale);
|
||||||
|
CurrencyUnit currencyUnit = MonetaryCurrencies.getCurrency(currency.getCurrencyCode());
|
||||||
|
return MonetaryAmounts.getDefaultAmountFactory().setNumber(numberValue).setCurrency(currencyUnit).create();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2015 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.format.number.money;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import javax.money.MonetaryAmount;
|
||||||
|
import javax.money.format.MonetaryAmountFormat;
|
||||||
|
import javax.money.format.MonetaryFormats;
|
||||||
|
|
||||||
|
import org.springframework.format.Formatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formatter for JSR-354 {@link javax.money.MonetaryAmount} values,
|
||||||
|
* delegating to {@link javax.money.format.MonetaryAmountFormat#format}
|
||||||
|
* and {@link javax.money.format.MonetaryAmountFormat#parse}.
|
||||||
|
*
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 4.2
|
||||||
|
* @see #getMonetaryAmountFormat
|
||||||
|
*/
|
||||||
|
public class MonetaryAmountFormatter implements Formatter<MonetaryAmount> {
|
||||||
|
|
||||||
|
private String formatName;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a locale-driven MonetaryAmountFormatter.
|
||||||
|
*/
|
||||||
|
public MonetaryAmountFormatter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MonetaryAmountFormatter for the given format name.
|
||||||
|
* @param formatName the format name, to be resolved by the JSR-354
|
||||||
|
* provider at runtime
|
||||||
|
*/
|
||||||
|
public MonetaryAmountFormatter(String formatName) {
|
||||||
|
this.formatName = formatName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the format name, to be resolved by the JSR-354 provider
|
||||||
|
* at runtime.
|
||||||
|
* <p>Default is none, obtaining a {@link MonetaryAmountFormat}
|
||||||
|
* based on the current locale.
|
||||||
|
*/
|
||||||
|
public void setFormatName(String formatName) {
|
||||||
|
this.formatName = formatName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String print(MonetaryAmount object, Locale locale) {
|
||||||
|
return getMonetaryAmountFormat(locale).format(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MonetaryAmount parse(String text, Locale locale) {
|
||||||
|
return getMonetaryAmountFormat(locale).parse(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain a MonetaryAmountFormat for the given locale.
|
||||||
|
* <p>The default implementation simply calls
|
||||||
|
* {@link javax.money.format.MonetaryFormats#getAmountFormat}
|
||||||
|
* with either the configured format name or the given locale.
|
||||||
|
* @param locale the current locale
|
||||||
|
* @return the MonetaryAmountFormat (never {@code null})
|
||||||
|
* @see #setFormatName
|
||||||
|
*/
|
||||||
|
protected MonetaryAmountFormat getMonetaryAmountFormat(Locale locale) {
|
||||||
|
if (this.formatName != null) {
|
||||||
|
return MonetaryFormats.getAmountFormat(this.formatName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return MonetaryFormats.getAmountFormat(locale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
/**
|
||||||
|
* Integration with the JSR-354 <code>javax.money</code> package.
|
||||||
|
*/
|
||||||
|
package org.springframework.format.number.money;
|
||||||
|
|
@ -21,6 +21,9 @@ import org.springframework.format.FormatterRegistry;
|
||||||
import org.springframework.format.datetime.DateFormatterRegistrar;
|
import org.springframework.format.datetime.DateFormatterRegistrar;
|
||||||
import org.springframework.format.datetime.joda.JodaTimeFormatterRegistrar;
|
import org.springframework.format.datetime.joda.JodaTimeFormatterRegistrar;
|
||||||
import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
|
import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
|
||||||
|
import org.springframework.format.number.money.CurrencyUnitFormatter;
|
||||||
|
import org.springframework.format.number.money.Jsr354NumberFormatAnnotationFormatterFactory;
|
||||||
|
import org.springframework.format.number.money.MonetaryAmountFormatter;
|
||||||
import org.springframework.format.number.NumberFormatAnnotationFormatterFactory;
|
import org.springframework.format.number.NumberFormatAnnotationFormatterFactory;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.StringValueResolver;
|
import org.springframework.util.StringValueResolver;
|
||||||
|
|
@ -40,6 +43,9 @@ import org.springframework.util.StringValueResolver;
|
||||||
*/
|
*/
|
||||||
public class DefaultFormattingConversionService extends FormattingConversionService {
|
public class DefaultFormattingConversionService extends FormattingConversionService {
|
||||||
|
|
||||||
|
private static final boolean jsr354Present = ClassUtils.isPresent(
|
||||||
|
"javax.money.MonetaryAmount", DefaultFormattingConversionService.class.getClassLoader());
|
||||||
|
|
||||||
private static final boolean jsr310Present = ClassUtils.isPresent(
|
private static final boolean jsr310Present = ClassUtils.isPresent(
|
||||||
"java.time.LocalDate", DefaultFormattingConversionService.class.getClassLoader());
|
"java.time.LocalDate", DefaultFormattingConversionService.class.getClassLoader());
|
||||||
|
|
||||||
|
|
@ -91,7 +97,17 @@ public class DefaultFormattingConversionService extends FormattingConversionServ
|
||||||
* @param formatterRegistry the service to register default formatters against
|
* @param formatterRegistry the service to register default formatters against
|
||||||
*/
|
*/
|
||||||
public static void addDefaultFormatters(FormatterRegistry formatterRegistry) {
|
public static void addDefaultFormatters(FormatterRegistry formatterRegistry) {
|
||||||
|
// Default handling of number values
|
||||||
formatterRegistry.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
|
formatterRegistry.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
|
||||||
|
|
||||||
|
// Default handling of monetary values
|
||||||
|
if (jsr354Present) {
|
||||||
|
formatterRegistry.addFormatter(new CurrencyUnitFormatter());
|
||||||
|
formatterRegistry.addFormatter(new MonetaryAmountFormatter());
|
||||||
|
formatterRegistry.addFormatterForFieldAnnotation(new Jsr354NumberFormatAnnotationFormatterFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default handling of date-time values
|
||||||
if (jsr310Present) {
|
if (jsr310Present) {
|
||||||
// just handling JSR-310 specific date and time types
|
// just handling JSR-310 specific date and time types
|
||||||
new DateTimeFormatterRegistrar().registerFormatters(formatterRegistry);
|
new DateTimeFormatterRegistrar().registerFormatters(formatterRegistry);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -43,10 +43,11 @@ import static org.junit.Assert.*;
|
||||||
*/
|
*/
|
||||||
public class DateFormatterTests {
|
public class DateFormatterTests {
|
||||||
|
|
||||||
|
private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public ExpectedException thown = ExpectedException.none();
|
public ExpectedException thown = ExpectedException.none();
|
||||||
|
|
||||||
private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldPrintAndParseDefault() throws Exception {
|
public void shouldPrintAndParseDefault() throws Exception {
|
||||||
|
|
@ -210,12 +211,12 @@ public class DateFormatterTests {
|
||||||
assertThat("uses style", formatter.print(date, Locale.US), is("6/1/09"));
|
assertThat("uses style", formatter.print(date, Locale.US), is("6/1/09"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Date getDate(int year, int month, int dayOfMonth) {
|
private Date getDate(int year, int month, int dayOfMonth) {
|
||||||
return getDate(year, month, dayOfMonth, 0, 0, 0, 0);
|
return getDate(year, month, dayOfMonth, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Date getDate(int year, int month, int dayOfMonth, int hour, int minute,
|
private Date getDate(int year, int month, int dayOfMonth, int hour, int minute, int second, int millisecond) {
|
||||||
int second, int millisecond) {
|
|
||||||
Calendar cal = Calendar.getInstance(Locale.US);
|
Calendar cal = Calendar.getInstance(Locale.US);
|
||||||
cal.setTimeZone(UTC);
|
cal.setTimeZone(UTC);
|
||||||
cal.clear();
|
cal.clear();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -46,10 +46,11 @@ import static org.junit.Assert.*;
|
||||||
*/
|
*/
|
||||||
public class DateFormattingTests {
|
public class DateFormattingTests {
|
||||||
|
|
||||||
private FormattingConversionService conversionService = new FormattingConversionService();
|
private final FormattingConversionService conversionService = new FormattingConversionService();
|
||||||
|
|
||||||
private DataBinder binder;
|
private DataBinder binder;
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
DateFormatterRegistrar registrar = new DateFormatterRegistrar();
|
DateFormatterRegistrar registrar = new DateFormatterRegistrar();
|
||||||
|
|
@ -73,6 +74,7 @@ public class DateFormattingTests {
|
||||||
LocaleContextHolder.setLocale(null);
|
LocaleContextHolder.setLocale(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBindDate() {
|
public void testBindDate() {
|
||||||
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -28,9 +28,10 @@ import static org.junit.Assert.*;
|
||||||
/**
|
/**
|
||||||
* @author Keith Donald
|
* @author Keith Donald
|
||||||
*/
|
*/
|
||||||
public class CurrencyFormatterTests {
|
public class CurrencyStyleFormatterTests {
|
||||||
|
|
||||||
|
private final CurrencyStyleFormatter formatter = new CurrencyStyleFormatter();
|
||||||
|
|
||||||
private CurrencyFormatter formatter = new CurrencyFormatter();
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void formatValue() {
|
public void formatValue() {
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -41,10 +41,11 @@ import static org.junit.Assert.*;
|
||||||
*/
|
*/
|
||||||
public class NumberFormattingTests {
|
public class NumberFormattingTests {
|
||||||
|
|
||||||
private FormattingConversionService conversionService = new FormattingConversionService();
|
private final FormattingConversionService conversionService = new FormattingConversionService();
|
||||||
|
|
||||||
private DataBinder binder;
|
private DataBinder binder;
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
DefaultConversionService.addDefaultConverters(conversionService);
|
DefaultConversionService.addDefaultConverters(conversionService);
|
||||||
|
|
@ -53,12 +54,13 @@ public class NumberFormattingTests {
|
||||||
public String resolveStringValue(String strVal) {
|
public String resolveStringValue(String strVal) {
|
||||||
if ("${pattern}".equals(strVal)) {
|
if ("${pattern}".equals(strVal)) {
|
||||||
return "#,##.00";
|
return "#,##.00";
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return strVal;
|
return strVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
conversionService.addFormatterForFieldType(Number.class, new NumberFormatter());
|
conversionService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
|
||||||
conversionService.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
|
conversionService.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
|
||||||
LocaleContextHolder.setLocale(Locale.US);
|
LocaleContextHolder.setLocale(Locale.US);
|
||||||
binder = new DataBinder(new TestBean());
|
binder = new DataBinder(new TestBean());
|
||||||
|
|
@ -70,6 +72,7 @@ public class NumberFormattingTests {
|
||||||
LocaleContextHolder.setLocale(null);
|
LocaleContextHolder.setLocale(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultNumberFormatting() {
|
public void testDefaultNumberFormatting() {
|
||||||
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
||||||
|
|
@ -172,6 +175,7 @@ public class NumberFormattingTests {
|
||||||
assertEquals("1,25.00,2,35.00", binder.getBindingResult().getFieldValue("patternList2"));
|
assertEquals("1,25.00,2,35.00", binder.getBindingResult().getFieldValue("patternList2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private static class TestBean {
|
private static class TestBean {
|
||||||
|
|
||||||
|
|
@ -261,7 +265,6 @@ public class NumberFormattingTests {
|
||||||
public void setPatternList2(List<BigDecimal> patternList2) {
|
public void setPatternList2(List<BigDecimal> patternList2) {
|
||||||
this.patternList2 = patternList2;
|
this.patternList2 = patternList2;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -27,9 +27,10 @@ import static org.junit.Assert.*;
|
||||||
/**
|
/**
|
||||||
* @author Keith Donald
|
* @author Keith Donald
|
||||||
*/
|
*/
|
||||||
public class NumberFormatterTests {
|
public class NumberStyleFormatterTests {
|
||||||
|
|
||||||
|
private final NumberStyleFormatter formatter = new NumberStyleFormatter();
|
||||||
|
|
||||||
private NumberFormatter formatter = new NumberFormatter();
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void formatValue() {
|
public void formatValue() {
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -27,9 +27,10 @@ import static org.junit.Assert.*;
|
||||||
/**
|
/**
|
||||||
* @author Keith Donald
|
* @author Keith Donald
|
||||||
*/
|
*/
|
||||||
public class PercentFormatterTests {
|
public class PercentStyleFormatterTests {
|
||||||
|
|
||||||
|
private final PercentStyleFormatter formatter = new PercentStyleFormatter();
|
||||||
|
|
||||||
private PercentFormatter formatter = new PercentFormatter();
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void formatValue() {
|
public void formatValue() {
|
||||||
|
|
@ -38,8 +39,7 @@ public class PercentFormatterTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseValue() throws ParseException {
|
public void parseValue() throws ParseException {
|
||||||
assertEquals(new BigDecimal(".2356"), formatter.parse("23.56%",
|
assertEquals(new BigDecimal(".2356"), formatter.parse("23.56%", Locale.US));
|
||||||
Locale.US));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = ParseException.class)
|
@Test(expected = ParseException.class)
|
||||||
|
|
@ -0,0 +1,244 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2015 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.format.number.money;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import javax.money.CurrencyUnit;
|
||||||
|
import javax.money.MonetaryAmount;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.beans.MutablePropertyValues;
|
||||||
|
import org.springframework.context.i18n.LocaleContextHolder;
|
||||||
|
import org.springframework.format.annotation.NumberFormat;
|
||||||
|
import org.springframework.format.support.DefaultFormattingConversionService;
|
||||||
|
import org.springframework.format.support.FormattingConversionService;
|
||||||
|
import org.springframework.validation.DataBinder;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 4.2
|
||||||
|
*/
|
||||||
|
public class MoneyFormattingTests {
|
||||||
|
|
||||||
|
private final FormattingConversionService conversionService = new DefaultFormattingConversionService();
|
||||||
|
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
LocaleContextHolder.setLocale(Locale.US);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
LocaleContextHolder.setLocale(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAmountAndUnit() {
|
||||||
|
DataBinder binder = new DataBinder(new MoneyHolder());
|
||||||
|
binder.setConversionService(conversionService);
|
||||||
|
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
||||||
|
propertyValues.add("amount", "USD 10.50");
|
||||||
|
propertyValues.add("unit", "USD");
|
||||||
|
binder.bind(propertyValues);
|
||||||
|
assertEquals(0, binder.getBindingResult().getErrorCount());
|
||||||
|
assertEquals("USD10.50", binder.getBindingResult().getFieldValue("amount"));
|
||||||
|
assertEquals("USD", binder.getBindingResult().getFieldValue("unit"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAmountWithNumberFormat1() {
|
||||||
|
DataBinder binder = new DataBinder(new FormattedMoneyHolder1());
|
||||||
|
binder.setConversionService(conversionService);
|
||||||
|
|
||||||
|
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
||||||
|
propertyValues.add("amount", "$10.50");
|
||||||
|
binder.bind(propertyValues);
|
||||||
|
assertEquals(0, binder.getBindingResult().getErrorCount());
|
||||||
|
assertEquals("$10.50", binder.getBindingResult().getFieldValue("amount"));
|
||||||
|
|
||||||
|
/* TODO: preserve currency from given value
|
||||||
|
LocaleContextHolder.setLocale(Locale.CANADA);
|
||||||
|
binder.bind(propertyValues);
|
||||||
|
LocaleContextHolder.setLocale(Locale.US);
|
||||||
|
assertEquals(0, binder.getBindingResult().getErrorCount());
|
||||||
|
assertEquals("$10.50", binder.getBindingResult().getFieldValue("amount"));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAmountWithNumberFormat2() {
|
||||||
|
DataBinder binder = new DataBinder(new FormattedMoneyHolder2());
|
||||||
|
binder.setConversionService(conversionService);
|
||||||
|
|
||||||
|
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
||||||
|
propertyValues.add("amount", "10.50");
|
||||||
|
binder.bind(propertyValues);
|
||||||
|
assertEquals(0, binder.getBindingResult().getErrorCount());
|
||||||
|
assertEquals("10.5", binder.getBindingResult().getFieldValue("amount"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAmountWithNumberFormat3() {
|
||||||
|
DataBinder binder = new DataBinder(new FormattedMoneyHolder3());
|
||||||
|
binder.setConversionService(conversionService);
|
||||||
|
|
||||||
|
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
||||||
|
propertyValues.add("amount", "10%");
|
||||||
|
binder.bind(propertyValues);
|
||||||
|
assertEquals(0, binder.getBindingResult().getErrorCount());
|
||||||
|
assertEquals("10%", binder.getBindingResult().getFieldValue("amount"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAmountWithNumberFormat4() {
|
||||||
|
DataBinder binder = new DataBinder(new FormattedMoneyHolder4());
|
||||||
|
binder.setConversionService(conversionService);
|
||||||
|
|
||||||
|
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
||||||
|
propertyValues.add("amount", "010.500");
|
||||||
|
binder.bind(propertyValues);
|
||||||
|
assertEquals(0, binder.getBindingResult().getErrorCount());
|
||||||
|
assertEquals("010.500", binder.getBindingResult().getFieldValue("amount"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAmountWithNumberFormat5() {
|
||||||
|
DataBinder binder = new DataBinder(new FormattedMoneyHolder5());
|
||||||
|
binder.setConversionService(conversionService);
|
||||||
|
|
||||||
|
MutablePropertyValues propertyValues = new MutablePropertyValues();
|
||||||
|
propertyValues.add("amount", "$ 10.50");
|
||||||
|
binder.bind(propertyValues);
|
||||||
|
assertEquals(0, binder.getBindingResult().getErrorCount());
|
||||||
|
assertEquals("$ 010.500", binder.getBindingResult().getFieldValue("amount"));
|
||||||
|
|
||||||
|
/* TODO: preserve currency from given value
|
||||||
|
LocaleContextHolder.setLocale(Locale.CANADA);
|
||||||
|
binder.bind(propertyValues);
|
||||||
|
LocaleContextHolder.setLocale(Locale.US);
|
||||||
|
assertEquals(0, binder.getBindingResult().getErrorCount());
|
||||||
|
assertEquals("$ 010.500", binder.getBindingResult().getFieldValue("amount"));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class MoneyHolder {
|
||||||
|
|
||||||
|
private MonetaryAmount amount;
|
||||||
|
|
||||||
|
private CurrencyUnit unit;
|
||||||
|
|
||||||
|
public MonetaryAmount getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(MonetaryAmount amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CurrencyUnit getUnit() {
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUnit(CurrencyUnit unit) {
|
||||||
|
this.unit = unit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class FormattedMoneyHolder1 {
|
||||||
|
|
||||||
|
@NumberFormat
|
||||||
|
private MonetaryAmount amount;
|
||||||
|
|
||||||
|
public MonetaryAmount getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(MonetaryAmount amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class FormattedMoneyHolder2 {
|
||||||
|
|
||||||
|
@NumberFormat(style = NumberFormat.Style.NUMBER)
|
||||||
|
private MonetaryAmount amount;
|
||||||
|
|
||||||
|
public MonetaryAmount getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(MonetaryAmount amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class FormattedMoneyHolder3 {
|
||||||
|
|
||||||
|
@NumberFormat(style = NumberFormat.Style.PERCENT)
|
||||||
|
private MonetaryAmount amount;
|
||||||
|
|
||||||
|
public MonetaryAmount getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(MonetaryAmount amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class FormattedMoneyHolder4 {
|
||||||
|
|
||||||
|
@NumberFormat(pattern = "#000.000#")
|
||||||
|
private MonetaryAmount amount;
|
||||||
|
|
||||||
|
public MonetaryAmount getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(MonetaryAmount amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class FormattedMoneyHolder5 {
|
||||||
|
|
||||||
|
@NumberFormat(pattern = "\u00A4 #000.000#")
|
||||||
|
private MonetaryAmount amount;
|
||||||
|
|
||||||
|
public MonetaryAmount getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(MonetaryAmount amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -28,7 +28,6 @@ import java.util.Properties;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.joda.time.format.DateTimeFormat;
|
import org.joda.time.format.DateTimeFormat;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
@ -53,7 +52,7 @@ import org.springframework.format.annotation.NumberFormat;
|
||||||
import org.springframework.format.datetime.joda.DateTimeParser;
|
import org.springframework.format.datetime.joda.DateTimeParser;
|
||||||
import org.springframework.format.datetime.joda.JodaDateTimeFormatAnnotationFormatterFactory;
|
import org.springframework.format.datetime.joda.JodaDateTimeFormatAnnotationFormatterFactory;
|
||||||
import org.springframework.format.datetime.joda.ReadablePartialPrinter;
|
import org.springframework.format.datetime.joda.ReadablePartialPrinter;
|
||||||
import org.springframework.format.number.NumberFormatter;
|
import org.springframework.format.number.NumberStyleFormatter;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
|
@ -67,6 +66,7 @@ public class FormattingConversionServiceTests {
|
||||||
|
|
||||||
private FormattingConversionService formattingService;
|
private FormattingConversionService formattingService;
|
||||||
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
formattingService = new FormattingConversionService();
|
formattingService = new FormattingConversionService();
|
||||||
|
|
@ -79,9 +79,10 @@ public class FormattingConversionServiceTests {
|
||||||
LocaleContextHolder.setLocale(null);
|
LocaleContextHolder.setLocale(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFormatFieldForTypeWithFormatter() throws ParseException {
|
public void testFormatFieldForTypeWithFormatter() throws ParseException {
|
||||||
formattingService.addFormatterForFieldType(Number.class, new NumberFormatter());
|
formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
|
||||||
String formatted = formattingService.convert(3, String.class);
|
String formatted = formattingService.convert(3, String.class);
|
||||||
assertEquals("3", formatted);
|
assertEquals("3", formatted);
|
||||||
Integer i = formattingService.convert("3", Integer.class);
|
Integer i = formattingService.convert("3", Integer.class);
|
||||||
|
|
@ -239,26 +240,26 @@ public class FormattingConversionServiceTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPrintNull() throws ParseException {
|
public void testPrintNull() throws ParseException {
|
||||||
formattingService.addFormatterForFieldType(Number.class, new NumberFormatter());
|
formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
|
||||||
assertEquals("", formattingService.convert(null, TypeDescriptor.valueOf(Integer.class), TypeDescriptor.valueOf(String.class)));
|
assertEquals("", formattingService.convert(null, TypeDescriptor.valueOf(Integer.class), TypeDescriptor.valueOf(String.class)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseNull() throws ParseException {
|
public void testParseNull() throws ParseException {
|
||||||
formattingService.addFormatterForFieldType(Number.class, new NumberFormatter());
|
formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
|
||||||
assertNull(formattingService
|
assertNull(formattingService
|
||||||
.convert(null, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
|
.convert(null, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseEmptyString() throws ParseException {
|
public void testParseEmptyString() throws ParseException {
|
||||||
formattingService.addFormatterForFieldType(Number.class, new NumberFormatter());
|
formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
|
||||||
assertNull(formattingService.convert("", TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
|
assertNull(formattingService.convert("", TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParseBlankString() throws ParseException {
|
public void testParseBlankString() throws ParseException {
|
||||||
formattingService.addFormatterForFieldType(Number.class, new NumberFormatter());
|
formattingService.addFormatterForFieldType(Number.class, new NumberStyleFormatter());
|
||||||
assertNull(formattingService.convert(" ", TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
|
assertNull(formattingService.convert(" ", TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(Integer.class)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -270,7 +271,7 @@ public class FormattingConversionServiceTests {
|
||||||
|
|
||||||
@Test(expected=ConversionFailedException.class)
|
@Test(expected=ConversionFailedException.class)
|
||||||
public void testParseNullPrimitiveProperty() throws ParseException {
|
public void testParseNullPrimitiveProperty() throws ParseException {
|
||||||
formattingService.addFormatterForFieldType(Integer.class, new NumberFormatter());
|
formattingService.addFormatterForFieldType(Integer.class, new NumberStyleFormatter());
|
||||||
assertNull(formattingService.convert(null, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(int.class)));
|
assertNull(formattingService.convert(null, TypeDescriptor.valueOf(String.class), TypeDescriptor.valueOf(int.class)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -48,7 +48,7 @@ import org.springframework.context.support.ResourceBundleMessageSource;
|
||||||
import org.springframework.context.support.StaticMessageSource;
|
import org.springframework.context.support.StaticMessageSource;
|
||||||
import org.springframework.core.convert.support.DefaultConversionService;
|
import org.springframework.core.convert.support.DefaultConversionService;
|
||||||
import org.springframework.format.Formatter;
|
import org.springframework.format.Formatter;
|
||||||
import org.springframework.format.number.NumberFormatter;
|
import org.springframework.format.number.NumberStyleFormatter;
|
||||||
import org.springframework.format.support.FormattingConversionService;
|
import org.springframework.format.support.FormattingConversionService;
|
||||||
import org.springframework.tests.sample.beans.BeanWithObjectProperty;
|
import org.springframework.tests.sample.beans.BeanWithObjectProperty;
|
||||||
import org.springframework.tests.sample.beans.DerivedTestBean;
|
import org.springframework.tests.sample.beans.DerivedTestBean;
|
||||||
|
|
@ -332,7 +332,7 @@ public class DataBinderTests extends TestCase {
|
||||||
DataBinder binder = new DataBinder(tb);
|
DataBinder binder = new DataBinder(tb);
|
||||||
FormattingConversionService conversionService = new FormattingConversionService();
|
FormattingConversionService conversionService = new FormattingConversionService();
|
||||||
DefaultConversionService.addDefaultConverters(conversionService);
|
DefaultConversionService.addDefaultConverters(conversionService);
|
||||||
conversionService.addFormatterForFieldType(Float.class, new NumberFormatter());
|
conversionService.addFormatterForFieldType(Float.class, new NumberStyleFormatter());
|
||||||
binder.setConversionService(conversionService);
|
binder.setConversionService(conversionService);
|
||||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||||
pvs.add("myFloat", "1,2");
|
pvs.add("myFloat", "1,2");
|
||||||
|
|
@ -363,7 +363,7 @@ public class DataBinderTests extends TestCase {
|
||||||
DataBinder binder = new DataBinder(tb);
|
DataBinder binder = new DataBinder(tb);
|
||||||
FormattingConversionService conversionService = new FormattingConversionService();
|
FormattingConversionService conversionService = new FormattingConversionService();
|
||||||
DefaultConversionService.addDefaultConverters(conversionService);
|
DefaultConversionService.addDefaultConverters(conversionService);
|
||||||
conversionService.addFormatterForFieldType(Float.class, new NumberFormatter());
|
conversionService.addFormatterForFieldType(Float.class, new NumberStyleFormatter());
|
||||||
binder.setConversionService(conversionService);
|
binder.setConversionService(conversionService);
|
||||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||||
pvs.add("myFloat", "1x2");
|
pvs.add("myFloat", "1x2");
|
||||||
|
|
@ -409,7 +409,7 @@ public class DataBinderTests extends TestCase {
|
||||||
DataBinder binder = new DataBinder(tb);
|
DataBinder binder = new DataBinder(tb);
|
||||||
FormattingConversionService conversionService = new FormattingConversionService();
|
FormattingConversionService conversionService = new FormattingConversionService();
|
||||||
DefaultConversionService.addDefaultConverters(conversionService);
|
DefaultConversionService.addDefaultConverters(conversionService);
|
||||||
conversionService.addFormatterForFieldType(Float.class, new NumberFormatter());
|
conversionService.addFormatterForFieldType(Float.class, new NumberStyleFormatter());
|
||||||
binder.setConversionService(conversionService);
|
binder.setConversionService(conversionService);
|
||||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||||
pvs.add("integerList[0]", "1");
|
pvs.add("integerList[0]", "1");
|
||||||
|
|
@ -430,7 +430,7 @@ public class DataBinderTests extends TestCase {
|
||||||
DataBinder binder = new DataBinder(tb);
|
DataBinder binder = new DataBinder(tb);
|
||||||
FormattingConversionService conversionService = new FormattingConversionService();
|
FormattingConversionService conversionService = new FormattingConversionService();
|
||||||
DefaultConversionService.addDefaultConverters(conversionService);
|
DefaultConversionService.addDefaultConverters(conversionService);
|
||||||
conversionService.addFormatterForFieldType(Float.class, new NumberFormatter());
|
conversionService.addFormatterForFieldType(Float.class, new NumberStyleFormatter());
|
||||||
binder.setConversionService(conversionService);
|
binder.setConversionService(conversionService);
|
||||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||||
pvs.add("integerList[0]", "1x2");
|
pvs.add("integerList[0]", "1x2");
|
||||||
|
|
@ -452,7 +452,7 @@ public class DataBinderTests extends TestCase {
|
||||||
DataBinder binder = new DataBinder(tb);
|
DataBinder binder = new DataBinder(tb);
|
||||||
FormattingConversionService conversionService = new FormattingConversionService();
|
FormattingConversionService conversionService = new FormattingConversionService();
|
||||||
DefaultConversionService.addDefaultConverters(conversionService);
|
DefaultConversionService.addDefaultConverters(conversionService);
|
||||||
conversionService.addFormatterForFieldType(Float.class, new NumberFormatter());
|
conversionService.addFormatterForFieldType(Float.class, new NumberStyleFormatter());
|
||||||
binder.setConversionService(conversionService);
|
binder.setConversionService(conversionService);
|
||||||
binder.initDirectFieldAccess();
|
binder.initDirectFieldAccess();
|
||||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||||
|
|
@ -485,7 +485,7 @@ public class DataBinderTests extends TestCase {
|
||||||
binder.initDirectFieldAccess();
|
binder.initDirectFieldAccess();
|
||||||
FormattingConversionService conversionService = new FormattingConversionService();
|
FormattingConversionService conversionService = new FormattingConversionService();
|
||||||
DefaultConversionService.addDefaultConverters(conversionService);
|
DefaultConversionService.addDefaultConverters(conversionService);
|
||||||
conversionService.addFormatterForFieldType(Float.class, new NumberFormatter());
|
conversionService.addFormatterForFieldType(Float.class, new NumberStyleFormatter());
|
||||||
binder.setConversionService(conversionService);
|
binder.setConversionService(conversionService);
|
||||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||||
pvs.add("myFloat", "1x2");
|
pvs.add("myFloat", "1x2");
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2015 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -26,7 +26,7 @@ import org.springframework.context.support.GenericApplicationContext;
|
||||||
import org.springframework.core.env.MapPropertySource;
|
import org.springframework.core.env.MapPropertySource;
|
||||||
import org.springframework.format.annotation.NumberFormat;
|
import org.springframework.format.annotation.NumberFormat;
|
||||||
import org.springframework.format.annotation.NumberFormat.Style;
|
import org.springframework.format.annotation.NumberFormat.Style;
|
||||||
import org.springframework.format.number.PercentFormatter;
|
import org.springframework.format.number.PercentStyleFormatter;
|
||||||
import org.springframework.format.support.FormattingConversionServiceFactoryBean;
|
import org.springframework.format.support.FormattingConversionServiceFactoryBean;
|
||||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||||
import org.springframework.mock.web.test.MockPageContext;
|
import org.springframework.mock.web.test.MockPageContext;
|
||||||
|
|
@ -71,7 +71,7 @@ public class EvalTagTests extends AbstractTagTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPrintFormattedScopedAttributeResult() throws Exception {
|
public void testPrintFormattedScopedAttributeResult() throws Exception {
|
||||||
PercentFormatter formatter = new PercentFormatter();
|
PercentStyleFormatter formatter = new PercentStyleFormatter();
|
||||||
tag.setExpression("bean.formattable");
|
tag.setExpression("bean.formattable");
|
||||||
int action = tag.doStartTag();
|
int action = tag.doStartTag();
|
||||||
assertEquals(Tag.EVAL_BODY_INCLUDE, action);
|
assertEquals(Tag.EVAL_BODY_INCLUDE, action);
|
||||||
|
|
@ -98,7 +98,8 @@ public class EvalTagTests extends AbstractTagTests {
|
||||||
assertEquals(Tag.EVAL_BODY_INCLUDE, action);
|
assertEquals(Tag.EVAL_BODY_INCLUDE, action);
|
||||||
action = tag.doEndTag();
|
action = tag.doEndTag();
|
||||||
assertEquals(Tag.EVAL_PAGE, action);
|
assertEquals(Tag.EVAL_PAGE, action);
|
||||||
assertEquals("function foo() { alert(\\\"hi\\\") }", ((MockHttpServletResponse)context.getResponse()).getContentAsString());
|
assertEquals("function foo() { alert(\\\"hi\\\") }",
|
||||||
|
((MockHttpServletResponse)context.getResponse()).getContentAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSetFormattedScopedAttributeResult() throws Exception {
|
public void testSetFormattedScopedAttributeResult() throws Exception {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue