001    package org.springframework.binding.format.support;
002    
003    import java.text.AttributedCharacterIterator;
004    import java.text.FieldPosition;
005    import java.text.NumberFormat;
006    import java.text.ParseException;
007    import java.text.ParsePosition;
008    import java.util.Currency;
009    
010    /**
011     * This is a decorator class for NumberFormat to ensure an exact number parsing.
012     * The {@link NumberFormat} class allows parsing of numbers in strings like
013     * '2abc' but at the richclient end we don't want this to be a valid parsing.
014     * Therefor a specific NumberFormat that doesn't allow any other input than a
015     * number.
016     *
017     * @author Yudhi Widyatama
018     * @author Jan Hoskens
019     *
020     */
021    public class StrictNumberFormat extends NumberFormat {
022            NumberFormat inner;
023    
024            public StrictNumberFormat(NumberFormat instance) {
025                    inner = instance;
026            }
027    
028            public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
029                    return inner.format(number, toAppendTo, pos);
030            }
031    
032            public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
033                    return inner.format(number, toAppendTo, pos);
034            }
035    
036            public StringBuffer format(Object number, StringBuffer toAppendTo, FieldPosition pos) {
037                    return inner.format(number, toAppendTo, pos);
038            }
039    
040            public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
041                    return inner.formatToCharacterIterator(obj);
042            }
043    
044            public Currency getCurrency() {
045                    return inner.getCurrency();
046            }
047    
048            public int getMaximumFractionDigits() {
049                    return inner.getMaximumFractionDigits();
050            }
051    
052            public int getMaximumIntegerDigits() {
053                    return inner.getMaximumIntegerDigits();
054            }
055    
056            public int getMinimumFractionDigits() {
057                    return inner.getMinimumFractionDigits();
058            }
059    
060            public int getMinimumIntegerDigits() {
061                    return inner.getMinimumIntegerDigits();
062            }
063    
064            public int hashCode() {
065                    return inner.hashCode();
066            }
067    
068            public boolean isGroupingUsed() {
069                    return inner.isGroupingUsed();
070            }
071    
072            public boolean isParseIntegerOnly() {
073                    return inner.isParseIntegerOnly();
074            }
075    
076            public Number parse(String source, ParsePosition parsePosition) {
077                    return inner.parse(source, parsePosition);
078            }
079    
080            public Number parse(String source) throws ParseException {
081                    // idea taken from
082                    // org.apache.commons.validator.routines.AbstractFormatValidator
083                    ParsePosition parsePosition = new ParsePosition(0);
084                    Number result = inner.parse(source, parsePosition);
085                    if (parsePosition.getErrorIndex() > -1)
086                            throw new ParseException("Invalid format", parsePosition.getIndex());
087                    if (parsePosition.getIndex() < source.length())
088                            throw new ParseException("Invalid format[ii]", parsePosition.getIndex());
089                    return result;
090            }
091    
092            public Object parseObject(String source) throws ParseException {
093                    return inner.parseObject(source);
094            }
095    
096            public void setCurrency(Currency currency) {
097                    inner.setCurrency(currency);
098            }
099    
100            public void setGroupingUsed(boolean newValue) {
101                    inner.setGroupingUsed(newValue);
102            }
103    
104            public void setMaximumFractionDigits(int newValue) {
105                    inner.setMaximumFractionDigits(newValue);
106            }
107    
108            public void setMaximumIntegerDigits(int newValue) {
109                    inner.setMaximumIntegerDigits(newValue);
110            }
111    
112            public void setMinimumFractionDigits(int newValue) {
113                    inner.setMinimumFractionDigits(newValue);
114            }
115    
116            public void setMinimumIntegerDigits(int newValue) {
117                    inner.setMinimumIntegerDigits(newValue);
118            }
119    
120            public void setParseIntegerOnly(boolean value) {
121                    inner.setParseIntegerOnly(value);
122            }
123    }