001    
002    package data;
003    
004    import java.text.NumberFormat;
005    import java.text.ParseException;
006    import java.util.Locale;
007    
008    import data.ooimpl.CatalogImpl;
009    import data.ooimpl.CurrencyItemImpl;
010    
011    /**
012     * Abstract Java implementation of the {@link Currency} interface.
013     *
014     * @author  Thomas Medack
015     * @version 3.0
016     */
017    public abstract class AbstractCurrency extends CatalogImpl implements Currency {
018    
019        /**
020         * Data container for names and values of CurrencyItems.
021         */
022        protected class CurrencyItemData {
023            private String name;
024            private int value;
025    
026            /**
027             * Constructor
028             *
029             * @param name the name of the CurrencyItem.
030             * @param value the appropriate value of the CurrencyItem.
031             */
032            public CurrencyItemData(String name, int value) {
033                this.value = value;
034                this.name = name;
035            }
036    
037            /**
038             * Returns the name of a CurrencyItem in this data container.
039             *
040             * @return the name of the CurrencyItem.
041             */
042            public String getName() {
043                return name;
044            }
045    
046            /**
047             * Returns the value of a CurrencyItem in this data container.
048             *
049             * @return the value of the CurrencyItem.
050             */
051            public int getValue() {
052                return value;
053            }
054        }
055    
056        /**
057         * Tool used to format and parse currency values.
058         *
059         * @serial
060         */
061        private NumberFormat m_nfFormatter;
062    
063        /**
064         * Create a new, initially empty AbstractCurrency for the given locale.
065         *
066         * @param sName the name of the currency to create.
067         * @param l the locale that determines how currency values will be formatted.
068         */
069        public AbstractCurrency(String sName, Locale l) {
070            super(sName);
071    
072            m_nfFormatter = NumberFormat.getCurrencyInstance(l);
073    
074            initCurrencyItems();
075        }
076    
077        /**
078         * Create a new AbstractCurrency with a default locale of {@link Locale#GERMANY} and fill it.
079         *
080         * @param sName the name of the new currency.
081         */
082        public AbstractCurrency(String sName) {
083            this(sName, Locale.GERMANY);
084        }
085    
086        /**
087         * Initializes all CurrencyItems in this container with names and values.
088         */
089        private void initCurrencyItems() {
090            CurrencyItemData[] data = getCurrencyItemData();
091    
092            for (int i = 0; i < data.length; i++) {
093                add(new CurrencyItemImpl(data[i].getName(), data[i].getValue()), null);
094            }
095        }
096    
097        /**
098         * Try to interpret the given {@link String} according to the currency format of the specific currency.
099         *
100         * @override Always
101         * @param s the text to be parsed
102         * @return the interpreted value in the smallest unit of the currency.
103         * @exception ParseException if the input could not be parsed.
104         */
105        public NumberValue parse(String s) throws ParseException {
106            int j = 1;
107            for (int i = 1; i <= m_nfFormatter.getMinimumFractionDigits(); i++) {
108                j *= 10;
109            }
110    
111            // 10/27/2000-sz9: Fixed to use round instead a simple cast to int.
112            return new IntegerValue((int)java.lang.Math.round(m_nfFormatter.parse(s).doubleValue() * j));
113        }
114    
115        /**
116         * Convert the given value into a {@link String} representation according to the currency format of the
117         * specific currency. <code>nv</code> must be given in the smallest unit of the currency, i.e. if you want
118         * to specify 5,05 DM <code>nv</code> should be 505.
119         *
120         * @override Always
121         * @param nv the value to be converted
122         * @return formatted String.
123         */
124        public String toString(NumberValue nv) {
125            int j = 1;
126            for (int i = 1; i <= m_nfFormatter.getMinimumFractionDigits(); i++) {
127                j *= 10;
128            }
129    
130            return m_nfFormatter.format(nv.getValue().doubleValue() / j);
131        }
132    
133        /**
134         * This abstract method allows the programmer to choose the names and values of the
135         * CurrencyItems (EURO, DM, ...).
136         *
137         * A complete list of data containers, which always contain pairs of name and value, has to be returned.
138         * The single CurrencyItems can be found in the Catalog (Currency) with those names.
139         *
140         * @return an Array of data containers that contain names and values of CurrencyItems to be added.
141         */
142        protected abstract CurrencyItemData[] getCurrencyItemData();
143    }