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