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; 022 023import java.lang.ref.Reference; 024import java.lang.ref.SoftReference; 025import java.text.DecimalFormat; 026import java.text.ParseException; 027import java.text.ParsePosition; 028import java.util.Collections; 029import java.util.HashMap; 030import java.util.Map; 031 032/** 033 * Unique identifier to a particular office (branch) of a german bank. 034 * <p>A Bankleitzahl (BLZ) is a positive integer with a maximum of eight digits. For further information see the 035 * <a href="../../../doc-files/merkblatt_bankleitzahlendatei.pdf">Merkblatt Bankleitzahlendatei</a>. An updated version of the document 036 * may be found at <a href="http://www.bundesbank.de">Deutsche Bundesbank</a>.</p> 037 * 038 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 039 * @version $JDTAUS: Bankleitzahl.java 8725 2012-10-04 21:26:50Z schulte $ 040 * 041 * @see BankleitzahlenVerzeichnis 042 */ 043public final class Bankleitzahl extends Number implements Comparable 044{ 045 046 /** 047 * Constant for the electronic format of a Bankleitzahl. 048 * <p>The electronic format of a Bankleitzahl is an eigth digit number with leading zeros omitted (e.g. 5678).</p> 049 */ 050 public static final int ELECTRONIC_FORMAT = 3001; 051 052 /** 053 * Constant for the letter format of a Bankleitzahl. 054 * <p>The letter format of a Bankleitzahl is an eigth digit number with leading zeros omitted separated by spaces 055 * between the first three digits and the second three digits, and between the second three digits and the last two 056 * digits (e.g. 123 456 78).</p> 057 */ 058 public static final int LETTER_FORMAT = 3002; 059 060 /** Maximum number of digits of a Bankleitzahl. */ 061 public static final int MAX_DIGITS = 8; 062 063 /** Maximum number of characters of a Bankleitzahl. */ 064 public static final int MAX_CHARACTERS = 10; 065 066 /** {@code 10^0..10^7}. */ 067 private static final double[] EXP10 = 068 { 069 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 070 }; 071 072 /** Serial version UID for backwards compatibility with 1.0.x classes. */ 073 private static final long serialVersionUID = -3329406998979147668L; 074 075 /** Used to cache instances. */ 076 private static volatile Reference cacheReference = new SoftReference( null ); 077 078 /** 079 * German bank code. 080 * @serial 081 */ 082 private int blz; 083 084 /** 085 * Clearing area code of this Bankleitzahl. 086 * @serial 087 */ 088 private int clearingArea; 089 090 /** 091 * Locality code of this Bankleitzahl. 092 * @serial 093 */ 094 private int localityCode; 095 096 /** 097 * Network code of this Bankleitzahl. 098 * @serial 099 */ 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}