001/*
002 *  jDTAUS Banking SPI
003 *  Copyright (C) 2005 Christian Schulte
004 *  <cs@schulte.it>
005 *
006 *  This library is free software; you can redistribute it and/or
007 *  modify it under the terms of the GNU Lesser General Public
008 *  License as published by the Free Software Foundation; either
009 *  version 2.1 of the License, or any later version.
010 *
011 *  This library is distributed in the hope that it will be useful,
012 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014 *  Lesser General Public License for more details.
015 *
016 *  You should have received a copy of the GNU Lesser General Public
017 *  License along with this library; if not, write to the Free Software
018 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
019 *
020 */
021package org.jdtaus.banking.dtaus.spi;
022
023import java.io.Serializable;
024import java.util.Currency;
025import java.util.HashMap;
026import java.util.HashSet;
027import java.util.Iterator;
028import java.util.Map;
029import java.util.Set;
030
031/**
032 * Utility class for maintaining a mapping of currencies to corresponding counters.
033 *
034 * <p><b>Note:</b><br/>This class is not synchronized and must not be used concurrently without external
035 * synchronization.</p>
036 *
037 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
038 * @version $JDTAUS: CurrencyCounter.java 8661 2012-09-27 11:29:58Z schulte $
039 */
040public class CurrencyCounter implements Serializable
041{
042
043    /** Serial version UID for backwards compatibility with 1.1.x classes. */
044    private static final long serialVersionUID = -2765988202184349786L;
045
046    /**
047     * Maps ISO currency codes to counters.
048     * @serial
049     */
050    private Map currencyMap;
051
052    /**
053     * Gets the currencies for which the instance holds counters.
054     *
055     * @return The currencies for which the instance holds counters.
056     */
057    public Currency[] getCurrencies()
058    {
059        final Set currencies = new HashSet( this.getCurrencyMap().size() );
060        for ( Iterator it = this.getCurrencyMap().entrySet().iterator(); it.hasNext(); )
061        {
062            final Map.Entry entry = (Map.Entry) it.next();
063            currencies.add( Currency.getInstance( (String) entry.getKey() ) );
064        }
065
066        return (Currency[]) currencies.toArray( new Currency[ currencies.size() ] );
067    }
068
069    /**
070     * Gets the value of the counter for a given {@code Currency}.
071     *
072     * @param currency The currency to return the value of the counter for.
073     *
074     * @return The value of the counter of {@code currency}.
075     *
076     * @throws NullPointerException if {@code currency} is {@code null}.
077     */
078    public long getValue( final Currency currency )
079    {
080        if ( currency == null )
081        {
082            throw new NullPointerException( "currency" );
083        }
084
085        final Long value = (Long) this.getCurrencyMap().get( currency.getCurrencyCode() );
086        return value != null ? value.longValue() : 0L;
087    }
088
089    /**
090     * Adds to the counter of a currency.
091     *
092     * @param currency The currency to add to.
093     *
094     * @throws NullPointerException if {@code currency} is {@code null}.
095     * @throws IndexOutOfBoundsException if the value of the counter of {@code currency} is equal to
096     * {@link Long#MAX_VALUE}.
097     */
098    public void add( final Currency currency )
099    {
100        if ( currency == null )
101        {
102            throw new NullPointerException( "currency" );
103        }
104
105        final long value = this.getValue( currency );
106
107        if ( value == Long.MAX_VALUE )
108        {
109            throw new IndexOutOfBoundsException();
110        }
111
112        this.getCurrencyMap().put( currency.getCurrencyCode(), new Long( value + 1L ) );
113    }
114
115    /**
116     * Substracts from the counter of a currency.
117     *
118     * @param currency The currency to substract from.
119     *
120     * @throws NullPointerException if {@code currency} is {@code null}.
121     * @throws IndexOutOfBoundsException if the value of the counter of {@code currency} is equal to zero.
122     */
123    public void substract( final Currency currency )
124    {
125        if ( currency == null )
126        {
127            throw new NullPointerException( "currency" );
128        }
129
130        final long value = this.getValue( currency );
131
132        if ( value == 0L )
133        {
134            throw new IndexOutOfBoundsException();
135        }
136
137        this.getCurrencyMap().put( currency.getCurrencyCode(), new Long( value - 1L ) );
138    }
139
140    /**
141     * Gets the {@code Map} backing the instance.
142     *
143     * @return The {@code Map} backing the instance.
144     */
145    private Map getCurrencyMap()
146    {
147        if ( this.currencyMap == null )
148        {
149            this.currencyMap = new HashMap( 10 );
150        }
151
152        return this.currencyMap;
153    }
154
155}