1 // joi/5/bank/Bank.java 2 // 3 // 4 // Copyright 2003 Bill Campbell and Ethan Bolker 5 // Ethan Bolker: modifications Spring 2004 for cs110 hw7 6 // allow banker to open a SavingsAccount 7 // enable banker's newmonth command 8 // 9 // allow customer to close his or her account (answer to hw6) 10 // check cashing is with customer transaction "cash check" or 11 // "check" (just look at first two characters). To close an 12 // account, need the whole word "close" to guard against error. 13 14 import java.util.*; 15 16 /** 17 * A Bank object simulates the behavior of a simple bank/ATM. 18 * It contains a Terminal object and a collection of 19 * BankAccount objects. 20 * 21 * The visit method opens this Bank for business, 22 * prompting the customer for input. 23 * 24 * To create a Bank and open it for business issue the command 25 * java Bank. 26 * 27 * @see BankAccount 28 * @version 5.1 29 */ 30 31 public class Bank 32 { 33 private String bankName; // the name of this Bank 34 private Terminal atm; // for talking with the customer 35 private int balance = 0; // total cash on hand 36 private int transactionCount = 0; // number of Bank transactions 37 private Month month; // the current month. 38 39 private TreeMap accountList; // mapping names to accounts. 40 41 // what the banker can ask of the bank 42 43 private static final String BANKER_COMMANDS = 44 "Banker commands: " + 45 "exit, open, customer, report, newmonth, help."; 46 47 // what the customer can ask of the bank 48 49 private static final String CUSTOMER_TRANSACTIONS = 50 " Customer transactions: " + 51 "deposit, withdraw, transfer, balance, cash check, close, quit, help."; 52 53 /** 54 * Construct a Bank with the given name and Terminal. 55 * 56 * @param bankName the name for this Bank. 57 * @param atm this Bank's Terminal. 58 */ 59 60 public Bank( String bankName, Terminal atm ) 61 { 62 this.atm = atm; 63 this.bankName = bankName; 64 accountList = new TreeMap(); 65 month = new Month(); 66 } 67 68 /** 69 * Simulates interaction with a Bank. 70 * Presents the user with an interactive loop, prompting for 71 * banker transactions and in case of the banker transaction 72 * "customer", an account id and further customer 73 * transactions. 74 */ 75 76 public void visit() 77 { 78 instructUser(); 79 80 String command; 81 while (!(command = 82 atm.readWord("banker command: ")).equals("exit")) { 83 84 if (command.startsWith("h")) { 85 help( BANKER_COMMANDS ); 86 } 87 else if (command.startsWith("o")) { 88 openNewAccount(); 89 } 90 else if (command.startsWith("r")) { 91 report(); 92 } 93 else if (command.startsWith("n")) { 94 newMonth(); 95 } 96 else if (command.startsWith( "c" ) ) { 97 BankAccount acct = whichAccount(); 98 if ( acct != null ) 99 processTransactionsForAccount( acct ); 100 } 101 else { 102 // Unrecognized Request 103 atm.println( "unknown command: " + command ); 104 } 105 } 106 report(); 107 atm.println( "Goodbye from " + bankName ); 108 } 109 110 111 // Open a new bank account, 112 // prompting the user for information. 113 114 private void openNewAccount() 115 { 116 String accountName = atm.readWord( "Account name: " ); 117 char accountType = 118 atm.readChar( "Checking/Fee/Regular/Savings? (c/f/r/s): " ); 119 int startup = atm.readInt( "Initial deposit: " ); 120 BankAccount newAccount; 121 switch( accountType ) { 122 case 'c': 123 newAccount = new CheckingAccount( startup, this ); 124 break; 125 case 'f': 126 newAccount = new FeeAccount( startup, this ); 127 break; 128 case 'r': 129 newAccount = new RegularAccount( startup, this ); 130 break; 131 case 's': 132 newAccount = new SavingsAccount( startup, this ); 133 break; 134 default: 135 atm.println("invalid account type: " + accountType); 136 return; 137 } 138 accountList.put( accountName, newAccount ); 139 atm.println( "opened new account " + accountName 140 + " with $" + startup ); 141 } 142 143 // Prompt the customer for transaction to process. 144 // Then send an appropriate message to the account. 145 146 private void processTransactionsForAccount( BankAccount acct ) 147 { 148 help( CUSTOMER_TRANSACTIONS ); 149 150 String transaction; 151 while (!(transaction = 152 atm.readWord(" transaction: ")).equals("quit")) { 153 154 if ( transaction.startsWith( "h" ) ) { 155 help( CUSTOMER_TRANSACTIONS ); 156 } 157 else if ( transaction.startsWith( "d" ) ) { 158 int amount = atm.readInt( " amount: " ); 159 atm.println(" deposited " + acct.deposit( amount )); 160 } 161 else if ( transaction.startsWith( "w" ) ) { 162 int amount = atm.readInt( " amount: " ); 163 atm.println(" withdrew " + acct.withdraw( amount )); 164 } 165 else if ( transaction.startsWith( "ca" ) || 166 transaction.startsWith( "ch" ) ) { 167 int amount = atm.readInt( " amount of check: " ); 168 atm.println(" cashed check for " + 169 ((CheckingAccount)acct).honorCheck( amount )); 170 } 171 else if (transaction.startsWith("t")) { 172 atm.print( " to "); 173 BankAccount toacct = whichAccount(); 174 if (toacct != null) { 175 int amount = atm.readInt(" amount to transfer: "); 176 atm.println(" transfered " + 177 toacct.deposit(acct.withdraw(amount))); 178 } 179 } 180 else if (transaction.startsWith("b")) { 181 atm.println(" current balance " + 182 acct.requestBalance()); 183 } 184 else if (transaction.equals("close")) { 185 close(acct); 186 break; // no more transactions for this account! 187 } 188 else { 189 atm.println(" sorry, unknown transaction" ); 190 } 191 } 192 atm.println(); 193 } 194 195 196 // Close a bank account, inform the user that a check 197 // for the balance of the account will be mailed to them. 198 199 private void close( BankAccount accountToClose ) 200 { 201 atm.println(" We will send you a check for $" + 202 accountToClose.getBalance()); 203 atm.println(" Thank you for banking with " + 204 bankName); 205 206 //update the bank's balance and transactionCount 207 balance -= accountToClose.getBalance(); 208 transactionCount -= accountToClose.getTransactionCount(); 209 210 // find key, to remove the account from the accountList 211 Set keys = accountList.keySet(); 212 Iterator keyIterator = keys.iterator(); 213 while( keyIterator.hasNext() ) { 214 String accountName = (String)keyIterator.next(); 215 BankAccount account = (BankAccount)accountList.get(accountName); 216 if ( accountToClose.equals(account) ) { 217 accountList.remove(accountName); 218 break; 219 } 220 } 221 } 222 223 // Prompt for an account name (or number), look it up 224 // in the account list. If it's there, return it; 225 // otherwise report an error and return null. 226 227 private BankAccount whichAccount() 228 { 229 String accountName = atm.readWord( "account name: " ); 230 BankAccount account = (BankAccount) accountList.get(accountName); 231 if (account == null) { 232 atm.println("not a valid account"); 233 } 234 return account; 235 } 236 237 // Action to take when a new month starts. 238 // Update the month field by sending a next message. 239 // Loop on all accounts, sending each a newMonth message. 240 241 private void newMonth() 242 { 243 month.next(); 244 for (Iterator i = accountList.values().iterator(); 245 i.hasNext(); ) { 246 BankAccount acct = (BankAccount) i.next(); 247 acct.newMonth(); 248 } 249 } 250 251 // Report bank activity. 252 // For each BankAccount, print the account name, 253 // account balance and the number of transactions. 254 // Then print Bank totals. 255 256 private void report() 257 { 258 atm.println( bankName + " report for " + month ); 259 atm.println( "\nSummaries of individual accounts:" ); 260 atm.println( "account balance transaction count" ); 261 for (Iterator i = accountList.keySet().iterator(); 262 i.hasNext(); ) { 263 String accountName = (String) i.next(); 264 BankAccount acct = (BankAccount) accountList.get(accountName); 265 atm.println(accountName + "\t$" + acct.getBalance() + "\t\t" + 266 acct.getTransactionCount()); 267 } 268 atm.println( "\nBank totals"); 269 atm.println( "open accounts: " + getNumberOfAccounts() ); 270 atm.println( "cash on hand: $" + getBalance()); 271 atm.println( "transactions: " + getTransactionCount()); 272 atm.println(); 273 } 274 275 276 // Welcome the user to the bank and instruct her on 277 // her options. 278 279 private void instructUser() 280 { 281 atm.println( "Welcome to " + bankName ); 282 atm.println( "Open some accounts and work with them." ); 283 help( BANKER_COMMANDS ); 284 } 285 286 // Display a help string. 287 288 private void help( String helpString ) 289 { 290 atm.println( helpString ); 291 atm.println(); 292 } 293 294 /** 295 * Increment bank balance by given amount. 296 * 297 * @param amount the amount increment. 298 */ 299 300 public void incrementBalance(int amount) 301 { 302 balance += amount; 303 } 304 305 /** 306 * Increment by one the count of transactions, 307 * for this bank. 308 */ 309 310 public void countTransaction() 311 { 312 transactionCount++; 313 } 314 315 /** 316 * Get the number of transactions performed by this bank. 317 * 318 * @return number of transactions performed. 319 */ 320 321 public int getTransactionCount( ) 322 { 323 return transactionCount ; 324 } 325 326 /** 327 * Get the current bank balance. 328 * 329 * @return current bank balance. 330 */ 331 332 public int getBalance() 333 { 334 return balance; 335 } 336 337 /** 338 * Get the current number of open accounts. 339 * 340 * @return number of open accounts. 341 */ 342 343 public int getNumberOfAccounts() 344 { 345 return accountList.size(); 346 } 347 348 /** 349 * Run the simulation by creating and then visiting a new Bank. 350 * 351 *

352 * A -e argument causes the input to be echoed. 353 * This can be useful for executing the program against 354 * a test script, e.g., 355 *

   356	     *   java Bank -e < Bank.in
   357	     * 
358 * 359 * @param args the command line arguments: 360 *
   361	     *         -e echo input.
   362	     *         bankName any other command line argument.
   363	     *         
364 */ 365 366 public static void main( String[] args ) 367 { 368 // parse the command line arguments for the echo 369 // flag and the name of the bank 370 371 boolean echo = false; // default does not echo 372 String bankName = "Faithless Trust"; // default bank name 373 374 for (int i = 0; i < args.length; i++ ) { 375 if (args[i].equals("-e")) { 376 echo = true; 377 } 378 else { 379 bankName = args[i]; 380 } 381 } 382 Bank aBank = new Bank( bankName, new Terminal(echo) ); 383 aBank.visit(); 384 } 385 }