1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package net.sf.plausj.bank.german;
18
19 import net.sf.plausj.bank.german.strategy.Strategy;
20 import net.sf.plausj.bank.german.util.StrategyHelper;
21 import net.sf.plausj.bank.german.util.StrategyHelperImpl;
22
23 /**
24 * This is a german bank account object.
25 *
26 * @author ninan
27 *
28 */
29 public class BankAccount {
30
31 /** Used internally to represent default value */
32 private static final int UNSET = 0;
33
34 /** No strategy is responsible for this bank account */
35 public static final int NOCHECK = 2;
36
37 /** All strategies said this bank account is valid */
38 public static final int VALID = 4;
39
40 /** All strategies said this bank account is invalid */
41 public static final int INVALID = 8;
42
43 /** Used to signal that the bank code was not found */
44 public static final int BANK_CODE_NOT_FOUND = 256;
45
46 /**
47 * Used to signal that the strategy referenced by the bank code is not
48 * implemented
49 */
50 public static final int NOT_IMPLEMENTED = 512;
51
52 /** Some strategies said this bank account is valid, some said it is invalid */
53 public static final int AMBIGUOUS1 = VALID | INVALID;
54
55 /**
56 * Some strategies said this bank account is valid, some said they are not
57 * responsible
58 */
59 public static final int AMBIGUOUS2 = VALID | NOCHECK;
60
61 /**
62 * Some strategies said this bank account is invalid, some said they are not
63 * responsible
64 */
65 public static final int AMBIGUOUS3 = INVALID | NOCHECK;
66
67 /**
68 * Some strategies said this bank account is valid, some said it is invalid
69 * and some said they are not responsible
70 */
71 public static final int AMBIGUOUS4 = VALID | INVALID | NOCHECK;
72
73 /** Stores the instance of the bank code */
74 private final BankCode bankCode;
75
76 /** Stores the instance of the account code */
77 private final AccountCode accountCode;
78
79 /** Stores the validity of the bank account */
80 private int validity = UNSET;
81
82 private final StrategyHelper sh = new StrategyHelperImpl();
83
84 /**
85 * The default CTOR for a bank account.
86 *
87 * @param bankCode
88 * The bank code of the account
89 * @param accountCode
90 * The account code
91 * @throws IllegalArgumentException
92 * If bank account or bank code are invalid this exception is
93 * thrown
94 */
95 public BankAccount(final BankCode bankCode, final AccountCode accountCode)
96 throws IllegalArgumentException {
97
98 if (null == bankCode) {
99 throw new IllegalArgumentException(
100 "Null pointer supplied as bank code.");
101 }
102
103 if (null == accountCode) {
104 throw new IllegalArgumentException(
105 "Null pointer supplied as account code.");
106 }
107
108 this.bankCode = bankCode;
109 this.accountCode = accountCode;
110
111 calculateValidity();
112
113 }
114
115 /**
116 * An comfort CTOR using strings instead of objects for bank code and
117 * account code
118 *
119 * @param bankCode
120 * The bank code of the account
121 * @param accountCode
122 * The account code
123 * @throws IllegalArgumentException
124 * If bank account or bank code are invalid this exception is
125 * thrown
126 */
127 public BankAccount(final String bankCode, final String accountCode)
128 throws IllegalArgumentException {
129
130 this(new BankCode(bankCode), new AccountCode(accountCode));
131
132 }
133
134 /**
135 * Returns the validity of this bank account. It returns an integer from the
136 * range of the MAGICs in this class
137 *
138 * @return The validity of the bank account
139 *
140 * @see BankAccount#NOCHECK
141 * @see BankAccount#VALID
142 * @see BankAccount#INVALID
143 * @see BankAccount#BLZ_NOT_FOUND
144 * @see BankAccount#NOT_IMPLEMENTED
145 * @see BankAccount#AMBIGUOUS1
146 * @see BankAccount#AMBIGUOUS2
147 * @see BankAccount#AMBIGUOUS3
148 * @see BankAccount#AMBIGUOUS4
149 */
150 public int getValidity() {
151 return validity;
152 }
153
154 /**
155 * Return the validity as string constant
156 *
157 * @return The validity as string
158 */
159 public String getValidityAsString() {
160
161 if (UNSET == validity)
162 return "UNSET";
163
164 if (VALID == validity)
165 return "VALID";
166
167 if (INVALID == validity)
168 return "INVALID";
169
170 if (NOCHECK == validity)
171 return "NOCHECK";
172
173 if (BANK_CODE_NOT_FOUND == validity)
174 return "BANK_CODE_NOT_FOUND";
175
176 if (NOT_IMPLEMENTED == validity)
177 return "NOT_IMPLEMENTED";
178
179 if (AMBIGUOUS1 == validity)
180 return "AMBIGUOUS1";
181
182 if (AMBIGUOUS2 == validity)
183 return "AMBIGUOUS2";
184
185 if (AMBIGUOUS3 == validity)
186 return "AMBIGUOUS3";
187
188 if (AMBIGUOUS4 == validity)
189 return "AMBIGUOUS4";
190
191 return "UNKNOWN";
192
193 }
194
195 /**
196 * @return Returns the accountCode.
197 */
198 public AccountCode getAccountCode() {
199 return accountCode;
200 }
201
202 /**
203 * @return Returns the bankCode.
204 */
205 public BankCode getBankCode() {
206 return bankCode;
207 }
208
209 /**
210 * Calculates the validity of the bank account
211 *
212 */
213 private void calculateValidity() {
214
215 final Strategy[] strategies = sh.getStrategiesByBankCode(bankCode);
216
217
218 if (null == strategies) {
219 validity = NOCHECK;
220 return;
221 }
222
223 for (int i = 0; i < strategies.length; ++i) {
224 Strategy s = strategies[i];
225 CheckDigit cd = s.calculateCheckDigit(bankCode, accountCode);
226
227
228 if (null == cd) {
229 validity |= NOCHECK;
230 continue;
231 }
232
233 if (cd.isAlwaysValid()) {
234 validity |= VALID;
235 continue;
236 }
237
238 if (cd.isAlwaysInvalid()) {
239 validity |= INVALID;
240 continue;
241 }
242
243 if (cd.isBankCodeNotFound()) {
244
245
246 validity = BANK_CODE_NOT_FOUND;
247 return;
248 }
249
250 if (cd.isNotImplemented()) {
251
252 validity = NOT_IMPLEMENTED;
253 return;
254 }
255
256 if (accountCode.matchesCheckDigit(cd)) {
257 validity |= VALID;
258 continue;
259 } else {
260 validity |= INVALID;
261 continue;
262 }
263 }
264 }
265
266 /**
267 * @see java.lang.Object#toString()
268 */
269 public String toString() {
270 return "[BankCode='" + bankCode + "'; AccountCode='" + accountCode
271 + "'; validity='" + getValidityAsString() + "(" + getValidity()
272 + ")']";
273 }
274
275 }