Project Paper OOSE

Embed Size (px)

Citation preview

SUPERTRANSNEW GENERATION CUSTOMER TRANSACTION SOLUTION

STATHIS POLYZOSOBJECT ORIENTED SOFTWARE ENGINEERINGLARISSA ATEI UNIVERSITY OF STAFFORDSHIRE

TABLE OF CONTENTS1. 2. INTRODUCTION REQUIREMENTS 2.1 2.2 2.3 3. FUNCTIONAL & NON-FUNCTIONAL REQUIREMENTS USE CASES & SEQUENCE DIAGRAM SYSTEM CLASSES 1 1 1 2 3 3 34 5

PROPOSED SYSTEM 3.13.1.1 3.1.2

COMMUNICATION: TRADETOKEN AND ITS CONTENTSCOMMON OBJECTS ENTITIES

3.23.2.1 3.2.2

THE SERVERFRONT END DATABASE

77 8

3.3 3.43.4.1 3.4.2

SERVER-SIDE TASKS TOKEN HANDLING THE CLIENTCUSTOMERS STAFF

8 910 11

3.53.5.1 3.5.2

UTILITIESCLIENT UTILITIES DATABASE UTILITIES

1414 15

4.

DEVELOPMENT ISSUES COMMENTS 4.1 4.24.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7

15 15 1717 17 17 17 17 17 17

THE DEVELOPMENT PROCESS TEST SCENARIOSINVALID LOGON ATTEMPTS ATTEMPT LOGON WHEN SERVER IS DOWN DEPOSIT TO A NON-EXISTENT ACCOUNT USE OF INVALID AMOUNTS INVALID DATE RANGES FOR ACCOUNT TRANSACTIONS NEW USER ID TO AN INACTIVE EMPLOYEE ALPHABETICAL CHARACTERS IN PIN

4.3

SYSTEM CRITIQUE

18i

5.

CONCLUSION USE CASE DIAGRAMS

18 21 21 22 23 2323 23 23 23 24 24 24 24 24 25 25 25 25 26 26 26

APPENDIX A . A.1. A.2.

CUSTOMER USE CASES STAFF USE CASES USE CASE DESCRIPTIONS

APPENDIX B . B.1.

HIGH LEVEL

B.1.1. ACTIVATE/DEACTIVATE CARD B.1.2. ACTIVATE/DEACTIVATE USER B.1.3. ADD NEW EMPLOYEE B.1.4. CHANGE CARD PIN B.1.5. CHANGE PIN (CUSTOMER) B.1.6. CHECK ACCOUNTS B.1.7. CHECK SOURCE ACCOUNT BALANCE B.1.8. DEPOSIT CASH B.1.9. PAY CREDIT CARD BILL B.1.10. PAY TO CREDIT CARD B.1.11. PAY TO UTILITY B.1.12. PAY UTILITY BILL B.1.13. TRANSFER MONEY B.1.14. VERIFY OLD PIN B.1.15. VIEW TRANSACTIONS B.1.16. WITHDRAW CASH

B.2.

FULL DESCRIPTION

2727 28

B.2.1. CHANGE PIN (CUSTOMER) B.2.2. TRANSFER MONEY

APPENDIX C . APPENDIX D . APPENDIX E . APPENDIX F . F.1.

CLASS DIAGRAM SEQUENCE DIAGRAM STATE MACHINE DIAGRAM SOURCE CODE

29 30 31 32 3232 37 39 41 45 49 57 64 71

CLIENTPACK

F.1.1. CLIENTGUI.JAVA F.1.2. CSPACLIENT.JAVA F.1.3. F.1.4. F.1.5. F.1.6. F.1.7. F.1.8. F.1.9. iiFRMACCOUNTSTATUS.JAVA FRMACTIVATESUSPEND.JAVA FRMCHANGEPIN.JAVA FRMCUSTOMERS.JAVA FRMEMPLOYEES.JAVA FRMLISTTRANSACTIONS.JAVA FRMNEWACCOUNT.JAVA

F.1.10. FRMNEWCREDITCARD.JAVA F.1.11. FRMNEWUSERID.JAVA F.1.12. FRMPAYCREDITCARD.JAVA F.1.13. FRMPAYUTILITY.JAVA F.1.14. FRMTRANSACTION.JAVA F.1.15. FRMTRANSFER.JAVA F.1.16. FRMTRANSFERCREDITCARD.JAVA F.1.17. FRMUTILITYTRANSACTION.JAVA F.1.18. MAINCUSMENU.JAVA F.1.19. MAINMENU.JAVA F.1.20. MAINMENUINT.JAVA

74 79 83 88 93 97 102 107 112 116 120

F.2.

COMMON OBJECTS

124124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141

F.2.1. ADDACCOUNT.JAVA F.2.2. ADDCREDITCARD.JAVA F.2.3. ADDUSER.JAVA F.2.4. CHANGEACTIVATIONSTATUS.JAVA F.2.5. CREDITCARDPAYMENT.JAVA F.2.6. CUSTOMERDATA.JAVA F.2.7. EMPLOYEEDATA.JAVA F.2.8. GETACCOUNT.JAVA F.2.9. LOGINSTATUS.JAVA F.2.10. LOGINUSER.JAVA F.2.11. MAKETRANSACTION.JAVA F.2.12. MAKETRANSFER.JAVA F.2.13. MAKETRANSFERTOCREDIT.JAVA F.2.14. REQUESTCUSTOMER.JAVA F.2.15. REQUESTEMPLOYEE.JAVA F.2.16. REQUESTPINCHANGE.JAVA F.2.17. REQUESTTRANSACTIONS.JAVA F.2.18. USERID.JAVA

F.3.

COMMON OBJECTS.ENTITIES

142142 144 145 149 151 153 154 157 158 159 161

F.3.1. ACCOUNT.JAVA F.3.2. ADDRESS.JAVA F.3.3. CREDITCARD.JAVA F.3.4. CREDITCARDTRANSACTION.JAVA F.3.5. CUSTOMER.JAVA F.3.6. DATABASEOBJECT.JAVA F.3.7. EMPLOYEE.JAVA F.3.8. GENTRANSACTION.JAVA F.3.9. PERSON.JAVA F.3.10. TRANSACTION.JAVA F.3.11. USER.JAVA

F.4.

GLOBALPACK

164164 iii

F.4.1. CLIENTUTILITIES.JAVA

F.4.2. DBUTILITIES.JAVA F.4.3. TRADETOKEN.JAVA

169 172

F.5.

SERVERPACK

173173 177 179

F.5.1. CSPA.JAVA F.5.2. CSPAGUI.JAVA F.5.3. SERVERCSPA.JAVA

APPENDIX G . APPENDIX H . H.1. H.2.

TRADETOKEN CONTENTS & RETURN TYPES DATABASE SQL CODE

195 197 197 199 205 206 206 207 208 209 209 210 213 215 216 218 220

DATABASE TABLES & VIEWS DATABASE DIAGRAM REQUIRED DEMO SCREENSHOTS

APPENDIX I . APPENDIX J . J.1. J.2. J.3.

CASH DEPOSIT CASH WITHDRAWA INSUFFICIENT FUNDS ON CREDIT CARD PAYMENT APPLICATION SCREENSHOTS

APPENDIX K . K.1. K.2. K.3.

SERVER STAFF CUSTOMER VISUAL PARADIGM SCREENSHOTS JBUILDER SCREENSHOTS MS SQL SERVER 2005 SCREENSHOTS

APPENDIX L . APPENDIX M . APPENDIX N .

REFERENCES BIBLIOGRAPHY

iv

1. INTRODUCTIONOur aim in this paper is to present a system analysis and an implementation proposal for the SuperTrans system, a customer transaction system to be used by banks. In the first part of the paper, we will begin by briefly reviewing the system requirements proposed in the given scenario. We will then represent some of More these requirements in a more formal manner, using UML diagrams.

specifically, we will demonstrate a set of Use Cases for the system, we will see a class diagram of all classes our proposed application and we will also see some sequence and state machine diagrams. In the second part, we will describe the proposed implementation. Firstly, we examine the communication sequence between the server and client and we will analyse the way in which the server receives and handles client request. We will then describe the client side of the system and go through all front end forms as well as the code behind them. Moreover, we will take a look at some utility classes that we have designed to facilitate our work. we will identify the We will then discuss the issues that arose during the developed systems weaknesses and propose some development process and the ways in which we dealt with some of them. Finally, appropriate solutions. Concluding this paper, we will see that the resulting application is a system that focuses particularly on extendibility and scalability. the needs of a small bank. We have developed a solid system core that can be improved and expanded to easily fit

2. REQUIREMENTS2.1 Functional & Non-Functional RequirementsThe scenario requires the development of a Java application to cover the needs of a bank (DORBank in our proposed system). The requirements provided 1

SUPERTRANS CUSTOMER TRANSACTION SYSTEMare somewhat general and thus imply a system that will implement a long series of procedures and as well as a solid security mechanism, not unlike the professional systems of todays large financial institutions. The system must support the common tasks carried out by both bank staff and customers, such as cash deposits and withdrawals, utility bill payments, credit card payments etc, requesting a confirmation before each transaction. Staff options should also include adding customers, creating bank accounts, issuing and managing cards and creating new system credentials for customers. The banks management should also have access to employee records and must be able to handle employee access to the system. All the above should be implemented in a user friendly environment that facilitates the common tasks carried out by the staff or the customers, and that also implements a security mechanism that only allows access to those feature available to each user. The client application should not be different for staff and customers, but should rather disable the procedures that the user does not have access to. cards. On the server side, the application should be able to authenticate users, receive and appropriately process their requests and also provide a simple interface that will allow the staff to configure the server as needed. communication with the client part should be done via sockets. All Finally, as the The scenario states that a customer can only have one user ID and up to three credit

bank also uses some older types of devices, it is important that requests be processed on a separate service, so as to allow the handling of requests from these devices.

2.2 Use Cases & Sequence DiagramSome sample use cases can be seen in Appendix A and while their descriptions are seen in Appendix B. These use cases essentially describe the interaction of actors (customers, staff or the system server) inside the two main interfaces of the system: the customer interface and the staff interface. The design of the use case was made in such a way so as to facilitate the analysis of the complex system into two main parts. too complex to read and understand. In fact, the manner in which the parts of the system and the end users interact is demonstrated in a much clearer fashion in the sequence diagram in Appendix D. The diagram depicts in detail the exact steps taken when a regular scenario of the Transfer Money use case is realised. It would have been impossible to depict the entire system inside on use case diagram without making

2

PROPOSED SYSTEM Stathis Polyzos

2.3 System ClassesThe class diagram for the systems entities is shown in Appendix C. This system shows the required system classes, their attributes and their methods. Note that, in order to simplify the diagram, we have not included the get and set methods regarding the class attributes, but it goes without saying that these need to be implemented in the final system. However, the relationships between the classes are exhibited clearly and the resulting diagram can make an efficient guide to the programmer regarding the implementation of the system. Extending the Transaction object, we are requested to show a State Machine diagram for that object. This requirement is not clear (e.g. whether it refers to a bank transaction or a system transaction); hence the developed diagram shows the progress of a system transaction object from the client to the server until it ends up in a successful or failed state.

3. PROPOSED SYSTEMThe proposed application is a Java application that has been developed in Borlands JBuilder 2006 for Windows using the Java Development Kit (JDK) version 5 update 6 (v. 1.5.0_06-b05), which was the latest update at the time of development. The development environment, JBuilder 2006, is a cross-platform development solution and is generally accepted to be one of the best packages in the market today. The source code for all classes can be found in Appendix F, while screenshots of the GUI are shown in Appendix K. demo procedures are demonstrated in Appendix J. Finally, we have created two installation packages (one for the server and one for the client) that install the applications to the computer and create handy shortcuts. The programs can be started using a Windows executable application and include all the necessary libraries and class files that each part of the system requires. Additionally, the requested

3.1 Communication: TradeToken and its ContentsOur first point of analysis is the method of communication between the server and its clients. As we will see later, the server and client exchange objects using object data streams. TradeToken. The particular object that is exchanged is the TradeToken objects are serialisable and include only two data

members, the tokens data and an integer variable (objectType) that signals to the system how the token must be handled. The data contained in the token is 3

SUPERTRANS CUSTOMER TRANSACTION SYSTEMset to be of type object, since it can include an instance of any class, with the objectType providing additional information. 3.1.1 Common Objects The objects that the clients send to the server are all included in the CommonObjects package and are listed, along with the expected return information in Appendix G. These objects are also serialisable (so as to be included in the TradeToken without problems) and carry all the required information for some sort of action to take place. There are different objects to make a transfer from one account to another, or to make cash transactions. The use of these objects to carry the required information provided scalability to the application since it is easy to include new features by simply adding new objects and telling the server how to handle them. Since most of these objects carry one or two pieces of information, we will not describe all of them, but will rather explain the framework in which they where developed and analyse a few of them that are either important or more complicated. By far the most important token data object is the LoginStatus object. This is the only object that cannot be passed from the client to the server, but only vice versa, whilst this type of object is included in nearly all other types in the package, as well as all forms in the ClientPack. The client sends a login request (object LoginUser type 1) with the username and the password (as well as the hostname and the port, information that will later be returned to and used by the client). If the username and password match a set from the database, then a LoginStatus object is created, which included the server and port that the login information was successful (this will be used to route the other objects), a boolean variable (status) that signals a successful login and the user ID. As you will see from the constructor, the values of the status variable and of the user ID cannot be set to true when the object is initialised, but they can only be changed by calling the appropriate method with the correct integer value. In our proposed system, the value is a simple six-digit number, but in a more professional implementation this would be a longer number generated by an algorithm, possible requiring more data exchange*. This procedure implements a basic security mechanism, since all processing on the server side requires that the status variable be true on the object passed in each token. Another interesting object is the UserID object (type 3). This object

essentially sends the users ID to the server along with the users LoginStatus and an integer (actionType) that marks the corresponding action required from the server. In essence, this is an extension to the logic of the TradeToken and

* For example, the server could send a number to the client, the client would then process the number and return the result which should in turn match the result of the same process performed on the server side.

4

PROPOSED SYSTEM Stathis Polyzos this is portrayed by the nested switch statement for the case of that particular object in the token handling algorithm. Some action types actually use the user ID, to get for example the users accounts, credit cards or the access level, while others disregard it and just check the LoginStatus object. We will see this when we discuss token handling later. by the server. Some other token data objects are instantiated using string variables but actually use that information to instantiate other system entities like Account, or Transaction objects. Examples here include the MakeTransaction, the MakeTransfer, or the MakeTransferToCredit objects. The framework under which these common token data objects were built is fairly simple. Firstly, all objects (except for the UserID) must have a LoginStatus data member and must implement a GetStatus method that retrieves the status variable from that data member. Additionally, there are no default constructors, whilst overloading has been avoided, as a simple efficiency mechanism, since these objects serve a very particular cause and using them in various forms could create errors during token handling. Finally, for the same reason, there are no set methods while the gets return only the data of interest. We could have developed these classes using a parent class and having all of them extend it, but this practice created problems in token handling and was dropped (further discussion in section 4.1). 3.1.2 Entities Inside the CommonObjects package, we have included a sub-package called Entities, which essentially defines the classes for the records in the database tables. In fact, the class attributes in this package are identical to the field in the corresponding database tables. These classes are self-explanatory in general and have been designed in absolute accordance with the class diagram in Appendix C so we will only provide some general observations. Contrary to the token data objects, these objects include default constructors and implement get and set methods for all attributes. Additionally, in some of them, we have implemented particular constructors that instantiate the object by reading its attributes directly from the database using a Connection argument and the appropriate unique key. All the classes extend the DatabaseObject abstract class which includes the ID attribute, its get and set methods and the two required abstract methods to add and save the object to the database. All child classes implement the AddToDB method that adds a new object to the appropriate database table. Similarly, the SaveToDB method updates the database with the information that is 5 Action types are also used when exchanging Customer and Employee objects (types 14 and 15 respectively) for manipulation

SUPERTRANS CUSTOMER TRANSACTION SYSTEMstored in the particular instance of the class. Note here that a new object must have ID field equal to zero. A nifty trick added to the AddToDB method is that after the object has been added to the database, the method reads the last item in the appropriate table and stores its ID (primary key) to the ID variable of the given object, which was previously zero. Hence, when we call the AddToDB method on an object, its ID attribute is updated to match that stored in the database. The SaveToDB is not implemented on all objects since not all objects are directly accessible to the end user. An important note relates to the particular implementation of the Customer and Employee classes. These classes extend a parent abstract class (i.e. cannot be instantiated), namely Person, which in turn extends the DatabaseObject class. A Person object should always have a fullName and an address. class. The child classes inherit these attributes (and the corresponding get and set methods) and implement the attributes and methods particular to each Similar inheritance characteristics have been implemented in classes Transaction and CreditCardTransaction which extend the GenTransaction abstract class. Some classes implement methods that manipulate the data specifically for that class. For example, the CreditCard class includes the ChangePIN method to change the PIN of a credit card (and update the information in the database), including the necessary security procedures. Correspondingly, both the CreditCard and the User class include Activate and Deactivate methods that complete the corresponding actions, as requested in the specifications. A noteworthy observation at this point relates to how we have chosen to handle utility payments. Similarly to a real banking environment, a public utility company (PUC) is nothing but an instance of the Customer class. However, in that class (and, thus, in the customers table in that database), we have included a Boolean attribute that shows us whether a particular customer is a PUC. PUC customers are only allowed one account, to enable the system to locate their account by the customer name. customers name. Finally, it must be explained that the type variable in realisations of the GenTransaction class is set to 1 for deposits and 2 for withdrawals. This is also stored in the database and it allows the proper updating of the accounts balance in real time by the database. Consequently, the Account class includes an extra String attribute, which was not included in the design and which holds the

6

PROPOSED SYSTEM Stathis Polyzos

3.2 The Server3.2.1 Front End We will continue this analysis by describing the server part of the GUI. When the banks system administrator starts the server (called CSPA) on the bank servers, the main application frame appears. The option that are required here are the name of the computer that hosts the application database, the name of the database itself and a valid username and password. By pressing the Up Server button, the server starts (actually a server thread starts) and incoming requests can be handled and processed. Note that screenshots of the proposed system are supplied in Appendix K. The database connector used is the latest version of Microsofts own SQL Server driver for JDBC that supports JDK 1.5*. The actual connection object is returned by calling on a method from the database utilities class (see section 3.5.2), and is passed as a parameter to the server class. Note that since the name of the computer that host the database server is given by the user, the application server and the database server computers need not be the same, thus allowing a three-tier architecture, so popular in todays enterprise systems. Now, the server class constructor accepts this parameter and starts a new server socket (a socket capable of accepting incoming connections) at port 5701, and starts a new thread where new connections can be handled. This thread runs while the allowRun variable is true (it becomes false when the server must be stopped) and sends incoming connections on a new thread class, ConnectedClient class. We have chosen to handle connections on a different

thread to enable the server to accept a connection from a new client even if the processing of request from the previous client has not been completed yet. The database connection is passed as an argument to the new thread. The type of stream selected to exchange information between server and client is the object stream, since objects will be exchanged between server and client, and more particularly instances of the TradeToken class which is described in section 3.1. Hence, an ObjectInputStream and ObjectOutputStream are created when a new client connection is accepted. We receive a TradeToken on the ObjectInputStream, handle it (HandleToken method, see below) and return another TradeToken on the ObjectOutputStream. closed. All connections are then

* The driver can be downloaded from Microsofts website at http://www.microsoft.com/downloads/details.aspx?FamilyID=e22bc83b-32ff-4474-a44a22b6ae2c4e17&DisplayLang=en (link valid on 28 January 2005) and is also included in the accompanying CD. The port number is hard-coded into the application for simplicity; it could alternatively be inputted in the server GUI frame, like in the client login form.

7

SUPERTRANS CUSTOMER TRANSACTION SYSTEMThe above summarises the communication tasks carried out by the server. We have kept the data exchange functionality as simple as possible so as simplify communication testing, which in fact was the first issue in the development process. 3.2.2 Database The database behind the server was designed using the last version of MS SQL Server, namely the 2005 edition*, even though the server can also connect to SQL Server 2000 databases, since the connector works for all versions. It will not be described in great detail since it is a relatively simple model. A diagram of the tables and the relationships between them is shown in Appendix I, while the required SQL code for building the database is included in Appendix H. The fields of all tables are also attributes of the corresponding classes (see section 3.1.2 above) implemented in the application. The only exception here relates to the transaction date fields which are entered automatically by the server to prevent user errors or inconsistencies (e.g. a transaction is entered on a date after the current date). Additionally, the RegDate field in the tables that do not carry a transaction date is the date the record was inserted; it is also assigned by the database. Finally, a trigger has been implemented on the transactions table that updates an accounts balance when a related (tbl_Transactions)

transaction record is inserted, updated or deleted.

3.3 Server-Side Tasks Token HandlingToken handling, as well as all required processing, takes place on the server side. This automatically reduces the load off the client terminals and also allows older devices to send their requests to the server, as required in the system specifications. The server class is the ServerCPSA class, a class that extends Thread (to allow the front end to function while the server is running). While it runs, this class waits for connections and reads incoming object from the client. The server starts a new thread to process all incoming connections. This thread receives the TradeToken from the client, processes it and returns another TradeToken, with the requested information. The particular method that handles the tokens goes by the unimaginative name of HandleToken. The method starts by initialising the variables that will be required during the processing. The code for this method is

* We used MS SQL Server 2005 Workgroup Edition during development since it is the only version that runs on a 32-bit x86 workstation with Windows XP. For more advanced server systems, the Enterprise edition can be used instead, which also supports 64-bit systems. In a real banking environment, this may be permitted as most transactions carry a date value known, in Greece at least (and probably in France too!), as Valeur which signifies the date as of which the transaction is valid. However, we choose not to implement this feature for reasons of simplicity.

8

PROPOSED SYSTEM Stathis Polyzos quite large, but the actual processing time should be small, since a switch statement is used to do the required tasks for each token. For each case, comments mark the type of object that must have been received according to the TradeTokens data as well as the type of data that must be placed on the returning TradeToken. A list of the token data, their types and the returning data is shown in Appendix G. A popular returning data type is the confirmation token, which includes null data and either 1 (for success of the operation) or 0 (for failure) as the data type. As we can see, in all cases (except case 1, i.e. before login), the first action that takes place after reading the data from the incoming token (incToken) is the verification of the users login status. If the user has not successfully logged in, the operation stops returning a null TradeToken (null data and -1 as the data type). We can also see that when an error occurs, the returning token is again the null TradeToken. However, some procedures return particular error tokens. For example, in case 16, where a new account must be added to the database (object AddAccount), if the customer is a public utility company and already has an account (i.e. new account cannot be added), the error token returns the number of the existing account. Similar error token are returned for cases 17 (new user object AddUser) and 18 (new credit card object AddCreditCard). Another important note has to do with cases where the return data is an array. In these cases, we chose to include the arrays length in the returning TradeToken as its objectType, so as to facilitate the handling of the array on the client side. Finally, in cases where a double transaction must take place (e.g. a transfer from one account to another), if the second transaction in the set fails, we rollback the process by removing the first transaction from the database, not unlike professional banking information systems.

3.4 The ClientThe client GUI is slightly more complicated than the server GUI, since we need to implement the security functionality proposed in the requirements. Before we start discussing the GUI, we must say that the singleton pattern has been implemented on all forms to prevent multiple instances of the same form. According to the singleton pattern, the forms constructor is private, the class includes a data member of its own type (unForm) to see if it has been instantiated and a public method (Instance in our implementation) is used to instantiate the form; the form is instantiated only if its instance data member (unForm) is null.

9

SUPERTRANS CUSTOMER TRANSACTION SYSTEMAdditionally, all forms check if the user has successfully logged on, by using the GetStatus method in the status data member they all have. When the client application starts, the first frame that appears is the login frame (see Appendix K), which ask the user to input the server name and port and also provide a valid username and password. When pressing the Connect button, the first thing that must be done is to get the required arguments, namely the host name and port and the users name and password. The system corrects erroneous input either by filling in the blanks or by presenting the appropriate error messages. Once all information is successfully entered, a LoginUser object is prepared and sent to the server using the DispatchToken method (included in ClientUtilities see section 3.5.1). We receive the reply from the server and check the login status. error. If the user has failed to login, we inform them of the Four consecutive failed login attempts will end the application; a simple

security measure. If the user has successfully logged in, we present a message and then the main menu form appears. This menu is different for customers and for staff. 3.4.1 Customers The customer menu comes from the MainMenu class. It is a JFrame object that includes buttons that complete certain tasks for the customer. From the point of view of the customer, this application represents an electronic banking solution. Hence, no cash transactions can take place from this component. As requested in the system specifications, before any transaction is initiated, a confirmation dialogue box appears. The first option on the form is the account status form. The second button (Account Transactions) opens up This form a form

(frmAccountStatus) simply shows the customers accounts and their balance. (frmListTransactions) that allows the user to see the transactions that took place for a particular account in the given time period. Customers select the account of interest from a combo box and also provide the date period required. The parts of the dates are entered in different text boxes, so as to avoid the complications of using the Date or the Calendar class, and validated immediately through the ValidateField method. This method checks the validity of the data entered in the field according a maximum allowed value (e.g. 12 for months). Hence, when the user presses the View button, all data entered is valid. When the button is pressed, the application asks the transaction list from the server. The dates are passed in the format that the SQL query will use them (i.e. in the form yyyy-m-d). The incoming token carries a Transaction array and its length. If the arrays length is zero, the user gets the information; otherwise 10

PROPOSED SYSTEM Stathis Polyzos the transactions are displayed in the text area, with the minus sign leading the sums of outgoing transactions (type 2). The Transfer Money button is next in the main menu form. The button

opens up the frmTransfer form that allows customers to transfer money between their accounts. The form adds the customers accounts to two combo boxes so that the user can easily select them. The amount is entered in a text box and validated on input (also see the ToDouble method in ClientUtilities section 3.5.1). When the user presses the Transfer button, the system first checks that the request is a valid one (source and destination accounts are different, enough funds exist at the source account) and sends the request to the server. Appropriate messages appear according to the incoming confirmation. The next option is the Pay Utility option that opens the frmPayUtitlity form. This form is identical to the frmTransfer form, with two exceptions. In the target account combo box, the names of the public utility companies are entered and there is a field to add the customers number at the particular company where the payment is made. The number is added to the transactions comments so that the company can process the payment correctly. The fifth button on the main menu opens the frmTranferCreditCard, which performs a payment from an account to a credit card. It is essentially similar to the frmTransfer form with the only difference that the destination account is now credit card. The object carried in the sent TradeToken is now a MakeTransferToCredit object. The last button opens the form that allows a user to change the PIN to a card, the frmChangePin form. If the user is a customer, the credit cards allowed are only those of the particular user, otherwise the combo box lists all cards. The user must enter their old PIN and enter the new PIN twice. The two new PINs are must be equal. The old PIN is not verified here, as it is verified when the ChangePin method will be called on the CreditCard object on the server side. Appropriate message appear according the confirmation received from the server. 3.4.2 Staff The bank staff forms are more in number, since the tasks carried out by the bank staff are far more. The main menu (MainMenuInt) of an employee user includes the most common options inside the bank. transaction. The first two buttons on the form enable the employee to perform a single account transaction, i.e. a deposit or a withdrawal. These two buttons open the same form (frmTransaction) passing an integer parameter that holds the type of 11 Similarly to the options visible to the banks customer, the system requests confirmations before each

SUPERTRANS CUSTOMER TRANSACTION SYSTEMthe transaction. The user enters the account number (by hand to avoid errors in selections, similarly to the transaction forms of real banking systems) and the amount and presses the Make Transaction button. The system firstly verifies user input, verifying the amount, the account number and the available balance, in case of a withdrawal. Note that account information is requested from the server after the amount is verified to avoid unnecessary traffic. The information is then passed on to the server who sends back a confirmation. The third button on the form opens the frmPayCreditCard that enables the user to perform a payment to a credit card. The process is similar to the transfer, with the system verifying user inputs, sending the request and informing the user of the reply. An interesting feature here is the automatic formatting of credit card numbers with a space every four digits, so as to improve readability. Similarly to the previous transaction processes, the frmUtilityTransaction form, which is the next in the main menu, performs a payment to public utility company account. The next option is only enabled if the user is a supervisor, i.e. has access level 1. A Boolean variable (supervisor) which is passed to the form during at user logon decided whether this button is enabled or not. This button opens the employees form (frmEmployees) which handles bank employee information. Similarly, the next button of the customer menu (which opens by the pressing the last button on the main menu) opens the frmCustomers form to handle customers. These forms include fields to enter all appropriate information and also include user friendly navigation buttons. They also include buttons to add a new record, to save changes to a record and to add related entities, namely a user ID and, for customers, a credit card or an account. Navigation is achieved by requesting employee or customer information from the server when needed. An integer array containing all employee or As the user This customer IDs is requested from the server on form initialisation.

presses the previous or next buttons, the appropriate ID is sent to the server requesting the corresponding entitys information from the database. procedure serves two important purposes. Firstly, it ensures that the user sees the most recent information on the form and, secondly, it minimises the entity data that must be stored in the memory of the client while the form is open. Imagine if the bank had a thousand employees and the system had to load all information to an array, or even a linked list. This would create a bigger problem in the case of customers (where navigation is the same), since they are expected to be much more. However, this procedure does not solve concurrency issues since once the object is sent to the client, the server will still allow changes to that object from other clients. This problem could also be solved by having the

12

PROPOSED SYSTEM Stathis Polyzos server keep a list of objects sent to clients and to send each object to other clients as read only while the first client is still viewing it. The forms are populated by a method called PopulateForm. This method reads the information from the server according to the current employee or customer ID and fills the forms fields with the received information. If the user wants to enter a new record, the form is cleared. This method is called at startup and also as the user navigates the available records. When the user wants to Save the data, the corresponding button pressed. The method saves the forms data into an Employee or Customer object and sends it to the server inside the appropriate token data object with the action type 1 to add or 2 to save an existing record. The server uses this information to call the appropriate method on the object. In case of success, the appropriate message pops up and if the object is a new (i.e. add), the form closes so the list of IDs can be updated*. When a new related entity (user ID, credit card or account) needs to be added, two important pieces of information are passed, along with the login status, which is, as mentioned earlier, present in every form. This information is the current entitys name and ID. The name is saved to the top of the insertion form for user-friendliness purposes, while the ID is used to link the related entity with the current one. In the case of the user ID, the forms also pass a Boolean variable indicating if the new ID will belong to an employee or a customer, as well as the permitted user levels. These insertion forms verify the data entered against objective rules (e.g. credit card number is sixteen digits long, a pin is four digits long) and send the request to the server. The servers handling of these insertion objects has been configured to output particular error results for cases where everything was done properly, but the record cannot be added because of a specifications limit. For example, as mentioned in section 2.1, a customer can only have up to three credit cards and only one user ID. We impose these limits from the front end, even though a database trigger would have been easier and possibly more efficient. The Customer menu includes common option regarding customer

management. The first option is, as mentioned earlier, the Customers form. The second and third options open the same form (frmActivateSuspend) that enables an employee to enable or suspend a credit card or a customer user ID. The form is informed of the required action by a Boolean variable (activate) that is passed as an argument. The form includes two check boxes that are programmed to be mutually exclusive (i.e. it is not possible for them to have the

*

This is, admittedly, not the most fitting solution, but it is a working one! The user levels are passed as arguments for scalability purposes; it may be required that the same form calls the new user ID form for different, but specific, access levels.

13

SUPERTRANS CUSTOMER TRANSACTION SYSTEMsame value) and that signal if the suspend/activate operation will be performed on a card or a user ID. User IDs and credit cards are conveniently selected from a combo box. When the user presses the button (whose caption changes according to the required operation), the method sends the request to the server and processed the reply. The last option on the customer menu opens the frmChangePin form that enables a staff member to change the PIN of a customers card. personal and the bank staff can never have access to them. This process However, this would never occur in a real banking environment, since card PINs are strictly featured is mentioned in the requirements and thus we implement it here. The form and its functionality were described earlier when discussing the customers part of the application.

3.5 UtilitiesTo facilitate the programming work, we have implemented some common procedures as methods in utility classes. We have separated these utilities into two categories, namely the client and the database utilities, according to the functionality that they perform. Let us examine each of these two categories in turn. 3.5.1 Client Utilities The ClientUtilities class implements a series of methods whose purpose is to automate request and receive procedures that are required often at the client side. The first such method is the DispatchToken method. This method is the method used to send tokens to the server and receive the replies. It reads the TradeToken and LoginStatus objects passed as arguments, builds opens up a socket with the server (the host name and port are provided in the LoginStatus object), initialises the appropriate object streams (to send and accept serialised objects) and dispatches the token to the server. It receives and stores the reply and returns it as output after shutting down all connections. The next series of utilities retrieves specific information from the server. For example, the GetUserAccounts method returns an array that includes the Account objects associated with the customer who uses the particular user ID. Similarly, all methods return some form of information that either is particular to the active user or relates to more general information required by employee users (e.g. list of all credit card numbers). The last utility method, ToDouble, parses a string as a double. The reason that this method is used, as opposed the simple parseDouble of the Double 14

DEVELOPMENT ISSUES COMMENTS Stathis Polyzos class, is that it includes a few more functionalities. Firstly, it includes appropriate error handling procedures (with the try... catch syntax) so it shortens the code whenever we need to use it. Secondly, it does not allow the use of negative numbers since the method is used to parse currency amounts and third it tries to parse the string twice; once as is and once without any decimals or separators. If an error still occurs, or if the resulting value is negative, -1 is returned. 3.5.2 Database Utilities The DBUtilities class is particular to the server side, since the client does not have direct access to the database, and implements methods relating to database access, without however excluding database access by other means. The first method it includes is the method that builds a connection to an SQL Server database. The arguments passed are the servers name, the database name and a valid username and password. As mentioned earlier, the connector used is Microsofts own SQL Server connector for JDBC. The other two methods implemented retrieve information often required by the token handling algorithm, namely the users customer ID and the users access level. The former is used to locate other entities related to the customer who uses the given ID, whereas the latter is used to decide the allowed actions of a system user.

4. DEVELOPMENT ISSUES COMMENTS4.1 The Development ProcessThe development of this extensive system was neither an easy nor a smooth process. A series of issues had to be addressed both during the design and during the implementation process. The first issue was the lack of any previous experience or practice on the requested CASE tool, namely Visual Paradigm. Even though the program is relatively easy to use, it did in fact require a lot of practice before the appropriate diagrams could be drawn. Naturally, all the interesting features of the product that aid the development process could not be effectively exploited exactly because of the lack of familiarity and of academic practice on the product. Additionally, the latest (5.1) version has some problems when requesting community keys and hence we had to be in contact with the Visual Paradigm support line to resolve the issue. The second issue relates to the given specifications. The fact that the

scenario given was quite general and did not propose particular functional 15

SUPERTRANS CUSTOMER TRANSACTION SYSTEMrequirements forced the developer to implement probably more features than would be expected. This occurred because it had to be ensured that the resulting system answered to the idea of the system proposed in the scenario, even though that idea was not exactly clear. From this issue, a third issue occurred: data storage. The scenario

mentions nothing about the underlying database system. An immediate thought would be that no such system was required. However, this would make testing difficult because of the relationships between the entities: how would we be able to repeatedly test the process of a transaction insertion, when we would have to manually enter customer and account details before every test? The answer to the issue was MS SQL Server 2005. Even though seemingly a huge database system (for example MySQL could have been used instead), the authors familiarity with the particular product along with Microsofts handy connector made the process relatively easy and definitely of huge practical interest. Other than the specification issues, a dilemma faced in the development process related to the data carried in the tokens. At first, we had designed the system so that all data classes would inherit their common methods from a parent class. This would facilitate the development process and would also demonstrate the benefits of inheritance. However, there was an issue with the returning tokens; most returning tokens are not specially developed classes, but classes native to the Java class (or particular to some of its common libraries). They could not be carried in the same TradeToken object, unless the token included more data members that would be empty when travelling from client to server and would be filled only on the way back. dropped. This solution however would result on wasted data exchanged between the end points and was immediately Another choice would be to build a different class for the returning However it was deemed Hence the data objects tokens (e.g. ReturnToken), which was acceptable. particular object that would travel along the network.

preferable and more efficient to have a common method of communication, a placed in the tokens where developed as different classes. A final issue related to the development environment. Even though

noticeably better than its predecessor, JBuilder 2006 has certain issues when rendering forms if the developer chooses to implement any functionality out of the ordinary. For example, the fact that we used private constructors made it impossible for JBuilder to show the forms in the designer, if the designer had not rendered the form previously with a public constructor. Thus, we had to disable this functionality so as to design the form and re-enable it afterwards. dealt with. This somewhat impeded the development process, but it was a problem that had to be

16

DEVELOPMENT ISSUES COMMENTS Stathis Polyzos

4.2 Test Scenarios4.2.1 Invalid logon attempts In the first test scenario, we will attempt to log in to the system using invalid credentials. We attempted to login using a blank password and the login process failed; we got a Login rejected message. attempt, the application was automatically terminated. 4.2.2 Attempt Logon when Server is down In this scenario, we attempted a logon when the server was down. The process did not complete with no error message at all. Additionally, if the attempted connection occurred after the server was put online and then offline again, the client application crashed and it was unavailable until we terminated the server application. 4.2.3 Deposit to a non-existent account In the test case, we tried to make a deposit to a non-existent account. The deposit did not complete and we received an appropriate Account does not exist error message. 4.2.4 Use of invalid amounts In this case, we tried to enter invalid amounts to the text boxes of forms. The system did not allow us to enter invalid or negative amounts and produced an informative error message. However, the error message appeared three times before we were allowed to re-edit the amount on the form. 4.2.5 Invalid date ranges for account transactions In this scenario, we requested the transactions of an account using invalid date ranges. Firstly, we requested the transactions from data 1 February 2006 to 1 January 2006. The result was a message saying An error occurred or no Additionally, we tried to transactions exist, which was not at all informative. After the fourth login

request transactions from 1 January to 31 February 2006 (an invalid date). In this case, the application crashed and would not be terminated until we shut down the server. 4.2.6 New user ID to an inactive employee In this test, we tried to add a new user ID to an inactive employee. The system allowed us this operation, when it should have rejected the request. 4.2.7 Alphabetical Characters in PIN In this scenario, we tried to use alphabetical characters in the PIN. This process was allowed by the system, even though it should not have been under normal conditions. 17

SUPERTRANS CUSTOMER TRANSACTION SYSTEM4.3 System CritiqueDespite all the aforementioned issues, the resulting system is a solid, professional application that definitely covers requirements of the given scenario. However, fine tuning. Firstly, the developed application is not as object-oriented as it could be. In a better tuned end system, all objects would be loaded by the server and the client would call (invoke) methods on them remotely probably using the Javas Remote Method Invocation (RMI). This would greatly simplify the communication between the server and the client, but it would require a more thorough implementation of methods in all the entity objects. There would be no server process to directly handle incoming client requests and thus manipulate objects. Hence each object would have to include methods to manipulate each of its attributes. A possibility would also be to include database operations in the set methods of the attributes; as the attribute would be modified with the set method, the corresponding record could immediately be updated in the database. Another drawback relates to the systems GUI. Admittedly, the developed GUI, albeit practical, is not that original and does not include common options, like a menu bar or a toolbar. Of course, these options were neither requested in the specifications nor required in the form that the system was developed. But still, it would have made a good addition to include more visual stimulation in the delivered GUI, even though JBuilder is not particularly helpful in this process. Furthermore, some operations are not supported by the system. For example, the deletion of entities, or the settling of account was not implemented. However, these procedures are simple to develop and cannot be considered a serious drawback to the system, particularly since they were not present in the given requirements. Finally, we have located some bugs during our brief testing process in section 4.2 above. Obviously, a more thorough testing procedure would have to take place and all located bugs would have to be corrected if the system were to be released in a commercial form. like all professional applications, there is certainly room for improvement and we have in fact pinpointed some features that could use a little

5. CONCLUSIONConcluding this paper, we have firstly discussed the scenario given and deduced the necessary requirements. We have then formulated these requirements into UML diagrams, namely use case, class, sequence and state machine diagrams, and discussed a little about these diagrams. 18

CONCLUSION Stathis Polyzos We have then implemented these requirements into a complete Java database application using cutting edge tools, like JBuilder 2006 and MS SQL Server 2005. We provided a comprehensive analysis of all the systems features and discussed in detail how the final system achieves communication between its client and its server part. Subsequently, we discussed some of the issues that arose during the development process and the way in which we dealt with them. We then tested the system using some test scenarios and shown that even though the system does include error handling procedures that protect it from crashing or malfunctioning, there are a few bugs that need to be dealt with. Finally, we have recognised that the delivered application does have some weaknesses and proposed ways in which these could be corrected. Summing up, we can definitely say that, despite its bugs, the final system is a solid application that requires only a bit of fine tuning if it were to be released in a commercial form. and in terms of security. The tools used are state-of-the-art and the end result could cover all the operational needs of a small bank, both in terms of usability

19

.

USE CASE DIAGRAMS Stathis Polyzos

APPENDIX A. USE CASE DIAGRAMSA.1. Customer Use Cases

21

SUPERTRANS CUSTOMER TRANSACTION SYSTEMA.2. Staff Use Cases

22

.

USE CASE DESCRIPTIONS Stathis Polyzos

APPENDIX B. USE CASE DESCRIPTIONSB.1. High LevelB.1.1. Activate/Deactivate Card BASIC COURSE OF ACTION1. 2. 3. 4. 5. Employee user requests to activate/deactivate card System displays all card numbers to user User selects card System asks for confirmation. If user gives negative reply, go back to 3 Transaction dispatched to server and system informs user of result; if failure go back to 3 else end use case.

B.1.2. Activate/Deactivate User BASIC COURSE OF ACTION1. 2. 3. 4. 5. Employee user requests to activate/deactivate user System displays all customer usernames to user User selects username System asks for confirmation. If user gives negative reply, go back to 3 Transaction dispatched to server and system informs user of result; if failure go back to 3 else end use case.

B.1.3. Add New Employee BASIC COURSE OF ACTION1. 2. 3. 4. 5. 6. Employee user selects the employees form If the user is a supervisor, open the form otherwise end use case User asks to add new employee User supplies all required information about the new employee and asks to save System asks for confirmation. If user gives negative reply, go back to 4 Transaction dispatched to server and system informs user of result; if failure go back to 4 else end use case.

B.1.4. Change Card PIN BASIC COURSE OF ACTION1. 2. 3. 4. Employee user selects the change PIN form System displays all card numbers User selects card and provides old PIN one and new PIN twice. System asks for confirmation. If user gives negative reply, go back to 3

23

SUPERTRANS CUSTOMER TRANSACTION SYSTEM5. 6. Old PIN verification and new PIN must be 4 characters exactly. If error, go back to 3 Transaction dispatched to server and system informs user of result; if failure go back to 3 else end use case.

B.1.5. Change PIN (Customer) BASIC COURSE OF ACTION1. 2. 3. 4. 5. 6. Customer user selects the change PIN form System displays customers card numbers User selects card and provides old PIN one and new PIN twice. System asks for confirmation. If user gives negative reply, go back to 3 Old PIN verification and new PIN must be 4 characters exactly. If error, go back to 3 Transaction dispatched to server and system informs user of result; if failure go back to 3 else end use case.

B.1.6. Check Accounts BASIC COURSE OF ACTION1. 2. Customer user selects the check accounts form System displays customers accounts and balance

B.1.7. Check Source Account Balance BASIC COURSE OF ACTION1. 2. 3. User requests withdrawal from account System verifies that amount is less than or equal to account balance System outputs whether transaction can take place

B.1.8. Deposit Cash BASIC COURSE OF ACTION1. 2. 3. 4. 5. User asks to deposit money User supplies the account number and amount System asks for confirmation. If user gives negative reply, go back to 2 Account number is confirmed; if error go back to 2 Transaction dispatched to server and system informs user of result; if failure go back to 2 else end use case.

B.1.9. Pay Credit Card Bill BASIC COURSE OF ACTION1. 2. Customer user requests to pay credit card bill System displays customer accounts and credit cards to customer user

24

.3. 4. 5. 6.

USE CASE DESCRIPTIONS Stathis PolyzosCustomer user selects source account and target credit card and supplies the required amount. System asks for confirmation. If user gives negative reply, go back to 3 If amount greater than source balance go back to 3 Transaction dispatched to server and system informs user of result; if failure go back to 3 else end use case.

B.1.10. Pay To Credit Card BASIC COURSE OF ACTION1. 2. 3. 4. 5. User requests to pay cash to credit card User provides credit card number and amount System asks for confirmation. If user gives negative reply, go back to 2 Credit card number is confirmed; if error go back to 2 Transaction dispatched to server and system informs user of result; if failure go back to 2 else end use case.

B.1.11. Pay To Utility BASIC COURSE OF ACTION1. 2. 3. 4. 5. User requests to pay to utility company System displays PUC accounts to user User selects target PUC account and supplies the required amount as well as the customer number at the PUC System asks for confirmation. If user gives negative reply, go back to 3 Transaction dispatched to server and system informs user of result; if failure go back to 3 else end use case.

B.1.12. Pay Utility Bill BASIC COURSE OF ACTION6. 7. 8. 9. Customer user requests to pay utility bill System displays customer and PUC accounts to customer user Customer user selects source and target account and supplies the required amount and their customer number at the PUC System asks for confirmation. If user gives negative reply, go back to 3 10. If amount greater than source balance go back to 3 11. Transaction dispatched to server and system informs user of result; if failure go back to 3 else end use case.

B.1.13. Transfer Money BASIC COURSE OF ACTION1. Customer user requests money transfer

25

SUPERTRANS CUSTOMER TRANSACTION SYSTEM2. System displays accounts to customer user; if customer only has one account the use case ends 3. Customer user selects source and target account and the required amount 4. System asks for confirmation. If user gives negative reply, go back to 3 5. If source and target are the same or amount greater than source balance go back to 3 6. Transaction dispatched to server and system informs user of result; if failure go back to 3 else end use case.

B.1.14. Verify Old PIN BASIC COURSE OF ACTION1. 2. 3. User suppliers old card PIN System verifies given PIN against card PIN System outputs whether PIN change can take place

B.1.15. View Transactions BASIC COURSE OF ACTION1. 2. 3. 4. 5. Customer user requests to view account transactions System displays accounts to customer user Customer user selects account and supplies the date required System verifies dates as valid; if error go back to 3 System displays account transactions to the user

B.1.16. Withdraw Cash BASIC COURSE OF ACTION1. 2. 3. 4. 5. User asks to withdraw money User supplies the account number and amount System asks for confirmation. If user gives negative reply, go back to 2 Account number is confirmed and its balance checked against amount; if error go back to 2 Transaction dispatched to server and system informs user of result; if failure go back to 2 else end use case.

26

.

USE CASE DESCRIPTIONS Stathis Polyzos

B.2.

Full Description

B.2.1. Change PIN (Customer) PRECONDITIONS1. 2. 3. User has had online credentials issued User has successfully logged in to the System User has at least one credit card for which the PIN is known

POSTCONDITIONS1. User can use new PIN for given card

BASIC COURSE OF ACTION1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Customer user selects the change PIN form Client application requests user card list from server Server sends back the users card number System displays card numbers in a combo box. User selects card and provides old PIN one and new PIN twice System asks for confirmation. If user gives negative reply, go back to 4 Old PIN verification and new PIN must be 4 characters exactly. If error, go back to 4 Transaction request dispatched to server Server verifies incoming information and performs transaction Server informs client of transaction result System informs user of result If failure go back to 4 else end use case.

27

SUPERTRANS CUSTOMER TRANSACTION SYSTEMB.2.2. Transfer Money PRECONDITIONS1. 2. 3. User has had online credentials issued User has successfully logged in to the System User has at least two accounts with one having enough balance

POSTCONDITIONS1. Money is available in target account

BASIC COURSE OF ACTION1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. Customer user requests money transfer Client application requests users account from server Server replies with user account list System displays account numbers to user in a combo box (Alternate course A: User has only one account) Customer user selects source and target account and the required amount System asks for confirmation. If user gives negative reply, go back to 4 If source and target are the same go back to 4 If amount greater than source balance go back to 4 Transaction request is dispatched to server Server reads incoming information Server performs first transaction (withdrawal from source) If successful, perform second transaction (deposit to target) (Alternate course B: Withdrawal unsuccessful) If successful, return positive confirmation to client (Alternate course C: Deposit unsuccessful) System informs user of transaction result; use case ends

ALTERNATE COURSE A: USER HAS ONLY ONE ACCOUNTA5. End use case

ALTERNATE COURSE B: WITHDRAWAL UNSUCCESSFULB12. Return negative confirmation B13. Go back to 4

ALTERNATE COURSE C: DEPOSIT UNSUCCESSFULC13. Rollback transaction Delete withdrawal C14. Return negative confirmation C15. Go back to 4

28

.

CLASS DIAGRAM Stathis Polyzos

APPENDIX C.

CLASS DIAGRAM

29

SUPERTRANS CUSTOMER TRANSACTION SYSTEM

APPENDIX D. SEQUENCE DIAGRAM

30

.

STATE MACHINE DIAGRAM Stathis Polyzos

APPENDIX E.

STATE MACHINE DIAGRAM

31

SUPERTRANS CUSTOMER TRANSACTION SYSTEM

APPENDIX F.F.1.

SOURCE CODE

ClientPack

F.1.1. ClientGUI.java package ClientPack ; import import import import import import java.awt.* ; java.awt.event.ActionEvent ; java.awt.event.ActionListener ; java.io.ObjectInputStream ; java.io.ObjectOutputStream ; java.net.Socket ;

import javax.swing.* ; import import import import CommonObjects.LoginStatus ; CommonObjects.LoginUser ; GlobalPack.TradeToken ; GlobalPack.ClientUtilities ;

public class ClientGUI extends JFrame { private JPanel contentPane ; private JMenuBar jMenuBar1 = new JMenuBar () ; private JMenu jMenuFile = new JMenu () ; private JMenuItem jMenuFileExit = new JMenuItem () ; private JTextField txtServer = new JTextField () ; private JLabel lblServer = new JLabel () ; private JLabel lblPort = new JLabel () ; private JTextField txtPort = new JTextField () ; private JButton btnConnect = new JButton () ; private JLabel jLabel1 = new JLabel () ; private JLabel jLabel2 = new JLabel () ; private JTextField txtUsername = new JTextField () ; private JPasswordField txtPass = new JPasswordField () ; private int errorCnt = 0; public ClientGUI () { try { setDefaultCloseOperation (EXIT_ON_CLOSE) ; jbInit () ; } catch (Exception exception) { exception.printStackTrace () ; } } /** * Component initialization. * * @throws java.lang.Exception */ private void jbInit () throws Exception 32

.

SOURCE CODE Stathis Polyzos

{ contentPane = (JPanel) getContentPane () ; contentPane.setLayout (null) ; setSize (new Dimension (401, 189)) ; setTitle ("CSPA Client") ; jMenuFile.setText ("File") ; jMenuFileExit.setText ("Exit") ; jMenuFileExit.addActionListener (new ClientGUI_jMenuFileExit_ActionAdapter (this)) ; txtServer.setText ("localhost") ; txtServer.setBounds (new Rectangle (91, 19, 128, 19)) ; lblServer.setFont (new java.awt.Font ("Tahoma", Font.BOLD, 11)) ; lblServer.setToolTipText ("") ; lblServer.setText ("Server") ; lblServer.setBounds (new Rectangle (15, 24, 68, 14)) ; lblPort.setFont (new java.awt.Font ("Tahoma", Font.BOLD, 11)) ; lblPort.setToolTipText ("") ; lblPort.setText ("Port") ; lblPort.setBounds (new Rectangle (15, 50, 68, 14)) ; txtPort.setText ("5701") ; txtPort.setBounds (new Rectangle (91, 45, 57, 19)) ; btnConnect.setBounds (new Rectangle (253, 57, 115, 22)) ; btnConnect.setFont (new java.awt.Font ("Tahoma", Font.BOLD, 11)) ; btnConnect.setText ("Connect") ; btnConnect.addActionListener (new ClientGUI_btnConnect_actionAdapter (this)) ; jLabel1.setFont (new java.awt.Font ("Tahoma", Font.BOLD, 11)) ; jLabel1.setToolTipText ("") ; jLabel1.setText ("Password") ; jLabel1.setBounds (new Rectangle (15, 101, 68, 14)) ; jLabel2.setFont (new java.awt.Font ("Tahoma", Font.BOLD, 11)) ; jLabel2.setToolTipText ("") ; jLabel2.setText ("Username") ; jLabel2.setBounds (new Rectangle (15, 75, 68, 14)) ; txtUsername.setText ("GPapak") ; txtUsername.setBounds (new Rectangle (91, 70, 128, 19)) ; contentPane.setFont (new java.awt.Font ("Tahoma", Font.BOLD, 11)) ; txtPass.setText ("123456") ; txtPass.setBounds (new Rectangle (91, 96, 98, 19)) ; jMenuBar1.add (jMenuFile) ; jMenuFile.add (jMenuFileExit) ; setJMenuBar (jMenuBar1) ; contentPane.add (txtServer) ; contentPane.add (txtPort) ; contentPane.add (txtUsername) ; contentPane.add (txtPass) ; contentPane.add (jLabel2) ; contentPane.add (lblPort) ; contentPane.add (lblServer) ; contentPane.add (jLabel1) ; contentPane.add (btnConnect) ; } /** * * File | Exit action performed. * * @param actionEvent ActionEvent */ void jMenuFileExit_actionPerformed (ActionEvent actionEvent) { 33

SUPERTRANS CUSTOMER TRANSACTION SYSTEMSystem.exit (0) ; } /** * * Connect action performed, client attempts logon with the server and * if succesful, the appropriate menu appears. * * @param e ActionEvent */ public void btnConnect_actionPerformed (ActionEvent e) { String hostName = "", userName = "", stPass = "" ; int portNo = 0 ; char[] chPass ; //Server name if (txtServer.getText () == "") { txtServer.setText ("localhost") ; } hostName = txtServer.getText () ; //port try { portNo = Integer.parseInt (txtPort.getText ()) ; } catch (NumberFormatException nexp) { JOptionPane.showMessageDialog (null, "Invalid port...", "Error", JOptionPane.ERROR_MESSAGE) ; return ; } //User name if (txtUsername.getText () == "") { JOptionPane.showMessageDialog (null, "Please enter your user name...", "Error", JOptionPane.ERROR_MESSAGE, null) ; return ; } userName = txtUsername.getText () ; //Password chPass = txtPass.getPassword () ; for (int i = 0 ; i < chPass.length ; i++) { stPass += chPass[i] ; } //Attempt user login try { //Instantiate object LoginUser lg = new LoginUser (userName, stPass, hostName, portNo) ; //Send Token and receive reply TradeToken ret = ClientUtilities.DispatchToken ( new TradeToken (lg, 1), null, hostName, portNo) ;

34

.

SOURCE CODE Stathis Polyzos

//Check reply if (ret.getType () == 2) { LoginStatus lgSt = (LoginStatus) ret.getData () ; // If logged successfully, get the user level and open the // proper menu, else show error message if (lgSt.GetStatus ()) { JOptionPane.showMessageDialog (null, "Succesful login...", "Success", JOptionPane.INFORMATION_MESSAGE, null) ; //Get user level int usr = ClientUtilities.GetUserLevel (lgSt) ; switch (usr) { case 1: //Supervisor MainMenuInt mm1 = new MainMenuInt (lgSt, true) ; mm1.setVisible (true) ; this.setVisible (false) ; break ; case 2: //Staff MainMenuInt mm2 = new MainMenuInt (lgSt, false) ; mm2.setVisible (true) ; this.setVisible (false) ; break; case 3: //Customer MainMenu mm3 = new MainMenu (lgSt) ; mm3.setVisible (true) ; this.setVisible (false) ; break ; default: break ; } } else { errorCnt++ ; JOptionPane.showMessageDialog (null, "Login rejected..." + (errorCnt == 4? "\n\nApplication will exit..." : ""), "Error", JOptionPane.WARNING_MESSAGE) ; if (errorCnt == 4) System.exit(0); } } } catch (Exception uexp) { System.out.println ("Error " + uexp.getMessage ()) ; } } } class ClientGUI_btnConnect_actionAdapter implements ActionListener { private ClientGUI adaptee ; ClientGUI_btnConnect_actionAdapter (ClientGUI adaptee) { this.adaptee = adaptee ; } 35

SUPERTRANS CUSTOMER TRANSACTION SYSTEM

public void actionPerformed (ActionEvent e) { adaptee.btnConnect_actionPerformed (e) ; } } class ClientGUI_jMenuFileExit_ActionAdapter implements ActionListener { private ClientGUI adaptee ; ClientGUI_jMenuFileExit_ActionAdapter (ClientGUI adaptee) { this.adaptee = adaptee ; } public void actionPerformed (ActionEvent actionEvent) { adaptee.jMenuFileExit_actionPerformed (actionEvent) ; } }

36

.

SOURCE CODE Stathis Polyzos F.1.2. CSPAClient.java

package ClientPack ; import java.awt.Dimension ; import java.awt.Toolkit ; import javax.swing.SwingUtilities ; import javax.swing.UIManager ; public class CSPAClient { private boolean packFrame = false ; /** * Construct and show the application. */ public CSPAClient () { ClientGUI frame = new ClientGUI () ; // Validate frames that have preset sizes // Pack frames that have useful preferred size info, e.g. from their layout if (packFrame) { frame.pack () ; } else { frame.validate () ; } // Center the window Dimension screenSize = Toolkit.getDefaultToolkit ().getScreenSize () ; Dimension frameSize = frame.getSize () ; if (frameSize.height > screenSize.height) { frameSize.height = screenSize.height ; } if (frameSize.width > screenSize.width) { frameSize.width = screenSize.width ; } frame.setLocation ((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2) ; frame.setVisible (true) ; } /** * Application entry point. * * @param args String[] */ public static void main (String[] args) { SwingUtilities.invokeLater (new Runnable () { public void run () { try { 37

SUPERTRANS CUSTOMER TRANSACTION SYSTEMUIManager.setLookAndFeel (UIManager.getSystemLookAndFeelClassName ()) ; } catch (Exception exception) { exception.printStackTrace () ; } new CSPAClient () ; } }) ; } }

38

.

SOURCE CODE Stathis Polyzos F.1.3. frmAccountStatus.java

package ClientPack ; import import import import java.awt.Font ; java.awt.Rectangle ; java.awt.event.* ; java.text.DecimalFormat ;

import javax.swing.* ; import CommonObjects.LoginStatus ; import CommonObjects.Entities.Account ; import GlobalPack.ClientUtilities ; public class frmAccountStatus extends JFrame { private LoginStatus status = null ; private Account[] cusAccounts ; private static frmAccountStatus unForm = null ; private JTextArea accStatus = new JTextArea () ; private JLabel jLabel1 = new JLabel () ; private frmAccountStatus (LoginStatus lgSt) { status = lgSt ; if (!status.GetStatus ()) { return ; } try { this.setSize (400, 350) ; jbInit () ; } catch (Exception exception) { exception.printStackTrace () ; } } public static frmAccountStatus Instance (LoginStatus lgSt) { if (unForm == null) { unForm = new frmAccountStatus (lgSt) ; unForm.setLocation (70, 50) ; } return unForm ; } private void jbInit () throws Exception { getContentPane ().setLayout (null) ; this.setResizable (false) ; this.setTitle ("Account Status") ; this.addComponentListener (new frmAccountStatus_this_componentAdapter (this)) ; accStatus.setFont (new java.awt.Font ("Dialog", Font.BOLD, 12)) ; accStatus.setVerifyInputWhenFocusTarget (false) ; 39

SUPERTRANS CUSTOMER TRANSACTION SYSTEMaccStatus.setEditable (false) ; accStatus.setText ("") ; accStatus.setBounds (new Rectangle (28, 51, 339, 219)) ; jLabel1.setFont (new java.awt.Font ("Tahoma", Font.BOLD, 12)) ; jLabel1.setHorizontalAlignment (SwingConstants.CENTER) ; jLabel1.setText (ClientUtilities.GetCustomerName (status)) ; jLabel1.setBounds (new Rectangle (17, 14, 356, 26)) ; this.getContentPane ().add (accStatus) ; this.getContentPane ().add (jLabel1) ; //Get customer's account list cusAccounts = ClientUtilities.GetUserAccounts (status) ; //Initialise text area accStatus.setText ("ID\tAccount Number\tBalance\n") ; //Append results for (int i = 0 ; i < cusAccounts.length ; i++) { accStatus.append (String.valueOf (i + 1) + "\t" + cusAccounts[i].GetAccountNumber () + "\t\t" + DecimalFormat.getCurrencyInstance ().format (cusAccounts[i].GetBalance ()) + "\n") ; } } public void this_componentHidden (ComponentEvent e) { unForm = null ; } } class frmAccountStatus_this_componentAdapter extends ComponentAdapter { private frmAccountStatus adaptee ; frmAccountStatus_this_componentAdapter (frmAccountStatus adaptee) { this.adaptee = adaptee ; } public void componentHidden (ComponentEvent e) { adaptee.this_componentHidden (e) ; } }

40

.

SOURCE CODE Stathis Polyzos F.1.4. frmActivateSuspend.java

package ClientPack ; import java.awt.* ; import java.awt.event.* ; import javax.swing.* ; import CommonObjects.* ; import GlobalPack.ClientUtilities ; import GlobalPack.TradeToken ; public class frmActivateSuspend extends JFrame { private static frmActivateSuspend unForm = null ; private LoginStatus status ; private boolean activate ; private String[] userIDs ; private String[] cards ; private JComboBox cmbCards = new JComboBox () ; private JComboBox cmbUsers = new JComboBox () ; private JLabel jLabel1 = new JLabel () ; private JLabel jLabel2 = new JLabel () ; private JCheckBox chkCard = new JCheckBox () ; private JCheckBox chkUser = new JCheckBox () ; private JButton btnExecute = new JButton () ; private frmActivateSuspend (LoginStatus lgSt, boolean activ) { status = lgSt ; activate = activ ; if (!status.GetStatus ()) return ; try { jbInit () ; } catch (Exception exception) { exception.printStackTrace () ; } } public static frmActivateSuspend Instance (LoginStatus lgSt, boolean activ) { if (unForm == null) { unForm = new frmActivateSuspend (lgSt, activ) ; unForm.setLocation (50, 50) ; } return unForm ; } private void jbInit () throws Exception { this.setSize (new Dimension (386, 200)) ; 41

SUPERTRANS CUSTOMER TRANSACTION SYSTEMthis.setTitle (activate ? "Activation" : "Deactivation") ; this.addComponentListener (new frmActivateSuspend_this_componentAdapter (this)) ; getContentPane ().setLayout (null) ; cmbCards.setBounds (new Rectangle (111, 33, 193, 22)) ; jLabel2.setToolTipText ("") ; jLabel2.setFont (new java.awt.Font ("Tahoma", Font.BOLD, 11)) ; jLabel2.setText ("User ID") ; jLabel2.setBounds (new Rectangle (44, 66, 52, 14)) ; jLabel1.setFont (new java.awt.Font ("Tahoma", Font.BOLD, 11)) ; jLabel1.setText ("Card") ; jLabel1.setBounds (new Rectangle (44, 37, 52, 14)) ; chkUser.setText ("") ; chkUser.setBounds (new Rectangle (313, 62, 28, 23)) ; chkUser.addMouseListener (new frmActivateSuspend_chkUser_mouseAdapter (this)) ; chkCard.addMouseListener (new frmActivateSuspend_chkCard_mouseAdapter (this)) ; btnExecute.setBounds (new Rectangle (121, 111, 147, 37)) ; btnExecute.setFont (new java.awt.Font ("Tahoma", Font.BOLD, 11)) ; btnExecute.setText (activate ? "Activation" : "Deactivation") ; btnExecute.addActionListener (new frmActivateSuspend_btnExecute_actionAdapter (this)) ; chkCard.setSelected (true) ; this.getContentPane ().add (cmbCards) ; chkCard.setBounds (new Rectangle (313, 33, 28, 23)) ; this.getContentPane ().add (jLabel1) ; this.getContentPane ().add (cmbUsers) ; this.getContentPane ().add (jLabel2) ; this.getContentPane ().add (chkCard) ; this.getContentPane ().add (chkUser) ; this.getContentPane ().add (btnExecute) ; cmbUsers.setBounds (new Rectangle (111, 62, 193, 22)) ; UserID usr1 = new UserID (status.GetUser (), 8, status) ; UserID usr2 = new UserID (status.GetUser (), 9, status) ; //Request and receive information from the server userIDs = (String[]) ClientUtilities.DispatchToken (new TradeToken (usr2, 3), status, "", 0).getData () ; cards = (String[]) ClientUtilities.DispatchToken (new TradeToken (usr1, 3), status, "", 0).getData () ; //Check received information and store results //Users if (userIDs.length == 0) cmbUsers.setEnabled (false) ; else { for (int i = 0 ; i < userIDs.length ; i++) cmbUsers.addItem (userIDs[i]) ; cmbUsers.setSelectedIndex (0) ; } //Cards if (cards.length == 0) cmbCards.setEnabled (false) ; else { for (int i = 0 ; i < cards.length ; i++) cmbCards.addItem (cards[i]) ; cmbCards.setSelectedIndex (0) ; } } 42

.

SOURCE CODE Stathis Polyzos

/** * Makes sure only one check box is selected */ public void chkCard_mouseClicked (MouseEvent e) { chkUser.setSelected (!chkCard.isSelected ()) ; } /** * Makes sure only one check box is selected */ public void chkUser_mouseClicked (MouseEvent e) { chkCard.setSelected (!chkUser.isSelected ()) ; } /** * Performs the Activate or Suspend operation according to the user's * choice. * * @param e ActionEvent */ public void btnExecute_actionPerformed (ActionEvent e) { //Confirm if (JOptionPane.showConfirmDialog (null, "Confirm transaction...", "Confirmation", JOptionPane.YES_NO_OPTION) == 1) return ; //Read data according to selected options boolean card = chkCard.isSelected () ; String unique = (card ? cmbCards.getSelectedItem ().toString () : cmbUsers.getSelectedItem ().toString ()) ; //Send request and receive reply TradeToken ret = ClientUtilities.DispatchToken (new TradeToken (new ChangeActivationStatus (status, unique, activate, card), 10), status, "", 0) ; //Process results if (ret.getType () == 1) { JOptionPane.showMessageDialog (card ? "Card" : "User") + " " + "suspended") + "...", "Success", this.setVisible (false) ; } else JOptionPane.showMessageDialog JOptionPane.ERROR_MESSAGE) ; } public void this_componentHidden (ComponentEvent e) { unForm = null ; } } class frmActivateSuspend_this_componentAdapter 43

(null, (activate ? "activated" : JOptionPane.INFORMATION_MESSAGE) ;

(null, "Operation failed...", "Error",

SUPERTRANS CUSTOMER TRANSACTION SYSTEMextends ComponentAdapter { private frmActivateSuspend adaptee ; frmActivateSuspend_this_componentAdapter (frmActivateSuspend adaptee) { this.adaptee = adaptee ; } public void componentHidden (ComponentEvent e) { adaptee.this_componentHidden (e) ; } } class frmActivateSuspend_btnExecute_actionAdapter implements ActionListener { private frmActivateSuspend adaptee ; frmActivateSuspend_btnExecute_actionAdapter (frmActivateSuspend adaptee) { this.adaptee = adaptee ; } public void actionPerformed (ActionEvent e) { adaptee.btnExecute_actionPerformed (e) ; } } class frmActivateSuspend_chkUser_mouseAdapter extends MouseAdapter { private frmActivateSuspend adaptee ; frmActivateSuspend_chkUser_mouseAdapter (frmActivateSuspend adaptee) { this.adaptee = adaptee ; } public void mouseClicked (MouseEvent e) { adaptee.chkUser_mouseClicked (e) ; } } class frmActivateSuspend_chkCard_mouseAdapter extends MouseAdapter { private frmActivateSuspend adaptee ; frmActivateSuspend_chkCard_mouseAdapter (frmActivateSuspend adaptee) { this.adaptee = adaptee ; } public void mouseClicked (MouseEvent e) { adaptee.chkCard_mouseClicked (e) ; } }

44

.

SOURCE CODE Stathis Polyzos F.1.5. frmChangePin.java

package ClientPack ; import java.awt.* ; import java.awt.event.* ; import javax.swing.* ; import import import import CommonObjects.* ; CommonObjects.Entities.CreditCard ; GlobalPack.ClientUtilities ; GlobalPack.TradeToken ;

public class frmChangePin extends JFrame { private static frmChangePin unForm = null ; private LoginStatus status ; private String[] cards ; private JComboBox cmbCards = new JComboBox () ; private JLabel jLabel1 = new JLabel () ; private JLabel jLabel2 = new JLabel () ; private JButton btnChange = new JButton () ; private JPasswordField txtOldpin = new JPasswordField () ; private JPasswordField txtNewpin = new JPasswordField () ; private JLabel jLabel3 = new JLabel () ; private JPasswordField txtNewpin2 = new JPasswordField () ; private JLabel jLabel4 = new JLabel () ; private frmChangePin (LoginStatus lgSt) { status = lgSt ; if (!status.GetStatus ()) return ; try { jbInit () ; } catch (Exception exception) { exception.printStackTrace () ; } } public static frmChangePin Instance (LoginStatus lgSt) { if (unForm == null) { unForm = new frmChangePin (lgSt) ; unForm.setLocation (70, 50) ; } return unForm ; } private void jbInit () throws Exception { this.setSize (new Dimension (386, 223)) ; 45

SUPERTRANS CUSTOMER TRANSACTION SYSTEMthis.setTitle ("Change PIN") ; this.addComponentListener (new frmChangePin_this_componentAdapter (this)) ; getContentPane ().setLayout (null) ; cmbCards.setBounds (new Rectangle (144, 26, 193, 22)) ; jLabel2.setToolTipText ("") ; jLabel2.setFont (new java.awt.Font ("Tahoma", Font.BOLD, 11)) ; jLabel2.setText ("Old PIN") ; jLabel2.setBounds (new Rectangle (41, 57, 52, 14)) ; jLabel1.setFont (new java.awt.Font ("Tahoma", Font.BOLD, 11)) ; jLabel1.setText ("Card") ; jLabel1.setBounds (new Rectangle (41, 30, 52, 14)) ; btnChange.setBounds (new Rectangle (129, 144, 147, 37)) ; btnChange.setFont (new java.awt.Font ("Tahoma", Font.BOLD, 11)) ; btnChange.setActionCommand ("Change") ; btnChange.setText ("Change PIN") ; btnChange.addActionListener (new frmChangePin_btnChange_actionAdapter (this)) ; txtOldpin.setText ("") ; txtOldpin.setBounds (new Rectangle (144, 53, 148, 22)) ; txtNewpin.setText ("") ; txtNewpin.setBounds (new Rectangle (144, 81, 148, 22)) ; jLabel3.setFont (new java.awt.Font ("Tahoma", Font.BOLD, 11)) ; jLabel3.setToolTipText ("") ; jLabel3.setText ("New PIN") ; jLabel3.setBounds (new Rectangle (41, 85, 52, 14)) ; txtNewpin2.setBounds (new Rectangle (144, 108, 148, 22)) ; jLabel4.setFont (new java.awt.Font ("Tahoma", Font.BOLD, 11)) ; jLabel4.setToolTipText ("") ; jLabel4.setText ("Reenter New PIN") ; jLabel4.setBounds (new Rectangle (41, 112, 100, 14)) ; this.getContentPane ().add (jLabel1) ; this.getContentPane ().add (jLabel2) ; this.getContentPane ().add (jLabel3) ; this.getContentPane ().add (jLabel4) ; this.getContentPane ().add (cmbCards) ; this.getContentPane ().add (txtOldpin) ; this.getContentPane ().add (txtNewpin) ; this.getContentPane ().add (txtNewpin2) ; this.getContentPane ().add (btnChange) ; this.getContentPane ().add (txtOldpin) ; //Get cards according to user level if (ClientUtilities.GetUserLevel (status) > 2) // Customer { TradeToken tk = ClientUtilities.DispatchToken (new TradeToken ( new UserID (status.GetUser (), 4, status), 3), status, "", 0) ; //Get customer credit card list CreditCard[] stCards = new CreditCard[tk.getType ()] ; stCards = (CreditCard[]) tk.getData () ; //Put the cards numbers in the array cards = new String[stCards.length] ; for (int i = 0 ; i < cards.length ; i++) cards[i] = stCards[i].GetCreditCardNumber () ; } else //Staff { //Get all credit card numbers cards = (String[]) ClientUtilities.DispatchToken (new TradeToken (new UserID (status.GetUser (), 8, status), 3), status, "", 0).getData () ; } //If no cards, disable button and combo box 46

.

SOURCE CODE Stathis Polyzos

if (cards.length == 0) { cmbCards.setEnabled (false) ; btnChange.setEnabled (false) ; } else { //Save the array in the combo box for (int i = 0 ; i < cards.length ; i++) cmbCards.addItem (cards[i]) ; cmbCards.setSelectedIndex (0) ; } } /** * Performs the Change Pin action. Old and new pins are read into strings, * and then sent to the server on Change Pin request. * A confirmation is returned and the user is informed appropriately * * @param e ActionEvent */ public void btnChange_actionPerformed (ActionEvent e) { //Confirm if (JOptionPane.showConfirmDialog (null, "Confirm transaction...", "Confirmation", JOptionPane.YES_NO_OPTION) == 1) return ; //Read data String newPin = "", newPin2 = "", oldPin = "" ; char[] newP = txtNewpin.getPassword (), newP2 = txtNewpin2.getPassword (), oldP = txtOldpin.getPassword () ; String unique = cmbCards.getSelectedItem ().toString () ; //Turn char arrays into strings for (int i = 0 ; i < newP.length ; i++) newPin += newP[i] ; for (int i = 0 ; i < newP.length ; i++) newPin2 += newP2[i] ; for (int i = 0 ; i < newP.length ; i++) oldPin += oldP[i] ; //Check that the new pins match if (!newPin.equals (newPin2)) { JOptionPane.showMessageDialog (null, "The new pins do not match...", "Error", JOptionPane.ERROR_MESSAGE) ; return ; } //Create pin change request RequestPinChange chPin = new RequestPinChange (status, unique, oldPin, newPin) ; //Send to the server and process reply if (ClientUtilities.DispatchToken (new TradeToken (chPin, 11), status, "", 0).getType () == 1) { JOptionPane.showMessageDialog (null, "PIN change complete...", "Success", JOptionPane.INFORMATION_MESSAGE) ; this.setVisible (false) ; 47

SUPERTRANS CUSTOMER TRANSACTION SYSTEM} else JOptionPane.showMessageDialog (null, "Operation failed...", "Error", JOptionPane.ERROR_MESSAGE) ; } public void this_componentHidden (ComponentEvent e) { unForm = null ; } } class frmChangePin_this_componentAdapter extends ComponentAdapter { private frmChangePin adaptee ; frmChangePin_this_componentAdapter (frmChangePin adaptee) { this.adaptee = adaptee ; } public void componentHidden (ComponentEvent e) { adaptee.this_componentHidden (e) ; } } class frmChangePin_btnChange_actionAdapter implements ActionListener { private frmChangePin adaptee ; frmChangePin_btnChange_actionAdapter (frmChangePin adaptee) { this.adaptee = adaptee ; } public void actionPerformed (ActionEvent e) { adaptee.btnChange_actionPerformed (e) ; } }

48

.

SOURCE CODE Stathis Polyzos F.1.6. frmCustomers.java

package ClientPack ; import java.awt.Rectangle ; import java.awt.event.* ; import javax.swing.* ; import import import import CommonObjects.* ; CommonObjects.Entities.Customer ; GlobalPack.ClientUtilities ; GlobalPack.TradeToken ;

public class frmCustomers extends JFrame { private LoginStatus status ; private static frmCustomers unForm ; private JTextField txtID = new JTextField () ; private JTextField txtCustomerName = new JTextField () ; private JTextField txtAddress = new JTextField () ; private JTextField txtCity = new JTextField () ; private JTextField txtZipCode = new JTextField () ; private JTextField txtPhoneNo = new JTextField () ; private JLabel jLabel1 = new JLabel () ; private JLabel jLabel3 = new JLabel () ; private JLabel jLabel5 = new JLabel () ; private JLabel jLabel6 = new JLabel () ; private JLabel jLabel7 = new JLabel () ; private JLabel jLabel8 = new JLabel () ; private JCheckBox chbPubUtilComp = new JCheckBox () ; private JLabel jLabel10 = new JLabel () ; private int[] customers ; private int curI ; private Customer curCust ; private private private private private private private JButton JButton JButton JButton JButton JButton JButton btnPrevious = new JButton () ; btnNext = new JButton () ; btnSave = new JButton () ; btnNew = new JButton () ; btnNewUser = new JButton () ; btnNewAccount = new JButton () ; btnNewCard = new JButton () ;

private frmCustomers (LoginStatus lgSt) { status = lgSt ; try { jbInit () ; } catch (Exception exception) { exception.printStackTrace () ; } } public static frmCustomers Instance (LoginStatus lgSt) 49

SUPERTRANS CUSTOMER TRANSACTION SYSTEM{ if (unForm == null) { unForm = new frmCustomers (lgSt) ; unForm.setLocation (80, 80) ; } return unForm ; } private void jbInit () throws Exception { this.setSize (450, 350) ; getContentPane ().setLayout (null) ; txtID.setEditable (false) ; txtID.setBounds (new Rectangle (110, 46, 64, 19)) ; txtCustomerName.setBounds (new Rectangle (110, 72, 301, 19)) ; this.addComponentListener (new frmCustomers_this_componentAdapter (this)) txtAddress.setBounds (new Rectangle (110, 95, 264, 19)) ; txtCity.setBounds (new Rectangle (110, 119, 91, 19)) ; txtZipCode.setBounds (new Rectangle (110, 143, 70, 19)) ; txtPhoneNo.setBounds (new Rectangle (110, 169, 139, 19)) ; jLabel1.setToolTipText ("LoginStatus lgSt") ; jLabel1.setText ("ID") ; jLabel1.setBounds (new Rectangle (29, 46, 70, 18)) ; jLabel3.setToolTipText ("LoginStatus lgSt") ; jLabel3.setText ("Full Name") ; jLabel3.setBounds (new Rectangle (29, 71, 70, 18)) ; jLabel5.setToolTipText ("LoginStatus lgSt") ; jLabel5.setText ("Address") ; jLabel5.setBounds (new Rectangle (29, 96, 70, 18)) ; jLabel6.setToolTipText ("LoginStatus lgSt") ; jLabel6.setText ("City") ; jLabel6.setBounds (new Rectangle (29, 120, 70, 18)) ; jLabel7.setToolTipText ("LoginStatus lgSt") ; jLabel7.setText ("ZipCode") ; jLabel7.setBounds (new Rectangle (29, 145, 70, 18)) ; jLabel8.setToolTipText ("LoginStatus lgSt") ; jLabel8.setText ("Phone No") ; jLabel8.setBounds (new Rectangle (29, 170, 70, 18)) ; chbPubUtilComp.setHorizontalTex