com.prowidesoftware.swift.model.BIC.java Source code

Java tutorial

Introduction

Here is the source code for com.prowidesoftware.swift.model.BIC.java

Source

/*******************************************************************************
 * Copyright (c) 2016 Prowide Inc.
 *
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Lesser General Public License as 
 *     published by the Free Software Foundation, either version 3 of the 
 *     License, or (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 *     
 *     Check the LGPL at <http://www.gnu.org/licenses/> for more details.
 *******************************************************************************/
package com.prowidesoftware.swift.model;

import org.apache.commons.lang.StringUtils;

import com.prowidesoftware.swift.DeleteSchedule;

/**
 * Helper class to process BIC related information.
 *
 * @author www.prowidesoftware.com
 * @since 3.3
 */
public class BIC {
    /**
     * Fake "test & training" BIC of 8 chars for testing
     * @since 7.6
     */
    public static final transient String TEST8 = "TESTUS00";
    /**
     * Fake Logical terminal address for testing,
     * consisting of a fake "test & training" BIC of 12 chars
     * (including the terminal identification)
     *
     * @since 7.6
     * @see SwiftBlock1#getLogicalTerminal()
     */
    public static final transient String TEST12 = "TESTAR00AXXX";
    /**
     * Constant value with which all partner bics start 
     * @since 7.8
     */
    public static final String PARTNER_PREFIX = "PTS";

    private String invalidCause = null;
    private String bic8 = null;
    private String branch = null;
    private String subtype = null;

    /**
     * Constructor with BIC code.
     * It accepts a BIC8, BIC11 or a logical terminal address (12 characters) in which
     * case the LT identifier at position 9 will be dropped.
     *
     * @param bic the BIC code to use in this BIC
     */
    public BIC(final String bic) {
        super();
        parse(bic);
    }

    /**
     * Parse the given string into the corresponding object attributes.
     *
     * @param bic
     */
    protected void parse(final String bic) {
        if (bic != null) {
            if (bic.length() >= 8) {
                this.bic8 = bic.substring(0, 8);
            }
            if (bic.length() == 11 || bic.length() == 12) {
                this.branch = bic.substring(bic.length() - 3, bic.length());
            }
        }
    }

    /**
     * Default constructor
     */
    public BIC() {
    }

    /**
     * Get the BIC code of this BIC.
     * This method does not guarantee that the BIC is valid. use {@link #isValid()}
     *
     * @return a string with the code
     * @deprecated use getBic8 or getBic11 instead
     */
    @Deprecated
    @DeleteSchedule(2016)
    public String getBic() {
        final StringBuilder sb = new StringBuilder();
        if (this.bic8 != null) {
            sb.append(this.bic8);
        }
        if (this.branch != null) {
            sb.append(this.branch);
        }
        return sb.toString();
    }

    /**
     * @param bic the BIC code
     * @deprecated use the constructor passing the string as parameter
     */
    @Deprecated
    @DeleteSchedule(2016)
    public void setBic(final String bic) {
        parse(bic);
    }

    /**
     * Get a human readable (english) string that gives information about why the BIC was found invalid.
     * @return a string or <code>null</code> if there's no invalid cause set
     */
    public String getInvalidCause() {
        return invalidCause;
    }

    /**
     * Validates a BIC structure.
     * It only checks that length is 8 or 11 and that the country code is valid.
     * This method does not validate against any BIC directory.
     *
     * @return <code>true</code> if the BIC is found to be valid and <code>false</code> in other case
     * @throws IllegalStateException if BIC is <code>null</code>
     */
    public boolean isValid() {
        if (this.bic8 == null) {
            this.invalidCause = "BIC is null";
            return false;
        }
        if (this.bic8.length() != 8) {
            this.invalidCause = "Expected 8 characters for the institution and country code and found "
                    + this.bic8.length() + " in " + this.bic8;
            return false;
        }
        if (this.branch != null && this.branch.length() != 3) {
            this.invalidCause = "Expected 3 characters for branch and found " + this.branch.length() + " in "
                    + this.branch;
            return false;
        }
        final String country = this.bic8.substring(4, 6);
        if (!ISOCountries.getInstance().isValidCode(country.toUpperCase())) {
            this.invalidCause = "Invalid country code " + country;
            return false;
        }
        final String b11 = getBic11();
        for (int i = 0; i < b11.length(); i++) {
            final char c = b11.charAt(i);
            final boolean digit = Character.isDigit(c);
            final boolean uppercase = Character.isUpperCase(c);
            if (!digit && !uppercase) {
                this.invalidCause = "BIC characters must be alphanumeric uppercase";
                return false;
            }
        }
        return true;
    }

    /**
     * It returns the last three that conform the branch or null if branch is not present.
     *
     * @since 7.8.5
     * @return the BIC's branch part or null if not found.
     */
    public String getBranch() {
        return this.branch;
    }

    /**
     * @since 7.4
     */
    public String getSubtype() {
        return subtype;
    }

    /**
     * @since 7.4
     */
    public void setSubtype(final String subtype) {
        this.subtype = subtype;
    }

    /**
     * Returns true if the BIC is a Test & Training BIC code.
     * In SWIFTs FIN messaging system, a BIC with a zero
     * in the 8th position is a Test & Training BIC, and as
     * such it cannot be used in production FIN messages.
     *
     * @return true if it is a T&T BIC, false if is not or if the condition cannot be determined
     * @since 7.6
     */
    public boolean isTestAndTraining() {
        if (this.bic8 != null && this.bic8.length() >= 8) {
            return this.bic8.charAt(7) == '0';
        }
        return false;
    }

    /**
     * Returns true if the BIC is not live (not connected) on the network.
     * <br />
     * BICs can identify not only financial institutions but also non-financial ones 
     * either connected or not connected to the SWIFT network.
     * <br /> 
     * A BIC of an institution which is <strong>not connected</strong> to the SWIFT network 
     * still has a location code with the digit 1 at the end (for instance AFSEUS31). 
     * BICs like that are called non-SWIFT BICs (or BIC 1).
     * <br />
     * In SWIFTs FIN messaging system, a BIC with a one in the 8th position is a Non-Live BIC.
     * <br />
     * Note this is not the opposite of {@link #isLive()}
     * 
     * @return true if it is a Non-Live BIC, false if is not or if the condition cannot be determined
     * @since 7.7
     */
    public boolean isNonLive() {
        if (this.bic8 != null && this.bic8.length() >= 8) {
            return this.bic8.charAt(7) == '1';
        }
        return false;
    }

    /**
     * Returns true if the BIC is live (connected and not test & training) on the network.
     * 
     * BICs can identify not only financial institutions but also non-financial ones 
     * either connected or not connected to the SWIFT network.
     * <br />
     * In SWIFTs FIN messaging system, a BIC with a character
     * different than zero (that would be T&T) or one (that would be non-connected) 
     * in the 8th position is a Live BIC.
     * <br />
     * Note this is not the opposite of {@link #isNonLive()}
     *
     * @return true if it is a Non-Live BIC, false if is not or if the condition cannot be determined
     * @since 7.7
     */
    public boolean isLive() {
        if (this.bic8 != null && this.bic8.length() >= 8) {
            return this.bic8.charAt(7) != '0' && this.bic8.charAt(7) != '1';
        }
        return false;
    }

    /**
     * Returns the first 8 characters of the BIC code.
     *
     * @return the bic8 or null if the BIC has less than 8 characters
     * @since 7.6
     */
    public String getBic8() {
        return this.bic8;
    }

    /**
     * Returns the BIC code with 11 characters composed by the first 8 characters of the BIC code,
     * plus the branch code, dropping the logical terminal identifier at position 9 if present, and
     * also padding with a default XXX branch if necessary.
     *
     * @return the bic8 or null if the BIC has less than 8 characters
     * @since 7.6
     */
    public String getBic11() {
        final String branch = this.branch != null ? this.branch : "XXX";
        if (this.bic8 != null) {
            return bic8 + branch;
        }
        return null;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((bic8 == null) ? 0 : bic8.hashCode());
        result = prime * result + ((branch == null) ? 0 : branch.hashCode());
        result = prime * result + ((invalidCause == null) ? 0 : invalidCause.hashCode());
        result = prime * result + ((subtype == null) ? 0 : subtype.hashCode());
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final BIC other = (BIC) obj;
        if (bic8 == null) {
            if (other.bic8 != null) {
                return false;
            }
        } else if (!bic8.equals(other.bic8)) {
            return false;
        }
        if (branch == null) {
            if (other.branch != null) {
                return false;
            }
        } else if (!branch.equals(other.branch)) {
            return false;
        }
        if (invalidCause == null) {
            if (other.invalidCause != null) {
                return false;
            }
        } else if (!invalidCause.equals(other.invalidCause)) {
            return false;
        }
        if (subtype == null) {
            if (other.subtype != null) {
                return false;
            }
        } else if (!subtype.equals(other.subtype)) {
            return false;
        }
        return true;
    }

    /**
     * Gets the 2 chars country code of the BIC, which are the 5th and 6th characters
     * @since 7.7
     */
    public String country() {
        return StringUtils.substring(this.bic8, 4, 6);
    }

    /**
     * Gets the first 4 characters of the BIC; corresponding to the institution code
     * @since 7.8.5
     */
    public String institution() {
        return StringUtils.substring(this.bic8, 0, 4);
    }

}