/*
* ServerThread.java
*
* Created on 13 November 2006, 16:07
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
import java.io.*;
import java.net.*;
import java.util.*;
/**
* The threads spun from the NewShop server to process client requests
* @author dsi06dh Dave Hollowell
* @version 0.1 23rd November 2006
*/
public class ServerThread implements Runnable
{
/**
* reference to the server GUI display
*/
private ServerGui theDisplay;
/**
* Reference to the warehaouse instance to use
*/
private Warehouse theWarehouse;
/**
* reference to the client socket
*/
private Socket theSocket;
/**
* Reference to the client number
*/
private int theClient;
/**
* The incoming object data stream
*/
private ObjectInputStream in = null;
/**
* The outgoing object data stream
*/
private ObjectOutputStream out = null;
/**
* Continue to process the requests
*/
private boolean process = true;
/**
* the customer details
*/
private Customer cust;
/**
* The branch details
*/
private Branch theBranch;
/**
* End of line character
*/
private static final String NEWLINE = System.getProperty("line.separator");
/**
* Creates a new instance of ServerThread
* @param clientNo Numeric reference to the client
* @param clientSocket Socket number for the client
* @param aWarehouse Reference to the required warehouse instance
* @param display Reference to the required server GUI display
*/
public ServerThread(int clientNo, Socket clientSocket,
Warehouse aWarehouse, ServerGui display)
{
theClient = clientNo;
theSocket = clientSocket;
theWarehouse = aWarehouse;
theDisplay = display;
}
/**
* Runnable implementation of the server thread
*/
public void run()
{
theDisplay.statusMessage("Client " + theClient +
" Thread started" + NEWLINE);
try
{
in = new ObjectInputStream((theSocket.getInputStream()));
}
catch (IOException e)
{
theDisplay.statusMessage("Client " + theClient +
" inbound connection failed" + NEWLINE);
System.exit(-1);
}
try
{
out = new ObjectOutputStream((theSocket.getOutputStream()));
}
catch (IOException e)
{
theDisplay.statusMessage("Client " + theClient +
" outbound connection failed" + NEWLINE);
System.exit(-1);
}
while(process)
{
// get incoming details
TransmissionData mess = null;
try
{
mess = (TransmissionData) in.readObject();
}
catch (IOException e)
{
theDisplay.statusMessage("Client " + theClient +
" read failed" + NEWLINE);
System.exit(-1);
}
catch (ClassNotFoundException e)
{
theDisplay.statusMessage(e.getMessage());
}
// procees the incoming message
mess = processRequest(mess);
if (process)
{
try
{
out.writeObject((TransmissionData) mess);
}
catch (IOException e)
{
theDisplay.statusMessage("Client " + theClient +
" send failed" + NEWLINE);
System.exit(-1);
}
}
}
theDisplay.statusMessage("Client " + theClient +
" Thread completed" + NEWLINE);
}
/**
* Process requests from the transmission details
* @param details Incoming transmission details
* @return Outqoing transmission details
*/
private TransmissionData processRequest(TransmissionData details)
{
TransmissionData input = details;
TransmissionData output = null;
// login requested
if (input.getDataType() == TransmissionData.CLT_LOGIN)
{
output = processLogin(input);
}
// branch selected
if (input.getDataType() == TransmissionData.CLT_BRANCH)
{
output = processBranch(input);
}
// client order completion requested
if (input.getDataType() == TransmissionData.CLT_COMPLETE)
{
output = processOrder(input);
}
// client closedown requested
if (input.getDataType() == TransmissionData.CLT_CLOSE)
{
processClose();
output = null;
}
return output;
}
/**
* Process a login request
* @param details incoming transmission details
* @return Outgoing transmission details
*/
private TransmissionData processLogin(TransmissionData details)
{
TransmissionData input = details;
TransmissionData output = null;
// determine customer sent
String custCode;
custCode = (String) input.getData();
theDisplay.statusMessage("Client " + theClient + " Login request "
+ custCode + NEWLINE);
cust = theWarehouse.getCustomer(custCode);
// customer exists?
if (cust == null)
{
theDisplay.statusMessage("Client " + theClient +
" Customer refused" + NEWLINE);
output = new TransmissionData(TransmissionData.SRV_ERROR,
"Customer does not exist.");
}
else
{
String data1, data2;
// send branch details
String branchData = theWarehouse.getBranchCodes_Names();
StringTokenizer st = new StringTokenizer(branchData, "*");
Vector<Branch> branchList = new Vector<Branch>();
while (st.hasMoreTokens())
{
data1 = st.nextToken();
if (!(data1.equals("END")))
{
data2 = st.nextToken();
Branch tempBranch = new Branch(data1, data2);
branchList.addElement(tempBranch);
}
}
theDisplay.statusMessage("Client " + theClient +
" Customer accepted" + NEWLINE);
output = new TransmissionData(TransmissionData.SRV_BRANCHLIST,
branchList);
}
return output;
}
/**
* Process a branch request
* @param details incoming transmission details
* @return Outgoing transmission details
*/
private TransmissionData processBranch(TransmissionData details)
{
TransmissionData input = details;
TransmissionData output = null;
String branchRequest = (String) input.getData();
theDisplay.statusMessage("Client " + theClient +
" Branch request " + branchRequest + NEWLINE);
//theBranch = theWarehouse.getBranch(branchRequest);
String stockData = theWarehouse.getBranchStockList(branchRequest);
String data1, data2, data3;
int data4;
// send branch item details
StringTokenizer st = new StringTokenizer(stockData, "*");
Vector<StockItem> stockList = new Vector<StockItem>();
while (st.hasMoreTokens())
{
data1 = st.nextToken();
if (!(data1.equals("END")))
{
data2 = st.nextToken();
data3 = st.nextToken();
data4 = Integer.parseInt(st.nextToken());
StockItem tempItem = new StockItem(data1, data2, data3,
data4);
stockList.addElement(tempItem);
}
}
theDisplay.statusMessage("Client " + theClient +
" Branch accepted" + NEWLINE);
output = new TransmissionData(TransmissionData.SRV_STOCKLIST,
stockList);
return output;
}
/**
* Process a client complete order request
* @param details incoming transmission details
* @return outgoing transmission details
*/
private TransmissionData processOrder(TransmissionData details)
{
theDisplay.statusMessage("Client " + theClient +
" complete Order requested" + NEWLINE);
TransmissionData input = details;
TransmissionData output = null;
String basketDetails;
basketDetails = cust.getCustomerCode() + "*";
// warning issued in compilation due to unchecked cast from
// input.getData() returning an object - see Generics
Vector<BasketItem> items = (Vector<BasketItem>) input.getData();
Iterator it = items.iterator();
while (it.hasNext())
{
BasketItem line = (BasketItem) it.next();
basketDetails = basketDetails + line.getItemCode() + "*";
basketDetails = basketDetails + line.getDescription() + "*";
basketDetails = basketDetails + line.getPrice() + "*";
basketDetails = basketDetails + line.getNumberOrdered() + "*";
}
basketDetails = basketDetails + "END*";
String orderNo = theWarehouse.processBasket(basketDetails);
output = new TransmissionData(TransmissionData.SRV_ORDER, orderNo);
theDisplay.statusMessage("Client " + theClient +
" Order " + orderNo + " completed" + NEWLINE);
return output;
}
/**
* Process a client closedown request
*/
private void processClose()
{
theDisplay.statusMessage("Client " + theClient +
" shutdown requested." + NEWLINE);
try
{
theSocket.close();
}
catch (IOException e)
{
theDisplay.statusMessage("Client " + theClient +
" shutdown exception " +e.getMessage() + NEWLINE);
}
try
{
in.close();
}
catch (IOException e)
{
theDisplay.statusMessage("Client " + theClient +
" read close exception " +e.getMessage() + NEWLINE);
}
try
{
out.close();
}
catch (IOException e)
{
theDisplay.statusMessage("Client " + theClient +
" write close exception " +e.getMessage() + NEWLINE);
}
process = false;
}
}