001/*
002 *  jDTAUS Banking API
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;
022
023import java.io.Serializable;
024
025/**
026 * "E" record.
027 *
028 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
029 * @version $JDTAUS: Checksum.java 8661 2012-09-27 11:29:58Z schulte $
030 */
031public class Checksum implements Cloneable, Serializable
032{
033
034    /** Serial version UID for backwards compatibility with 1.0.x classes. */
035    private static final long serialVersionUID = -7639085407620663083L;
036
037    /**
038     * Number of transactions stored in a logical file.
039     * @serial
040     */
041    private int transactionCount;
042
043    /**
044     * Sum of all target account codes of all transactions stored in a logical file.
045     * @serial
046     */
047    private long sumTargetAccount;
048
049    /**
050     * Sum of all target bank codes of all transactions stored in a logical file.
051     * @serial
052     */
053    private long sumTargetBank;
054
055    /**
056     * Sum of all amounts of all transactions stored in a logical file.
057     * @serial
058     */
059    private long sumAmount;
060
061    /** Cached hash code. */
062    private transient int hashCode = NO_HASHCODE;
063    private static final int NO_HASHCODE = Integer.MIN_VALUE;
064
065    /** Creates a new {@code Checksum} instance. */
066    public Checksum()
067    {
068        super();
069    }
070
071    /**
072     * Getter for property {@code transactionCount}.
073     *
074     * @return Number of transactions stored in a logical file.
075     */
076    public int getTransactionCount()
077    {
078        return this.transactionCount;
079    }
080
081    /**
082     * Setter for property {@code transactionCount}.
083     *
084     * @param value Number of transactions stored in a logical file.
085     */
086    public void setTransactionCount( final int value )
087    {
088        this.transactionCount = value;
089        this.hashCode = NO_HASHCODE;
090    }
091
092    /**
093     * Getter for property {@code sumTargetAccount}.
094     *
095     * @return Sum of all target account codes of all transactions stored in a logical file.
096     */
097    public long getSumTargetAccount()
098    {
099        return this.sumTargetAccount;
100    }
101
102    /**
103     * Setter for property {@code sumTargetAccount}.
104     *
105     * @param value Sum of all target account codes of all transactions stored in a logical file.
106     */
107    public void setSumTargetAccount( final long value )
108    {
109        this.sumTargetAccount = value;
110        this.hashCode = NO_HASHCODE;
111    }
112
113    /**
114     * Getter for property {@code sumTargetBank}.
115     *
116     * @return Sum of all target bank codes of all transactions stored in a logical file.
117     */
118    public long getSumTargetBank()
119    {
120        return this.sumTargetBank;
121    }
122
123    /**
124     * Setter for property {@code sumTargetBank}.
125     *
126     * @param value Sum of all target bank codes of all transactions stored in a logical file.
127     */
128    public void setSumTargetBank( final long value )
129    {
130        this.sumTargetBank = value;
131        this.hashCode = NO_HASHCODE;
132    }
133
134    /**
135     * Getter for property {@code sumAmount}.
136     *
137     * @return Sum of all amounts of all transactions stored in a logical file.
138     */
139    public long getSumAmount()
140    {
141        return this.sumAmount;
142    }
143
144    /**
145     * Setter for property {@code sumAmount}.
146     *
147     * @param value Sum of all amounts of all transactions stored in a logical file.
148     */
149    public void setSumAmount( final long value )
150    {
151        this.sumAmount = value;
152        this.hashCode = NO_HASHCODE;
153    }
154
155    /**
156     * Adds a {@code Transaction} to the checksum.
157     *
158     * @param transaction The transaction to add to the checksum.
159     *
160     * @throws NullPointerException if {@code transaction} is {@code null}.
161     */
162    public void add( final Transaction transaction )
163    {
164        if ( transaction == null )
165        {
166            throw new NullPointerException( "transaction" );
167        }
168
169        this.sumAmount += transaction.getAmount().longValue(); // TODO longValueExact()
170        this.sumTargetAccount += transaction.getTargetAccount().longValue();
171        this.sumTargetBank += transaction.getTargetBank().longValue();
172        this.hashCode = NO_HASHCODE;
173    }
174
175    /**
176     * Subtracts a {@code Transaction} from the checksum.
177     *
178     * @param transaction The transaction to subtract from the checksum.
179     *
180     * @throws NullPointerException if {@code transaction} is {@code null}.
181     * @deprecated Deprecated by {@link #subtract(Transaction) subtract}.
182     */
183    public final void substract( final Transaction transaction )
184    {
185        this.subtract( transaction );
186    }
187
188    /**
189     * Subtracts a {@code Transaction} from the checksum.
190     *
191     * @param transaction The transaction to subtract from the checksum.
192     *
193     * @throws NullPointerException if {@code transaction} is {@code null}.
194     */
195    public void subtract( final Transaction transaction )
196    {
197        if ( transaction == null )
198        {
199            throw new NullPointerException( "transaction" );
200        }
201
202        this.sumAmount -= transaction.getAmount().longValue(); // TODO longValueExact()
203        this.sumTargetAccount -= transaction.getTargetAccount().longValue();
204        this.sumTargetBank -= transaction.getTargetBank().longValue();
205        this.hashCode = NO_HASHCODE;
206    }
207
208    /**
209     * Indicates whether some other object is equal to this one by comparing the values of all properties.
210     *
211     * @param o The reference object with which to compare.
212     *
213     * @return {@code true} if this object is the same as {@code o}; {@code false} otherwise.
214     */
215    public boolean equals( final Object o )
216    {
217        boolean equal = o == this;
218
219        if ( !equal && o instanceof Checksum )
220        {
221            final Checksum that = (Checksum) o;
222            equal = this.getSumAmount() == that.getSumAmount() &&
223                    this.getSumTargetAccount() == that.getSumTargetAccount() &&
224                    this.getSumTargetBank() == that.getSumTargetBank() &&
225                    this.getTransactionCount() == that.getTransactionCount();
226
227        }
228
229        return equal;
230    }
231
232    /**
233     * Returns a hash code value for this object.
234     *
235     * @return A hash code value for this object.
236     */
237    public int hashCode()
238    {
239        if ( this.hashCode == NO_HASHCODE )
240        {
241            int hc = 23;
242            hc = 37 * hc + (int) ( this.sumAmount ^ ( this.sumAmount >>> 32 ) );
243            hc = 37 * hc + (int) ( this.sumTargetAccount ^ ( this.sumTargetAccount >>> 32 ) );
244            hc = 37 * hc + (int) ( this.sumTargetBank ^ ( this.sumTargetBank >>> 32 ) );
245            hc = 37 * hc + this.transactionCount;
246            this.hashCode = hc;
247        }
248
249        return this.hashCode;
250    }
251
252    /**
253     * Creates and returns a copy of this object.
254     *
255     * @return A clone of this instance.
256     */
257    public Object clone()
258    {
259        try
260        {
261            return super.clone();
262        }
263        catch ( final CloneNotSupportedException e )
264        {
265            throw new AssertionError( e );
266        }
267    }
268
269    /**
270     * Returns a string representation of the object.
271     *
272     * @return A string representation of the object.
273     */
274    public String toString()
275    {
276        return super.toString() + this.internalString();
277    }
278
279    /**
280     * Creates a string representing the properties of the instance.
281     *
282     * @return A string representing the properties of the instance.
283     */
284    private String internalString()
285    {
286        return new StringBuffer( 100 ).append( '{' ).
287            append( "sumAmount=" ).append( this.sumAmount ).
288            append( ", sumTargetAccount=" ).append( this.sumTargetAccount ).
289            append( ", sumTargetBank=" ).append( this.sumTargetBank ).
290            append( ", transactionCount=" ).append( this.transactionCount ).
291            append( '}' ).toString();
292
293    }
294
295}