start of new file
[IRC.git] / Robust / src / Benchmarks / BankAppJava / BankAppServer.java
1 // Bank App in Java
2
3 // Author: Danish Lakhani
4
5 // BankAppServer - Bank Application Server that services one client at a time
6
7 import java.io.*;
8 import java.net.*;
9 import java.util.*;
10
11 class BankAppServer
12 {
13         static int SUCCESS = 0;
14         static int ERROR = 1;
15
16         static int LOGIN_ACCOUNT = 1;
17         static int LOGIN_PIN = 2;
18
19         static int ACCOUNT_SAVINGS = 1;
20         static int ACCOUNT_CHECKING = 2;        
21         static int ACCOUNT_TELLER = 3;
22         
23         private ServerSocket serverSocket = null;
24         private Socket clientSocket = null;
25         private PrintWriter out = null;
26         private BufferedReader in = null;
27         private static int serverPort = 44444;
28         private AccountDatabase accounts = null;
29         
30         private boolean isLoggedIn = false;
31         private Integer activeAccount = 0;
32         private Integer tellerCode = 0;
33
34         public BankAppServer()
35         {
36 //              initializeServer();
37         }
38
39         private void initializeServer()
40         {
41                 //Initialize Database
42                 accounts = new AccountDatabase();
43
44                 //Initialize Server Socket
45                 System.out.print("Creating Server Socket...");
46                 try {
47                         serverSocket = new ServerSocket(serverPort);
48                 } catch (IOException e) {
49                         System.out.println("Cannot listen on port " + serverPort);
50                         System.exit(-1);
51                 }
52                 System.out.println("Done");     
53         }
54
55         private void establishConnection()
56                 throws IOException
57         {
58                         System.out.print("Waiting for connection...");
59                         try {
60                                 clientSocket = serverSocket.accept();
61                         } catch (IOException e) {
62                                 System.out.println("Accept failed");
63                                 System.exit(-1);
64                         }
65                         out = new PrintWriter(clientSocket.getOutputStream(), true);
66                         in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
67                         System.out.println("Connection Established!");
68         }
69
70         private int authenticateUser(Integer accountNumber, Integer pin)
71         {
72                 if (!accounts.accountExists(accountNumber))
73                         return LOGIN_ACCOUNT;
74                 if (accounts.getPin(accountNumber) != pin)
75                         return LOGIN_PIN;
76                 return SUCCESS;
77         }
78
79         private int login()
80                 throws IOException
81         {
82                 out.println("OK");
83                 Integer accountNumber = new Integer(in.readLine());
84                 System.out.println("Account number: " + accountNumber);
85                 Integer pin = new Integer(in.readLine());
86                 System.out.println("PIN: " + pin);
87                 System.out.println("Authenticating...");
88                 int status = authenticateUser(accountNumber, pin);
89                 if (status == SUCCESS)
90                 {
91                         out.println(accountNumber);
92                         isLoggedIn = true;
93                         tellerCode = 0;
94                         activeAccount = 0;
95                         if (accounts.isTeller(accountNumber))
96                                 tellerCode = accountNumber;
97                         else
98                                 activeAccount = accountNumber; 
99                         System.out.println("Logged Success");
100                         return SUCCESS;
101                 }
102                 else {
103                         if (status == LOGIN_ACCOUNT)
104                                 out.println("ERROR: login failed: Account " + accountNumber + " does not exist.");
105                         else
106                                 out.println("ERROR: login failed: Incorrect pin.");
107                 }                       
108                 System.out.println("Login Failed");
109                 return ERROR;
110         }
111
112         private void closeConnection()
113                 throws IOException
114         {
115                 out.close();
116                 in.close();
117                 clientSocket.close();
118 //              serverSocket.close();
119         }
120
121         private void processDeposit(Integer accountNumber) throws IOException
122         {
123                 String inVal;
124                 if (!accounts.accountExists(accountNumber))
125                 {
126                         out.println("ERROR: Account " + accountNumber + " not found.");
127                         return;
128                 }
129
130                 out.println("OK");
131                                 
132                 //Get Deposit Amount
133                 inVal = in.readLine();
134                 Double depAmount = new Double(inVal);
135                 if (depAmount <= 0)
136                 {
137                         out.println("ERROR: Negative or zero deposit amount");
138                         return;
139                 }                                       
140
141                 accounts.deposit(accountNumber, depAmount);
142                 out.println("OK");
143                 out.println("$" + depAmount + " deposited successfully! Account: " + accountNumber + " New Balance: " + accounts.getBalance(accountNumber));
144                 return;
145         }
146         
147         private void processWithdrawal(Integer accountNumber) throws IOException
148         {
149                 String inVal;
150                 if (!accounts.accountExists(accountNumber))
151                 {
152                         out.println("ERROR: Account " + accountNumber + " not found.");
153                         return;
154                 }
155
156                 out.println("OK");
157
158                 //Get withdrawal amount
159                 inVal = in.readLine();
160                 Double wdAmount = new Double(inVal);
161                 if (wdAmount <= 0)
162                 {
163                         out.println("ERROR: Negative or zero withdrawal amount");
164                         return;
165                 }
166 //              else if (wdAmount > accounts.getBalance(accountNumber))
167 //              {
168 //                      out.println("ERROR: Insufficient funds. Balance = " + accounts.getBalance(accountNumber));
169 //                      return;
170 //              }
171
172                 accounts.withdraw(accountNumber, wdAmount);
173                 out.println("OK");
174                 out.println("$" + wdAmount + " withdrawn successfully! Account: " + accountNumber + " New Balance: " + accounts.getBalance(accountNumber));
175                 return;
176         }
177         
178         private void processBalanceCheck(Integer accountNumber)
179         {
180                 out.println("OK");
181                 out.println("Account: " + accountNumber + " Balance: " + accounts.getBalance(accountNumber));
182                 return;
183         }
184
185         private void startServer()
186                 throws IOException
187         {
188                 int serverQuit = 0;
189                 int status = SUCCESS;
190                 int isConnected = 0;
191                 initializeServer();
192                 while (serverQuit == 0)
193                 {               
194                         establishConnection();
195                         isConnected = 1;
196                         accounts.loadDatabase();
197                         while (isConnected == 1)
198                         {
199                                 System.out.println("Waiting for request...");
200                                 // Wait for requests
201                                 String request = in.readLine();                                 
202                                 if (request == null)
203                                         continue;
204
205                                 System.out.println("Request: " + request);
206                                 
207                                 // Service requests                             
208                                 if (request.equals("EXIT"))
209                                 {
210                                         accounts.storeDatabase();
211                                         isLoggedIn = false;
212                                         activeAccount = 0;
213                                         tellerCode = 0; 
214                                         closeConnection();
215                                         isConnected = 0;
216                                         continue;
217                                 }
218
219                                 if (request.equals("LOGIN"))
220                                 {
221                                         if (isLoggedIn)
222                                         {
223                                                 out.println("ERROR: Already logged in. Please logout.");
224                                                 continue;
225                                         }
226                                         status = login();
227                                         if (status == ERROR)
228                                         {
229 //                                              isConnected = 0;
230                                                 continue;
231                                         }
232                                 }
233
234                                 if (!isLoggedIn)
235                                 {
236                                         out.println("ERROR: Not logged in");
237                                         continue;
238                                 }
239                                 
240                                 if (request.equals("LOGOUT"))
241                                 {
242                                         out.println("OK");
243                                         if (tellerCode == 0)
244                                                 out.println(activeAccount);
245                                         else
246                                                 out.println(tellerCode);
247                                         accounts.storeDatabase();
248                                         isLoggedIn = false;
249                                         activeAccount = 0;
250                                         tellerCode = 0; 
251 //                                      closeConnection();
252 //                                      isConnected = 0;
253                                 }
254                                 
255                                 if (request.equals("DEPOSIT"))
256                                 {
257                                         processDeposit(activeAccount);
258                                 }
259                                 
260                                 if (request.equals("WITHDRAW"))
261                                 {
262                                         processWithdrawal(activeAccount);
263                                 }
264                                 
265                                 if (request.equals("CHECK"))
266                                 {
267                                         processBalanceCheck(activeAccount);
268                                 }
269                                 
270                                 if (request.equals("TELLERDEPOSIT"))
271                                 {
272                                         if (tellerCode == 0)
273                                         {
274                                                 out.println("ERROR: Teller not logged in");
275                                                 continue;
276                                         }
277                                         out.println("OK");
278                                         Integer acc = new Integer(in.readLine());
279                                         processDeposit(acc);
280                                 }
281                                 
282                                 if (request.equals("TELLERWITHDRAW"))
283                                 {
284                                         if (tellerCode == 0)
285                                         {
286                                                 out.println("ERROR: Teller not logged in");
287                                                 continue;
288                                         }
289                                         out.println("OK");
290                                         Integer acc = new Integer(in.readLine());
291                                         processWithdrawal(acc);
292                                 }
293                                 
294                                 if (request.equals("TELLERCHECK"))
295                                 {
296                                         if (tellerCode == 0)
297                                         {
298                                                 out.println("ERROR: Teller not logged in");
299                                                 continue;
300                                         }
301                                         out.println("OK");
302                                         Integer acc = new Integer(in.readLine());
303                                         processBalanceCheck(acc);
304                                 }
305                                 
306                                 if (request.equals("TELLEROPEN"))
307                                 {
308                                         if (tellerCode == 0)
309                                         {
310                                                 out.println("ERROR: Teller not logged in");
311                                                 continue;
312                                         }
313                                         out.println("OK");
314                                         Integer accNum = new Integer(in.readLine());
315                                         String fName = in.readLine();
316                                         String mName = in.readLine();
317                                         String lName = in.readLine();
318                                         Integer accType = new Integer(in.readLine());
319                                         Double bal = new Double(in.readLine());
320                                         Integer pNum = new Integer(in.readLine());
321                                         status = accounts.openAccount(accNum, fName, mName, lName, accType, bal, pNum);
322                                         if (status == ERROR)
323                                         {
324                                                 out.println("ERROR: Account " + accNum + " already exists.");
325                                                 continue;
326                                         }
327                                         out.println("OK");
328                                         out.println("Account Number: " + accNum + " " +
329                                                                         "Customer Name: " + fName + " " + mName + " " + lName + " " +
330                                                                         "Account Type: " + ((accType == ACCOUNT_SAVINGS)?"SAVINGS":(accType == ACCOUNT_CHECKING)?"CHECKING":"TELLER") + " " +
331                                                                         "Balance: $" + bal + " " +
332                                                                         "PIN: " + pNum + " ");
333                                 }
334                                 
335                                 if (request.equals("TELLERCLOSE"))
336                                 {
337                                         if (tellerCode == 0)
338                                         {
339                                                 out.println("ERROR: Teller not logged in");
340                                                 continue;
341                                         }
342                                         out.println("OK");
343                                         Integer accNum = new Integer(in.readLine());
344                                         status = accounts.closeAccount(accNum);
345                                         if (status == ERROR)
346                                         {
347                                                 out.println("ERROR: Account " + accNum + " does not exist.");
348                                                 continue;
349                                         }
350                                         out.println("OK");
351                                         out.println("Account " + accNum + " closed successfully");                                      
352                                 }
353                                 
354                                 if (request.equals("TELLERMODIFY"))
355                                 {
356                                         if (tellerCode == 0)
357                                         {
358                                                 out.println("ERROR: Teller not logged in");
359                                                 continue;
360                                         }
361                                         out.println("OK");
362                                         Integer accNum = new Integer(in.readLine());
363                                         if (!accounts.accountExists(accNum))
364                                         {
365                                                 out.println("ERROR: Account " + accNum + " does not exist.");
366                                                 continue;
367                                         }
368                                         out.println("OK");
369                                         String inVal;
370                                         while (!(inVal = in.readLine()).equals("DONE"))
371                                         {
372                                                 if (inVal.equals("CHANGENAME"))
373                                                 {
374                                                         String fName = in.readLine();
375                                                         String mName = in.readLine();
376                                                         String lName = in.readLine();
377                                                         accounts.modifyName(accNum, fName, mName, lName);
378                                                         out.println("OK");
379                                                 }
380                                                 else if (inVal.equals("CHANGETYPE"))
381                                                 {
382                                                         Integer newType = new Integer(in.readLine());
383                                                         if (newType.intValue() < 1 || newType.intValue() > 3)
384                                                         {
385                                                                 out.println("ERROR: Invalid account type: " + newType + ". Must be 1-3.");
386                                                                 continue;
387                                                         }
388                                                         accounts.modifyType(accNum, newType);
389                                                         out.println("OK");
390                                                 }
391                                                 else if (inVal.equals("CHANGEPIN"))
392                                                 {
393                                                         Integer newPin = new Integer(in.readLine());
394                                                         if ((newPin < 0) || (newPin > 9999))
395                                                         {
396                                                                 out.println("ERROR: Invalid pin " + newPin + ". Must be 0000-9999.");
397                                                                 continue;
398                                                         }
399                                                         accounts.modifyPin(accNum, newPin);
400                                                         out.println("OK");
401                                                 }
402                                                 else if (inVal.equals("CHANGEBALANCE"))
403                                                 {
404                                                         Double newBal = new Double(in.readLine());
405                                                         accounts.modifyBalance(accNum, newBal);
406                                                         out.println("OK");
407                                                 }
408                                         }
409                                         out.println("Account Number: " + accNum + " " +
410                                                                         "Customer Name: " + accounts.nameString(accNum) + " " +
411                                                                         "Account Type: " + accounts.typeString(accNum) + " " +
412                                                                         "Balance: $" + accounts.getBalance(accNum) + " " +
413                                                                         "PIN: " + accounts.getPin(accNum) + " ");                               
414                                 }
415                                 
416                                 if (request.equals("TELLERVIEW"))
417                                 {
418                                         if (tellerCode == 0)
419                                         {
420                                                 out.println("ERROR: Teller not logged in");
421                                                 continue;
422                                         }
423                                         out.println("OK");
424                                         Integer accNum = new Integer(in.readLine());
425                                         if (!accounts.accountExists(accNum))
426                                         {
427                                                 out.println("ERROR: Account " + accNum + " does not exist.");
428                                                 continue;
429                                         }
430                                         out.println("OK");
431                                         out.println("Account Number: " + accNum + " " +
432                                                                         "Customer Name: " + accounts.nameString(accNum) + " " +
433                                                                         "Account Type: " + accounts.typeString(accNum) + " " +
434                                                                         "Balance: $" + accounts.getBalance(accNum) + " " +
435                                                                         "PIN: " + accounts.getPin(accNum) + " ");                               
436                                 }
437                         }
438                 }
439         }
440
441         public static void main(String [] args)
442                 throws IOException
443         {
444                 System.out.println("BankAppServer in Java");
445                 BankAppServer server = new BankAppServer();
446                 server.startServer();
447         }
448 }
449
450 class AccountEntry
451 {
452         Integer accountNumber;
453         String firstName;
454         String middleName;
455         String lastName;
456         Integer accountType;
457         Double balance;
458         Integer pin;
459
460         public AccountEntry(Integer accNum, String fName, String mName, String lName, Integer accType, Double bal, Integer pNum)
461         {
462                 accountNumber = accNum;
463                 firstName = fName;
464                 middleName = mName;
465                 lastName = lName;
466                 accountType = accType;
467                 balance = bal;
468                 pin = pNum;             
469         }
470 }
471
472
473 class AccountDatabase
474 {
475         static int ACCOUNT_SAVINGS = 1;
476         static int ACCOUNT_CHECKING = 2;        
477         static int ACCOUNT_TELLER = 3;
478         static int SUCCESS = 0;
479         static int ERROR = 1;
480
481         static String dbfilename = "accts.txt";
482
483         Vector<AccountEntry> entries = null;
484
485         public AccountDatabase()
486         {
487                 entries = new Vector<AccountEntry>();
488         }
489
490         public void loadDatabase()
491         {
492                 entries.removeAllElements();
493                 try {
494                         BufferedReader fin = new BufferedReader(new FileReader(dbfilename));
495                         String str;
496                         while ((str = fin.readLine()) != null)
497                         {
498                                 Integer accNum = new Integer(str);
499                                 String fName = fin.readLine();
500                                 String mName = fin.readLine();
501                                 String lName = fin.readLine();
502                                 Integer accType = new Integer(fin.readLine());
503                                 Double bal = new Double(fin.readLine());
504                                 Integer pNum = new Integer(fin.readLine());
505                                 AccountEntry newEntry = new AccountEntry(accNum, fName, mName, lName, accType, bal, pNum);
506                                 entries.add(newEntry);                          
507                         }
508                         fin.close();
509                 } catch (IOException e) {
510                         System.out.println("Cannot open database file");
511                         System.exit(-1);
512                 }
513                 printAccounts();
514         }
515
516         public void storeDatabase()
517         {
518                 try {
519                         BufferedWriter fout = new BufferedWriter(new FileWriter(dbfilename));
520                         for (int i = 0; i < entries.size(); i++)
521                         {
522                                 AccountEntry acc = (AccountEntry)entries.elementAt(i);
523                                 fout.write(acc.accountNumber.toString());
524                                 fout.newLine();
525                                 fout.write(acc.firstName);
526                                 fout.newLine();
527                                 fout.write(acc.middleName);
528                                 fout.newLine();
529                                 fout.write(acc.lastName);
530                                 fout.newLine();
531                                 fout.write(acc.accountType.toString());
532                                 fout.newLine();
533                                 fout.write(acc.balance.toString());
534                                 fout.newLine();
535                                 fout.write(acc.pin.toString());
536                                 fout.newLine();
537                         }
538                         fout.close();
539                 } catch (IOException e) {
540                         System.out.println("Cannot write to database file");
541                         System.exit(-1);
542                 }       
543         }
544
545         public AccountEntry getAccount(Integer accNum)
546         {
547                 for (int i = 0; i < entries.size(); i++)
548                 {
549                         AccountEntry acc = (AccountEntry)entries.elementAt(i);
550                         if (acc.accountNumber.equals(accNum))
551                                 return acc;
552                 }
553                 return null;
554         }
555         
556         public void deposit(Integer accNum, Double amount)
557         {
558                 AccountEntry acc = getAccount(accNum);
559                 acc.balance += amount;
560         }
561         
562         public void withdraw(Integer accNum, Double amount)
563         {
564                 AccountEntry acc = getAccount(accNum);
565                 acc.balance -= amount;
566         }
567         
568         public Double getBalance(Integer accNum)
569         {
570                 AccountEntry acc = getAccount(accNum);
571                 return acc.balance;
572         }
573
574         public int getPin(Integer accNum)
575         {
576                 AccountEntry acc = getAccount(accNum);
577                 if (acc != null)
578                         return acc.pin.intValue();
579                 return -1;
580         }
581
582         public boolean accountExists(Integer accNum)
583         {
584                 AccountEntry acc = getAccount(accNum);
585                 if (acc != null)
586                         return true;
587                 return false;
588         }
589         
590         public boolean isTeller(Integer accNum)
591         {
592                 AccountEntry acc = getAccount(accNum);
593                 if (acc.accountType.equals(ACCOUNT_TELLER))
594                         return true;
595                 return false;
596         }
597
598         public Integer openAccount(Integer accNum, String fName, String mName, String lName, Integer accType, Double bal, Integer pNum)
599         {
600                 if (accountExists(accNum))
601                         return ERROR;
602                 AccountEntry acc = new AccountEntry(accNum, fName, mName, lName, accType, bal, pNum);
603                 entries.add(acc);
604                 return SUCCESS;
605         }
606         
607         public Integer closeAccount(Integer accNum)
608         {
609                 if (accountExists(accNum))
610                 {
611                         AccountEntry acc = getAccount(accNum);
612                         entries.remove(acc);
613                         return SUCCESS;
614                 }
615                 else
616                         return ERROR;
617         }
618         
619         public String nameString(Integer accNum)
620         {
621                 AccountEntry acc = getAccount(accNum);
622                 if (acc != null)
623                 {
624                         return (acc.firstName + " " + acc.middleName + " " + acc.lastName);
625                 }
626                 return "";              
627         }
628         
629         public String typeString(Integer accNum)
630         {
631                 AccountEntry acc = getAccount(accNum);
632                 if (acc != null)
633                 {
634                         return ((acc.accountType == ACCOUNT_SAVINGS)?"SAVINGS":(acc.accountType == ACCOUNT_CHECKING)?"CHECKING":"TELLER");
635                 }
636                 return "";              
637         }
638         
639         public void modifyName(Integer accNum, String fName, String mName, String lName)
640         {
641                 AccountEntry acc = getAccount(accNum);
642                 if (acc != null)
643                 {
644                         acc.firstName = fName;
645                         acc.middleName = mName;
646                         acc.lastName = lName;
647                 }
648                 return; 
649         }
650
651         public void modifyType(Integer accNum, Integer newType)
652         {
653                 AccountEntry acc = getAccount(accNum);
654                 if (acc != null)
655                 {
656                         acc.accountType = newType;
657                 }
658                 return; 
659         }
660
661         public void modifyPin(Integer accNum, Integer newPin)
662         {
663                 AccountEntry acc = getAccount(accNum);
664                 if (acc != null)
665                 {
666                         acc.pin = newPin;
667                 }
668                 return; 
669         }
670         
671         public void modifyBalance(Integer accNum, Double newBal)
672         {
673                 AccountEntry acc = getAccount(accNum);
674                 if (acc != null)
675                 {
676                         acc.balance = newBal;
677                 }
678                 return;         
679         }
680         
681         public void printAccounts()
682         {
683                 System.out.println("entries.size = " + entries.size());
684                 for (int i = 0; i < entries.size(); i++)
685                 {
686                         System.out.println("Entry " + i);
687                         AccountEntry acc = entries.elementAt(i);
688                         System.out.println("1 " + acc.accountNumber.toString());
689                         System.out.println("2 " + acc.firstName);
690                         System.out.println("3 " + acc.middleName);
691                         System.out.println("4 " + acc.lastName);
692                         System.out.println("5 " + acc.accountType.toString());
693                         System.out.println("6 " + acc.balance.toString());
694                         System.out.println("7 " + acc.pin.toString());
695                 }
696         }
697 }