package COM.xinit.demon.co.uk.3tier.database;
import java.io.*;
import java.net.*;
import java.util.*;
import msql.*;
import database.*;
public class dbProxy implements Runnable {
int listenPort = 5500;
int alternatePort = listenPort;
RulesThread checkIt;
ServerSocket myServer = null;
Socket answerSocket;
Database myDB;
public void init(String databaseServer) {
// listen() gets called from main() & tries to create the Server Socket,
// using an alternate port if it fails
try {
myDB = new Database (databaseServer);
} catch (MsqlException e) {
System.out.println ("Error connecting to Database at " +
databaseServer);
}
try {
myServer = new ServerSocket(listenPort,5);
} catch (IOException e) {
System.out.println(e.toString());
listenPort = alternatePort++;
System.out.println("Unable to create Server Socket," +
"trying alternate port " + alternatePort);
} // close catch
System.out.println("Notify all clients that the current Server Port"
+ " is " + listenPort );
} //end listen
public void run() {
// loop forever, waiting to accept connections
for(;;) {
try {
answerSocket = myServer.accept();
} catch (IOException e) {
return;
}
// put the socket connection on its own thread, so my ServerSocket
// can go back to listen for new connection requests
System.out.println("Accepted connection from client");
checkIt = new RulesThread(answerSocket, this);
// Have to be polite, so my other threads can run()
Thread.yield();
}
}
public static void main(String args[]) {
// Test to see if any argument was passed - need the hostname of the
// database server
if (args.length < 1) {
System.out.println ("Usage: java dbProxy <DatabaseHostname>");
System.exit (1);
}
// create an instance of this class
dbProxy myHandler = new dbProxy();
// start up the Server Socket
String databaseServer = args[0];
myHandler.init(databaseServer);
// construct a new thread & tell it to find run() in myHandler's class
Thread myThread = new Thread (myHandler);
// answer those client requests
myThread.start();
}
}
class RulesThread extends Thread {
Database myDB;
Socket talkToMe;
DataOutputStream sendStream;
DataInputStream recvStream;
boolean success = true;
dbProxy myHandler;
private static final int BUYSHARES = 10;
private static final int SELLSHARES = 20;
private static final int READSTOCKLIST = 30;
private static final int READASTOCK = 40;
private static final int READCUSTLIST = 50;
private static final int VIEWACUSTOMER = 60;
private static final int ADDACUSTOMER = 70;
private static final int UPDATECUSTOMER = 80;
private static final int DELETECUSTOMER = 90;
public RulesThread (Socket s, dbProxy parent){
talkToMe = s;
myHandler = parent;
myDB = parent.myDB;
try {
sendStream = new DataOutputStream(talkToMe.getOutputStream());
recvStream = new DataInputStream(talkToMe.getInputStream());
} catch (IOException e) {
System.out.println("Error in RulesThread creating Input or Output Stream");
success = false;
}
if (success) {
this.start();
} else {
return;
}
}
// The specific methods for marshalling each request
// readStockList - reads the current list of stock and prices
// and returns them
public void readStockList () throws IOException {
StockRec s[] = myDB.getAllStocks();
if (s.length <= 0) {
sendStream.writeInt(-1);
System.out.println("Error in READSTOCKLIST");
return;
} else {
sendStream.writeInt(s.length);
for (int i=0;i < s.length;i++) {
sendStream.writeUTF(s[i].getSymbol());
sendStream.writeFloat(s[i].getPrice());
}
}
}
// readCustList - reads the current list of customers -
// name and ssn
public void readCustList () throws IOException {
// Get the customer list (if one exists)
CustomerRec cr[] = myDB.getAllCustomers();
if (cr.length <= 0) {
sendStream.writeInt(-1);
System.out.println("Error in READCUSTLIST");
return;
} else {
sendStream.writeInt(cr.length);
for (int i=0;i < cr.length;i++) {
sendStream.writeUTF(cr[i].ssn);
sendStream.writeUTF(cr[i].name);
sendStream.writeUTF(cr[i].addr);
}
}
}
public void readAStock (String id) throws IOException {
// make the database call to return the current price
float price = myDB.getStockPrice(id);
if (price == -1.0f) {
sendStream.writeInt(-1);
System.out.println("Error in READASTOCK");
return;
} else {
sendStream.writeInt(0);
sendStream.writeFloat(price);
}
}
public void viewACustomer (String id) throws IOException {
//make the database call to verify that the customer exists
if (verifyCustomerExists(id) == -1) {
sendStream.writeInt(-1);
System.out.println("Customer doesn't exist");
return;
} else {
try {
CustomerRec aCustomer = myDB.getCustomer(id);
//send the customer info back
sendStream.writeInt(0);
sendStream.writeUTF(aCustomer.ssn);
sendStream.writeUTF(aCustomer.name);
sendStream.writeUTF(aCustomer.addr);
// Check to see if there are any SharesRec objects in
// the portfolio, return zero if there aren't any ...
// First check to see if the portfolio is not null - T.McG
int size = 0;
if (aCustomer.portfolio != null) {
size = ((Vector)(aCustomer.portfolio)).size();
}
if (size == 0) {
sendStream.writeInt(0);
} else {
// otherwise, return the number of SharesRec objects
sendStream.writeInt(size);
// and the symbol/price pairs
for (int j=0; j < size; j++) {
sendStream.writeUTF(((SharesRec)(aCustomer.portfolio.elementAt(j))).symbol);
sendStream.writeInt(((SharesRec)(aCustomer.portfolio.elementAt(j))).quantity);
}
}
} catch (RecordNotFoundException e) {
sendStream.writeInt(-1);
System.out.println("Error in VIEWACUSTOMER");
return;
}
}
}
public void deleteCustomer (String id) throws IOException {
//make the database call to verify that the customer exists
if (verifyCustomerExists(id) == -1) {
sendStream.writeInt(-1);
System.out.println("Customer doesn't exist");
return;
} else {
//make the database call to delete the customer
try {
myDB.deleteCustomer(id);
sendStream.writeInt(0);
} catch (RecordNotFoundException e) {
sendStream.writeInt(-1);
System.out.println("Error in DELETECUSTOMER");
return;
}
}
}
public void updateCustomer (String ssn, String name, String addr)
throws IOException {
// if customer doesn't exist, return error code
if (verifyCustomerExists(ssn) == -1) {
sendStream.writeInt(-1);
System.out.println("Error in UPDATECUSTOMER");
return;
} else {
try {
// Database's updateCustomer is a little odd -
// the arguments are name, ssn, addr - T.McG
myDB.updateCustomer (name, ssn, addr);
sendStream.writeInt(0);
} catch (RecordNotFoundException e) {
sendStream.writeInt(-1);
System.out.println("Error in UPDATECUSTOMER");
return;
}
}
}
public void addACustomer (String ssn, String name, String addr)
throws IOException {
// if customer already exists, return error code
if (verifyCustomerExists(ssn) == 0) {
sendStream.writeInt(-1);
System.out.println("Error in ADDACUSTOMER");
return;
} else {
try {
// Database's addCustomer is a little odd -
// the arguments are name, ssn, addr - T.McG
// myDB.addCustomer(ssn,name,addr);
myDB.addCustomer(name, ssn, addr);
sendStream.writeInt(0);
} catch (Exception e) {
sendStream.writeInt(-1);
System.out.println("Error in ADDACUSTOMER");
return;
}
}
}
public void buyShares (String ssn, String stock, int qty)
throws IOException {
//make the database call to verify that the customer exists
if (verifyCustomerExists(ssn) == -1) {
sendStream.writeInt(-1);
System.out.println("Customer doesn't exist");
return;
}
// verify that qty > 0, and make the database call to buy
if (qty <= 0) {
sendStream.writeInt(-3);
System.out.println("Error in BUYSHARES: invalid number");
return;
} else {
try {
myDB.buyShares(ssn,stock,qty);
sendStream.writeInt (0);
} catch (RecordNotFoundException e) {
sendStream.writeInt(-1);
System.out.println("Error in BUYSHARES");
return;
}
}
}
public
void
sellShares (String ssn, String stock, int qty)
throws IOException {
//make the database call to verify that the customer exists
if (verifyCustomerExists(ssn) == -1) {
sendStream.writeInt(-1);
System.out.println("Customer doesn't exist");
return;
}
// make the database call to verify that I have that many
// shares to sell, and if I do, make the call to sell them
try{
Vector myVector = myDB.getPortfolio(ssn);
SharesRec sr[] = new SharesRec[myVector.size()];
int i = 0;
// Search the portfolio for this stock
for (; i < myVector.size(); i++) {
sr[i] = (SharesRec)myVector.elementAt(i);
if (sr[i].symbol.equals(stock)) {
break;
}
}
int curQty = sr[i].quantity;
if (qty > curQty) {
sendStream.writeInt(-3);
System.out.println("Error in SELLSHARES: invalid number");
return;
} else {
if (qty == curQty) {
myDB.sellShares(ssn,stock);
sendStream.writeInt (0);
} else {
myDB.sellShares(ssn, stock, qty);
sendStream.writeInt (0);
}
}
} catch (Exception e) {
sendStream.writeInt(-1);
System.out.println("Error in SELLSHARES");
return;
}
}
// General purpose method to validate customer ssn
public int verifyCustomerExists(String ssn) {
if (myDB.ssnExists(ssn)) {
return (0);
} else {
return (-1);
}
}
public void run() {
// get the client command, pass it through the business rules,
// make the appropriate database call(s) & send the result back
for (;;) {
// wait for the client command
try {
int command = recvStream.readInt();
// based on the command we receive, we know how many and
// what types of reads need to be made from the inputstream
switch (command) {
case READSTOCKLIST:
readStockList ();
break;
case READCUSTLIST:
readCustList ();
break;
case VIEWACUSTOMER:
viewACustomer (recvStream.readUTF());
break;
case READASTOCK:
readAStock (recvStream.readUTF());
break;
case DELETECUSTOMER:
deleteCustomer (recvStream.readUTF());
break;
case UPDATECUSTOMER:
updateCustomer (recvStream.readUTF(),
recvStream.readUTF(), recvStream.readUTF());
break;
case ADDACUSTOMER:
addACustomer (recvStream.readUTF(),
recvStream.readUTF(), recvStream.readUTF());
break;
case BUYSHARES:
buyShares (recvStream.readUTF(),
recvStream.readUTF(), recvStream.readInt());
break;
case SELLSHARES:
sellShares (recvStream.readUTF(),
recvStream.readUTF(), recvStream.readInt());
break;
default:
try {
// Tell client that we received an invalid command
sendStream.writeInt(-4);
} catch (IOException e) {
System.out.println("Failed to write error condition to client");
stop();
}
}
// Yeild to the other threads and drop back
// into my blocking readInt
this.yield();
} catch (Exception e) {
System.out.println ("Error reading command value from client");
System.out.println (e.toString());
System.out.println("Closing connection to client");
try {
recvStream.close();
sendStream.close();
} catch (IOException e9) {}
return;
}
}
}
}

Last Updated