In a single source file named App.java, define a public class named App that can be run as either a multithreaded Windows server or as a Windows client to process Item information. Two other non-public classes must also be defined. One, named Item, will encapsulate the data and processing of an item available for sale. The other, named ServerThread, will define the processing of a server thread for a client.
The server (via its threads) will be responsible for handling client requests to store and retrieve Item objects maintained within a HashMap. The server must also store the HashMap to disk at the conclusion of processing and reload the HashMap from disk whenever the server is re-run.
The client will provide a graphical front-end for adding, finding, updating, and deleting Item objects.
The following diagram represents the application environment:
[ HashMap ]
Define a serializable Item class that is outside of the App class. It must encapsulate item number (int), item name (String), and item price (double). Code a single constructor to instantiate an object using values received for all three instance variables. Also code "set" and "get" methods, such as setNumber(), getNumber(), etc., to store and retrieve the value of each instance variable. Do NOT be concerned with editing the values of the instance variables.
Define the App class for a Windows program that will immediately ask the user to specify the processing mode (client or server). The technique for determining the processing mode is up to you. Based upon the mode, processing is as follows:
Using a FileDialog, ask the user for the name and location of the item file. If the specified file contains data, read it into a HashMap. Otherwise, instantiate a new HashMap to hold item data in memory.
Loop to accept client logins. When one occurs, launch a new ServerThread (with a socket and a reference to the HashMap) and start the thread's processing.
When the Window is closed, destroy all threads and write the HashMap to disk.
As part of thread construction, establish a high-level I/O stream (of your choice) for the socket.
As part of the run() method, service client requests to add, find, update, and delete an Item object using the HashMap. Develop your own scheme for transaction codes and what is sent on the stream. Be sure to:
Send a verification message if the transaction is successful.
Send an error message if the transaction fails - such as "duplicate item" for an Add transaction or "item not found" for a Find, Update, or Delete transaction.
Synchronize code to prevent two threads from working with the same Item object at the same time.
Provide a destroy() method to kill the thread.
Provide a GUI with text fields for entering and displaying item number, item name, and item price. Use buttons to trigger Add, Find, Update, and Delete operations, and a text field or text area for displaying messages. The Update and Delete buttons should only be enabled after a Find operation has succeeded. The choice of layout, colors, and fonts are up to you.
When Add is selected, verify that all data is present. If so, build a transaction, send it to the server, and read and display the server's reply. If data is missing, display an error message.
When Find is selected, verify that the item number is present. If so, build a transaction, send it to the server, read and display the server's reply, and enable the Update and Delete buttons if the transaction was successful. If the item number is missing, display an error message.
When Update is selected, verify that all data is present. If so, build a transaction and send it to the server, read and display the server's reply, and disable the Update and Delete buttons. If data is missing, display an error message.
When Delete is selected, verify that the item number is present. If so, build a transaction and send it to the server, read and display the server's reply, and disable the Update and Delete buttons. If the item number is missing, display an error message.
Notes and Hints
To display the item price in currency notation, you may use my Utility.moneyFormat() method. To parse a currency string such as "$1,234.56" back into a primitive double, you may code an expression as follows, where x is the string to be parsed:
The NumberFormat class is in the java.text package and the parse() method may throw a checked ParseException.
When testing, be sure to launch multiple threads and try a variety of actions. Be sure to verify that two threads cannot access the same item object at the same time. You may want to log messages to the console to trace what is happening.
Your program will be worth 30 points to be awarded as follows:
Accuracy (20 points). The program should correctly perform all specified processing.
Creativity (5 points). The program should be original yet simple in design.
Maintainability (5 points). The program should contain useful comments, meaningful identifiers, and be logically structured. It should contain an opening documentation block with your name and a brief description of what the program does. It should also have a block of comments preceding every major section of code.
Send your App.java source file as an e-mail document or attachment no later than midnight on the program due date. If you are using JBuilder 4 and the Test project previously copied from the College of Business network, this file will be in the src folder of the project. In the College of Business labs, the complete path of your source file is:
To verify that you are doing this properly, send a copy to yourself, copy the source code to your test project, and re-test the program. If it works for you, it will probably work for me.
Upon receipt of your e-mail, I will send either a verification message or your project score and comments (based on the above criteria). Project scores will be posted on the Internet within a few days after the due date.