/* Program Code ------ | S. Cartwright Program Description | The Server acts as a network hub, and bridge | between the clients and the database. Version ----------- | 1 Creation Date ----- | 5/01 */ //State the name of the Package these classes are a part //***************************************************************************** package Server; //***************************************************************************** //Import the required utility packages import java.awt.*; import javax.swing.*; import com.borland.jbcl.layout.*; import java.awt.event.*; //***************************************************************************** //Declare the main Server class public class Server extends JFrame implements ActionListener{ //***************************************************************************** // Decalre the global data //clientName contains the name of the clients to connect, the number of elements //directly effects the number of clients expected by the class ServerNetworkCore static final private String[] clientName={"Till 1","Kitchen"};//,"Till 2","Kitchen","Cellar"}; //MessageHandler connects too and allows queries on the database, using the //MessagePacket protocol for IO private MessageHandler messageHandler; //ServerNetworkCore handles client connection, and client IO using either //String's or MessagePackets for the IO protocol private ServerNetworkCore net; //Various objects that produce the Server status output private TextArea display; JButton jButton1 = new JButton(); XYLayout xYLayout1 = new XYLayout(); //timer is used to update the time waiting of current orders Timer timer=new Timer(10000,this); //_SYSTEM_RESET is a system sentinal flag used to denote a server reset //requested by the user private boolean _SYSTEM_RESET=false; //***************************************************************************** //The main method, just constructs an annonymous instance of the Server class public static void main(String ignore[]) throws Exception {new Server();} //***************************************************************************** //The Server constructor, creates the window, and (re)starts the server public Server() throws Exception { super("Grub Pubs Server V 1.00"); makeWindow(); doRestart(); } //***************************************************************************** //The actionPerformed method for the timer object, updates the order waiting //times in the tblCurrentOrders table public void actionPerformed(ActionEvent e) { try { updateOrderWaiting(); } catch(Exception f) { f.printStackTrace(); } } //***************************************************************************** //For every record in the tblCurrentOrders table, we add 10 seconds to the //time waiting public void updateOrderWaiting() throws Exception { //Increment the current orders waiting times, by simulating a message from a //client asking for the current orders list, then update each record with //it's new value. //1) Create a new MessagePacket containing "getCurrentOrderList", with an annonymous //ID and no .data value in the constructor, which is perfectly valid for internal //comands //2) Use MessageHandler's processMessage method on the above MessagePacket //to produce some result data also in the MessagePacket format. //3) From this MessagePacket stip a plain String object containing the raw result //data into the RawDataHandler for processing. RawDataHandler internalPacket=new RawDataHandler(messageHandler.processMessage(new MessagePacket("getCurrentOrderList")).message); //internalPacket on construction sets "records" to the total number of records //contained in the raw data, we use this now while we step through the list for(int index=1;index<=internalPacket.records;index++) { //internalPacket now contains all the results of the search, in tabular form, //that can be found by using its member method "getDataItem" with oprands //(int) index, and (String) column name. //So for each record, we get this value (a String) convert it to an (int) and add 10 int totalSeconds=Integer.parseInt(internalPacket.getDataItem(index,"Time Waiting"))+10; //To update the record, we now need to create an SQL statement to pass to //the MessageHandler //So first, we get the current records "Order ID" value String thisID=internalPacket.getDataItem(index,"Order ID"); //Now we have enough information to construct a valid SQL statement to update //this record String SQL="UPDATE tblCurrentOrder SET [Time Waiting]='"+totalSeconds+"' WHERE [Order ID]="+thisID; //Pass the MessasgeHandler a new MessagePacket with the request //"DirectSQL-Update" and the data variable "SQL" to handle messageHandler.processMessage(new MessagePacket("DirectSQL-Update:"+SQL)); } } //***************************************************************************** //Restart the server public void doRestart() throws Exception { //Stop any more current order time updates timer.stop(); //Write messages display.append("Welcome to the Grub Pubs Server Utility Version 1.00\n"); display.append("(C)2001 A1 Systems Limited.\n"); for(int c=0;c<50;c++) display.append("_"); display.append("\n\n"); display.append("Initialising Server Core...\n\n"); display.append("Number of clients to connect to this server: "+clientName.length+"\n\n"); //Create a new MessageHandler and new ServerNetworkCore messageHandler= new MessageHandler(display); net=new ServerNetworkCore(clientName,display); //Write messages display.append("Server Core Initialisation Successful...\n"); for(int c=0;c<50;c++) display.append("_"); display.append("\n\n"); display.append("The database is live, listening for client requests...\n\n"); //Start the "current orders timer" update timer timer.start(); System.out.println("Started Timer"); //Begin main loop listenForClients(); } //***************************************************************************** //Construct the visible window public void makeWindow() { //Add components to the window display=new TextArea("",80,45,TextArea.SCROLLBARS_VERTICAL_ONLY); jButton1.setText("Reset Server"); this.setSize(new Dimension(430,500)); this.getContentPane().setLayout(xYLayout1); //Create a new inner ActionListener object within the jButton1 object jButton1.addActionListener ( new java.awt.event.ActionListener() //Add Action Listener Object { public void actionPerformed(ActionEvent e) //Add an annonymous method { //When the reset the button is pressed the following code is always executed if(net==null||(!net.allConnected())) { display.append("\n\nThe server cannot be reset at this time!\n\n"); return; } display.append( !_SYSTEM_RESET?"\n\nReseting...\n\n":"Reset has already been pressed!\n"); _SYSTEM_RESET=true; net._RESET=true; } } ); this.getContentPane().add(jButton1, new XYConstraints(20,437,130,30)); this.getContentPane().add(display, new XYConstraints(10,10,400,420)); display.setBackground(new Color(30,30,30)); display.setForeground(new Color(200,200,255)); show(); } //***************************************************************************** //The main message handling loop, listens for client messages in a round-robin //fashion, as clients messages are passively collected public void listenForClients() throws Exception { String message=""; int messageCount=0; //Right upto this moment, _SYSTEM_RESET is left alone, to ensure multiple resets //arnt received _SYSTEM_RESET=false; while(!_SYSTEM_RESET) { display.append(++messageCount+":"); //Wait for the next message (Execution follows nested parenthesis priority) net.sendMessage //Sends the MessagePacket to the client ( messageHandler.processMessage //Process' a MessagePacket ( net.getNextClientMessage() //Returns with a newly received ) //client MesssagePacket ); display.append("DONE\n"); System.out.println("Free Mem:"+Runtime.getRuntime().freeMemory()); } //Ensure all client connections are closed net.closeServer(); doRestart(); } //***************************************************************************** //Handle the "Window Closing" system event protected void processWindowEvent(WindowEvent e) { //Check ID of the window event is "WINDOW_CLOSING" if(e.getID()==WindowEvent.WINDOW_CLOSING) { //Ensure the ServerNetworkCore is instantiated, before we try closing client //connections! if(net!=null) net.closeServer(); //Do superclass handling super.processWindowEvent(e); System.exit(0); } } }