1 /*
2 * jDTAUS Banking API
3 * Copyright (C) 2005 Christian Schulte
4 * <cs@schulte.it>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 *
20 */
21 package org.jdtaus.banking;
22
23 import java.lang.ref.Reference;
24 import java.lang.ref.SoftReference;
25 import java.text.DecimalFormat;
26 import java.text.ParseException;
27 import java.text.ParsePosition;
28 import java.util.Collections;
29 import java.util.HashMap;
30 import java.util.Map;
31
32 /**
33 * Unique identifier to a particular office (branch) of a german bank.
34 * <p>A Bankleitzahl (BLZ) is a positive integer with a maximum of eight digits. For further information see the
35 * <a href="../../../doc-files/merkblatt_bankleitzahlendatei.pdf">Merkblatt Bankleitzahlendatei</a>. An updated version of the document
36 * may be found at <a href="http://www.bundesbank.de">Deutsche Bundesbank</a>.</p>
37 *
38 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
39 * @version $JDTAUS: Bankleitzahl.java 8725 2012-10-04 21:26:50Z schulte $
40 *
41 * @see BankleitzahlenVerzeichnis
42 */
43 public final class Bankleitzahl extends Number implements Comparable
44 {
45
46 /**
47 * Constant for the electronic format of a Bankleitzahl.
48 * <p>The electronic format of a Bankleitzahl is an eigth digit number with leading zeros omitted (e.g. 5678).</p>
49 */
50 public static final int ELECTRONIC_FORMAT = 3001;
51
52 /**
53 * Constant for the letter format of a Bankleitzahl.
54 * <p>The letter format of a Bankleitzahl is an eigth digit number with leading zeros omitted separated by spaces
55 * between the first three digits and the second three digits, and between the second three digits and the last two
56 * digits (e.g. 123 456 78).</p>
57 */
58 public static final int LETTER_FORMAT = 3002;
59
60 /** Maximum number of digits of a Bankleitzahl. */
61 public static final int MAX_DIGITS = 8;
62
63 /** Maximum number of characters of a Bankleitzahl. */
64 public static final int MAX_CHARACTERS = 10;
65
66 /** {@code 10^0..10^7}. */
67 private static final double[] EXP10 =
68 {
69 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
70 };
71
72 /** Serial version UID for backwards compatibility with 1.0.x classes. */
73 private static final long serialVersionUID = -3329406998979147668L;
74
75 /** Used to cache instances. */
76 private static volatile Reference cacheReference = new SoftReference( null );
77
78 /**
79 * German bank code.
80 * @serial
81 */
82 private int blz;
83
84 /**
85 * Clearing area code of this Bankleitzahl.
86 * @serial
87 */
88 private int clearingArea;
89
90 /**
91 * Locality code of this Bankleitzahl.
92 * @serial
93 */
94 private int localityCode;
95
96 /**
97 * Network code of this Bankleitzahl.
98 * @serial
99 */
100 private int networkCode;
101
102 /**
103 * Institute code of this Bankleitzahl.
104 * @serial
105 */
106 private int instituteCode;
107
108 /**
109 * Creates a new {@code Bankleitzahl} instance.
110 *
111 * @param bankCode The integer to create an instance from.
112 *
113 * @throws IllegalArgumentException if {@code bankCode} is negative, zero, greater than 99999999 or its first digit
114 * is either zero or nine.
115 *
116 * @see #checkBankleitzahl(Number)
117 */
118 private Bankleitzahl( final Number bankCode )
119 {
120 if ( !Bankleitzahl.checkBankleitzahl( bankCode ) )
121 {
122 throw new IllegalArgumentException( bankCode.toString() );
123 }
124
125 final int[] digits = Bankleitzahl.toDigits( bankCode.longValue() );
126 final long lCode = bankCode.longValue();
127
128 this.clearingArea = digits[7];
129 this.localityCode = (int) Math.floor( lCode / Bankleitzahl.EXP10[5] );
130 this.networkCode = digits[4];
131 this.instituteCode =
132 (int) Math.floor( lCode - digits[7] * Bankleitzahl.EXP10[7] -
133 digits[6] * Bankleitzahl.EXP10[6] -
134 digits[5] * Bankleitzahl.EXP10[5] -
135 digits[4] * Bankleitzahl.EXP10[4] );
136
137 this.blz = bankCode.intValue();
138 }
139
140 /**
141 * Parses text from a string to produce a {@code Bankleitzahl}.
142 * <p>The method attempts to parse text starting at the index given by {@code pos}. If parsing succeeds, then the
143 * index of {@code pos} is updated to the index after the last character used (parsing does not necessarily use all
144 * characters up to the end of the string), and the parsed value is returned. The updated {@code pos} can be used to
145 * indicate the starting point for the next call to this method.</p>
146 *
147 * @param bankCode A Bankleitzahl in either electronic or letter format.
148 * @param pos A {@code ParsePosition} object with index and error index information as described above.
149 *
150 * @return The parsed value, or {@code null} if the parse fails.
151 *
152 * @throws NullPointerException if either {@code bankCode} or {@code pos} is {@code null}.
153 */
154 public static Bankleitzahl parse( final String bankCode, final ParsePosition pos )
155 {
156 if ( bankCode == null )
157 {
158 throw new NullPointerException( "bankCode" );
159 }
160 if ( pos == null )
161 {
162 throw new NullPointerException( "pos" );
163 }
164
165 Bankleitzahl ret = null;
166 boolean sawSpace = false;
167 boolean failed = false;
168 final ParsePosition fmtPos = new ParsePosition( 0 );
169 final int len = bankCode.length();
170 final int startIndex = pos.getIndex();
171 final int maxIndex = startIndex + MAX_CHARACTERS;
172 final StringBuffer digits = new StringBuffer( MAX_DIGITS );
173 int mode = ELECTRONIC_FORMAT;
174 int part = 0;
175 int partStart = 0;
176 int partEnd = 2;
177 int digit = 0;
178 int i = startIndex;
179
180 for ( ; i < len && i < maxIndex && digits.length() < MAX_DIGITS; i++ )
181 {
182 final char c = bankCode.charAt( i );
183
184 if ( Character.isDigit( c ) )
185 {
186 sawSpace = false;
187
188 if ( mode == LETTER_FORMAT )
189 {
190 if ( digit < partStart || digit > partEnd )
191 {
192 failed = true;
193 }
194 else
195 {
196 digits.append( c );
197 }
198 }
199 else
200 {
201 digits.append( c );
202 }
203
204 digit++;
205 }
206 else if ( c == ' ' )
207 {
208 if ( sawSpace || i == startIndex || ( mode == ELECTRONIC_FORMAT && digit != 3 ) )
209 {
210 failed = true;
211 }
212 else
213 {
214 mode = LETTER_FORMAT;
215 switch ( part )
216 {
217 case 0:
218 partStart = 3;
219 partEnd = 5;
220 break;
221 case 1:
222 partStart = 6;
223 partEnd = 7;
224 break;
225 default:
226 failed = true;
227 break;
228 }
229 part++;
230
231 if ( digit < partStart || digit > partEnd )
232 {
233 failed = true;
234 }
235 }
236
237 sawSpace = true;
238 }
239 else
240 {
241 failed = true;
242 }
243
244 if ( failed )
245 {
246 pos.setErrorIndex( i );
247 break;
248 }
249 }
250
251 if ( !failed )
252 {
253 final Number num = new DecimalFormat( "########" ).parse( digits.toString(), fmtPos );
254
255 if ( num != null && fmtPos.getErrorIndex() == -1 )
256 {
257 final String key = num.toString();
258 ret = (Bankleitzahl) getCache().get( key );
259
260 if ( ret == null )
261 {
262 if ( !Bankleitzahl.checkBankleitzahl( num ) )
263 {
264 pos.setErrorIndex( startIndex );
265 ret = null;
266 }
267 else
268 {
269 pos.setIndex( i );
270 ret = new Bankleitzahl( num );
271 getCache().put( key, ret );
272 }
273 }
274 else
275 {
276 pos.setIndex( i );
277 }
278 }
279 else
280 {
281 pos.setErrorIndex( startIndex );
282 }
283 }
284
285 return ret;
286 }
287
288 /**
289 * Parses text from the beginning of the given string to produce a {@code Bankleitzahl}.
290 * <p>Unlike the {@link #parse(String, ParsePosition)} method this method throws a {@code ParseException} if
291 * {@code bankCode} cannot be parsed or is of invalid length.</p>
292 *
293 * @param bankCode A Bankleitzahl in either electronic or letter format.
294 *
295 * @return The parsed value.
296 *
297 * @throws NullPointerException if {@code bankCode} is {@code null}.
298 * @throws ParseException if the parse fails or {@code bankCode} is of invalid length.
299 */
300 public static Bankleitzahl parse( final String bankCode ) throws ParseException
301 {
302 if ( bankCode == null )
303 {
304 throw new NullPointerException( "bankCode" );
305 }
306
307 Bankleitzahl blz = (Bankleitzahl) getCache().get( bankCode );
308
309 if ( blz == null )
310 {
311 final ParsePosition pos = new ParsePosition( 0 );
312 blz = Bankleitzahl.parse( bankCode, pos );
313
314 if ( blz == null || pos.getErrorIndex() != -1 || pos.getIndex() < bankCode.length() )
315 {
316 throw new ParseException( bankCode, pos.getErrorIndex() != -1 ? pos.getErrorIndex() : pos.getIndex() );
317 }
318 else
319 {
320 getCache().put( bankCode, blz );
321 }
322 }
323
324 return blz;
325 }
326
327 /**
328 * Gets a {@code Bankleitzahl} for a given number.
329 *
330 * @param bankCode A number to get a {@code Bankleitzahl} for.
331 *
332 * @return An instance for {@code bankCode}.
333 *
334 * @throws NullPointerException if {@code bankCode} is {@code null}.
335 * @throws IllegalArgumentException if {@code bankCode} is negative, zero, greater than 99999999 or its first digit
336 * is either zero or nine.
337 *
338 * @see #checkBankleitzahl(Number)
339 */
340 public static Bankleitzahl valueOf( final Number bankCode )
341 {
342 if ( bankCode == null )
343 {
344 throw new NullPointerException( "bankCode" );
345 }
346
347 final String key = bankCode.toString();
348 Bankleitzahl ret = (Bankleitzahl) getCache().get( key );
349
350 if ( ret == null )
351 {
352 ret = new Bankleitzahl( bankCode );
353 getCache().put( key, ret );
354 }
355
356 return ret;
357 }
358
359 /**
360 * Parses text from the beginning of the given string to produce a {@code Bankleitzahl}.
361 * <p>Unlike the {@link #parse(String)} method this method throws an {@code IllegalArgumentException} if
362 * {@code bankCode} cannot be parsed or is of invalid length.</p>
363 *
364 * @param bankCode A Bankleitzahl in either electronic or letter format.
365 *
366 * @return The parsed value.
367 *
368 * @throws NullPointerException if {@code bankCode} is {@code null}.
369 * @throws IllegalArgumentException if the parse fails or {@code bankCode} is of invalid length.
370 */
371 public static Bankleitzahl valueOf( final String bankCode )
372 {
373 try
374 {
375 return Bankleitzahl.parse( bankCode );
376 }
377 catch ( final ParseException e )
378 {
379 throw (IllegalArgumentException) new IllegalArgumentException( bankCode ).initCause( e );
380 }
381 }
382
383 /**
384 * Checks a given number to conform to a Bankleitzahl.
385 *
386 * @param bankCode The number to check.
387 *
388 * @return {@code true} if {@code bankCode} is a valid Bankleitzahl; {@code false} if not.
389 */
390 public static boolean checkBankleitzahl( final Number bankCode )
391 {
392 boolean valid = bankCode != null;
393
394 if ( valid )
395 {
396 final long num = bankCode.longValue();
397 valid = num > 0L && num < 100000000L;
398 if ( valid && num > 9999999 )
399 {
400 final int[] digits = Bankleitzahl.toDigits( num );
401 valid = digits[7] != 0 && digits[7] != 9;
402 }
403 }
404
405 return valid;
406 }
407
408 /**
409 * Returns this Bankleitzahl as an int value.
410 *
411 * @return This Bankleitzahl as an int value.
412 */
413 public int intValue()
414 {
415 return this.blz;
416 }
417
418 /**
419 * Returns this Bankleitzahl as a long value.
420 *
421 * @return This Bankleitzahl as a long value.
422 */
423 public long longValue()
424 {
425 return this.blz;
426 }
427
428 /**
429 * Returns this Bankleitzahl as a float value.
430 *
431 * @return This Bankleitzahl as a float value.
432 */
433 public float floatValue()
434 {
435 return this.blz;
436 }
437
438 /**
439 * Returns this Bankleitzahl as a double value.
440 *
441 * @return This Bankleitzahl as a double value.
442 */
443 public double doubleValue()
444 {
445 return this.blz;
446 }
447
448 /**
449 * Gets a flag indicating that this Bankleitzahl provides a clearing area code.
450 *
451 * @return {@code true} if property {@code clearingAreaCode} is supported by this instance; {@code false} if
452 * property {@code clearingAreaCode} is not supported by this instance.
453 *
454 * @see #getClearingAreaCode()
455 */
456 public boolean isClearingAreaCodeSupported()
457 {
458 return this.blz > 9999999;
459 }
460
461 /**
462 * Gets the clearing area code of this Bankleitzahl.
463 * <p><ol>
464 * <li>Berlin, Brandenburg, Mecklenburg-Vorpommern</li>
465 * <li>Bremen, Hamburg, Niedersachsen, Schleswig-Holstein</li>
466 * <li>Rheinland (Regierungsbezirke Düsseldorf, Köln)</li>
467 * <li>Westfalen</li>
468 * <li>Hessen, Rheinland-Pfalz, Saarland</li>
469 * <li>Baden-Württemberg</li>
470 * <li>Bayern</li>
471 * <li>Sachsen, Sachsen-Anhalt, Thüringen</li>
472 * </ol></p>
473 *
474 * @return Code identifying the clearing area of this Bankleitzahl.
475 *
476 * @throws UnsupportedOperationException if this Bankleitzahl does not provide clearing area information.
477 *
478 * @see #isClearingAreaCodeSupported()
479 *
480 * @deprecated Renamed to {@link #getClearingAreaCode() }.
481 */
482 public int getClearingArea()
483 {
484 return this.getClearingAreaCode();
485 }
486
487 /**
488 * Gets the clearing area code of this Bankleitzahl.
489 * <p><ol>
490 * <li>Berlin, Brandenburg, Mecklenburg-Vorpommern</li>
491 * <li>Bremen, Hamburg, Niedersachsen, Schleswig-Holstein</li>
492 * <li>Rheinland (Regierungsbezirke Düsseldorf, Köln)</li>
493 * <li>Westfalen</li>
494 * <li>Hessen, Rheinland-Pfalz, Saarland</li>
495 * <li>Baden-Württemberg</li>
496 * <li>Bayern</li>
497 * <li>Sachsen, Sachsen-Anhalt, Thüringen</li>
498 * </ol></p>
499 *
500 * @return Code identifying the clearing area of this Bankleitzahl.
501 *
502 * @throws UnsupportedOperationException if this Bankleitzahl does not provide clearing area information.
503 *
504 * @see #isClearingAreaCodeSupported()
505 */
506 public int getClearingAreaCode()
507 {
508 if ( !this.isClearingAreaCodeSupported() )
509 {
510 throw new UnsupportedOperationException();
511 }
512
513 return this.clearingArea;
514 }
515
516 /**
517 * Gets a flag indicating that this Bankleitzahl provides a locality code.
518 *
519 * @return {@code true} if property {@code localityCode} is supported by this instance; {@code false} if property
520 * {@code localityCode} is not supported by this instance.
521 *
522 * @see #getLocalityCode()
523 */
524 public boolean isLocalityCodeSupported()
525 {
526 return this.blz > 99999;
527 }
528
529 /**
530 * Gets the locality code of this Bankleitzahl.
531 *
532 * @return Locality code of this Bankleitzahl.
533 *
534 * @throws UnsupportedOperationException if this Bankleitzahl does not provide a locality code.
535 *
536 * @see #isLocalityCodeSupported()
537 */
538 public int getLocalityCode()
539 {
540 if ( !this.isLocalityCodeSupported() )
541 {
542 throw new UnsupportedOperationException();
543 }
544
545 return this.localityCode;
546 }
547
548 /**
549 * Gets a flag indicating that this Bankleitzahl provides a network code.
550 *
551 * @return {@code true} if property {@code networkCode} is supported by this instance; {@code false} if property
552 * {@code networkCode} is not supported by this instance.
553 *
554 * @see #getNetworkCode()
555 */
556 public boolean isNetworkCodeSupported()
557 {
558 return this.blz > 9999;
559 }
560
561 /**
562 * Gets the network code of this Bankleitzahl.
563 * <p><table border="0">
564 * <tr>
565 * <td>0</td>
566 * <td>Deutsche Bundesbank</td>
567 * </tr>
568 * <tr>
569 * <td>1 - 3</td>
570 * <td>
571 * Kreditinstitute, soweit nicht in einer der anderen Gruppen erfasst
572 * </td>
573 * </tr>
574 * <tr>
575 * <td>4</td>
576 * <td>Commerzbank</td>
577 * </tr>
578 * <tr>
579 * <td>5</td>
580 * <td>Girozentralen und Sparkassen</td>
581 * </tr>
582 * <tr>
583 * <td>6 + 9</td>
584 * <td>
585 * Genossenschaftliche Zentralbanken, Kreditgenossenschaften sowie ehemalige
586 * Genossenschaften
587 * </td>
588 * </tr>
589 * <tr>
590 * <td>7</td>
591 * <td>Deutsche Bank</td>
592 * </tr>
593 * <tr>
594 * <td>8</td>
595 * <td>Dresdner Bank</td>
596 * </tr>
597 * </table></p>
598 *
599 * @return Network code of this Bankleitzahl.
600 *
601 * @throws UnsupportedOperationException if this Bankleitzahl does not provide a network code.
602 *
603 * @see #isNetworkCodeSupported()
604 */
605 public int getNetworkCode()
606 {
607 if ( !this.isNetworkCodeSupported() )
608 {
609 throw new UnsupportedOperationException();
610 }
611
612 return this.networkCode;
613 }
614
615 /**
616 * Gets the institute code of this Bankleitzahl.
617 *
618 * @return Institute code of this Bankleitzahl.
619 */
620 public int getInstituteCode()
621 {
622 return this.instituteCode;
623 }
624
625 /**
626 * Formats a Bankleitzahl and appends the resulting text to the given string buffer.
627 *
628 * @param style The style to use ({@code ELECTRONIC_FORMAT} or {@code LETTER_FORMAT}).
629 * @param toAppendTo The buffer to which the formatted text is to be appended.
630 *
631 * @return The value passed in as {@code toAppendTo}.
632 *
633 * @throws NullPointerException if {@code toAppendTo} is {@code null}.
634 * @throws IllegalArgumentException if {@code style} is neither {@code ELECTRONIC_FORMAT} nor {@code LETTER_FORMAT}.
635 *
636 * @see #ELECTRONIC_FORMAT
637 * @see #LETTER_FORMAT
638 */
639 public StringBuffer format( final int style, final StringBuffer toAppendTo )
640 {
641 if ( toAppendTo == null )
642 {
643 throw new NullPointerException( "toAppendTo" );
644 }
645 if ( style != Bankleitzahl.ELECTRONIC_FORMAT && style != Bankleitzahl.LETTER_FORMAT )
646 {
647 throw new IllegalArgumentException( Integer.toString( style ) );
648 }
649
650 final int[] digits = Bankleitzahl.toDigits( this.blz );
651 for ( int i = digits.length - 1, lastDigit = 0; i >= 0; i-- )
652 {
653 if ( digits[i] != 0 || lastDigit > 0 )
654 {
655 toAppendTo.append( digits[i] );
656 lastDigit++;
657 }
658
659 if ( style == Bankleitzahl.LETTER_FORMAT && ( lastDigit == 3 || lastDigit == 6 ) )
660 {
661 toAppendTo.append( ' ' );
662 }
663 }
664
665 return toAppendTo;
666 }
667
668 /**
669 * Formats a Bankleitzahl to produce a string. Same as
670 * <blockquote>
671 * {@link #format(int, StringBuffer) format<code>(style, new StringBuffer()).toString()</code>}
672 * </blockquote>
673 *
674 * @param style The style to use ({@code ELECTRONIC_FORMAT} or {@code LETTER_FORMAT}).
675 *
676 * @return The formatted string.
677 *
678 * @throws IllegalArgumentException if {@code style} is neither {@code ELECTRONIC_FORMAT} nor {@code LETTER_FORMAT}.
679 *
680 * @see #ELECTRONIC_FORMAT
681 * @see #LETTER_FORMAT
682 */
683 public String format( final int style )
684 {
685 return this.format( style, new StringBuffer() ).toString();
686 }
687
688 /**
689 * Formats a Bankleitzahl to produce a string. Same as
690 * <blockquote>
691 * {@link #format(int) bankleitzahl.format(ELECTRONIC_FORMAT)}
692 * </blockquote>
693 *
694 * @param bankleitzahl The {@code Bankleitzahl} instance to format.
695 *
696 * @return The formatted string.
697 *
698 * @throws NullPointerException if {@code bankleitzahl} is {@code null}.
699 */
700 public static String toString( final Bankleitzahl bankleitzahl )
701 {
702 if ( bankleitzahl == null )
703 {
704 throw new NullPointerException( "bankleitzahl" );
705 }
706
707 return bankleitzahl.format( ELECTRONIC_FORMAT );
708 }
709
710 /**
711 * Creates an array holding the digits of {@code number}.
712 *
713 * @param number The number to return the digits for.
714 *
715 * @return An array holding the digits of {@code number}.
716 */
717 private static int[] toDigits( final long number )
718 {
719 int i;
720 int j;
721 int subst;
722 final int[] ret = new int[ MAX_DIGITS ];
723
724 for ( i = MAX_DIGITS - 1; i >= 0; i-- )
725 {
726 for ( j = i + 1, subst = 0; j < MAX_DIGITS; j++ )
727 {
728 subst += ret[j] * EXP10[j];
729 }
730 ret[i] = (int) Math.floor( ( number - subst ) / EXP10[i] );
731 }
732
733 return ret;
734 }
735
736 /**
737 * Creates a string representing the properties of the instance.
738 *
739 * @return A string representing the properties of the instance.
740 */
741 private String internalString()
742 {
743 return new StringBuffer( 500 ).append( '{' ).
744 append( "blz=" ).append( this.blz ).
745 append( ", clearingAreaCodeSupported=" ).
746 append( this.isClearingAreaCodeSupported() ).
747 append( ", clearingArea=" ).append( this.clearingArea ).
748 append( ", instituteCode=" ).append( this.instituteCode ).
749 append( ", localityCodeSupported=" ).
750 append( this.isLocalityCodeSupported() ).
751 append( ", localityCode=" ).append( this.localityCode ).
752 append( ", networkCodeSupported=" ).
753 append( this.isNetworkCodeSupported() ).
754 append( ", networkCode=" ).append( this.networkCode ).
755 append( '}' ).toString();
756
757 }
758
759 /**
760 * Gets the current cache instance.
761 *
762 * @return Current cache instance.
763 */
764 private static Map getCache()
765 {
766 Map cache = (Map) cacheReference.get();
767 if ( cache == null )
768 {
769 cache = Collections.synchronizedMap( new HashMap( 1024 ) );
770 cacheReference = new SoftReference( cache );
771 }
772
773 return cache;
774 }
775
776 /**
777 * Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer
778 * as this object is less than, equal to, or greater than the specified object.<p>
779 *
780 * @param o The Object to be compared.
781 * @return A negative integer, zero, or a positive integer as this object is less than, equal to, or greater than
782 * the specified object.
783 *
784 * @throws NullPointerException if {@code o} is {@code null}.
785 * @throws ClassCastException if the specified object's type prevents it from being compared to this Object.
786 */
787 public int compareTo( final Object o )
788 {
789 if ( o == null )
790 {
791 throw new NullPointerException( "o" );
792 }
793 if ( !( o instanceof Bankleitzahl ) )
794 {
795 throw new ClassCastException( o.getClass().getName() );
796 }
797
798 int result = 0;
799 final Bankleitzahl that = (Bankleitzahl) o;
800
801 if ( !this.equals( that ) )
802 {
803 result = this.blz > that.blz
804 ? 1
805 : -1;
806 }
807
808 return result;
809 }
810
811 /**
812 * Indicates whether some other object is equal to this one.
813 *
814 * @param o The reference object with which to compare.
815 *
816 * @return {@code true} if this object is the same as {@code o}; {@code false} otherwise.
817 */
818 public boolean equals( final Object o )
819 {
820 boolean equal = o == this;
821
822 if ( !equal && o instanceof Bankleitzahl )
823 {
824 equal = this.blz == ( (Bankleitzahl) o ).blz;
825 }
826
827 return equal;
828 }
829
830 /**
831 * Returns a hash code value for this object.
832 *
833 * @return A hash code value for this object.
834 */
835 public int hashCode()
836 {
837 return this.blz;
838 }
839
840 /**
841 * Returns a string representation of the object.
842 *
843 * @return A string representation of the object.
844 */
845 public String toString()
846 {
847 return super.toString() + this.internalString();
848 }
849
850 }