165 lines
5.3 KiB
Java
165 lines
5.3 KiB
Java
package net.akpain;/*
|
|
* BooksDatabaseService.java
|
|
*
|
|
* The service threads for the books database server.
|
|
* This class implements the database access service, i.e. opens a JDBC connection
|
|
* to the database, makes and retrieves the query, and sends back the result.
|
|
*
|
|
* author: 2430671
|
|
*
|
|
*/
|
|
|
|
import java.io.*;
|
|
//import java.io.OutputStreamWriter;
|
|
|
|
import java.net.Socket;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.Properties;
|
|
import java.util.StringTokenizer;
|
|
|
|
import java.sql.*;
|
|
import javax.sql.rowset.*;
|
|
//Direct import of the classes CachedRowSet and CachedRowSetImpl will fail becuase
|
|
//these clasess are not exported by the module. Instead, one needs to impor
|
|
//javax.sql.rowset.* as above.
|
|
|
|
|
|
|
|
public class BooksDatabaseService extends Thread{
|
|
|
|
private Socket serviceSocket = null;
|
|
private String[] requestStr = new String[2]; //One slot for author's name and one for library's name.
|
|
private ResultSet outcome = null;
|
|
|
|
//JDBC connection
|
|
private String USERNAME = Credentials.USERNAME;
|
|
private String PASSWORD = Credentials.PASSWORD;
|
|
private String URL = Credentials.URL;
|
|
|
|
|
|
|
|
//Class constructor
|
|
public BooksDatabaseService(Socket aSocket){
|
|
serviceSocket = aSocket;
|
|
this.start();
|
|
}
|
|
|
|
|
|
//Retrieve the request from the socket
|
|
public String[] retrieveRequest()
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
try {
|
|
BufferedReader in = new BufferedReader(new InputStreamReader(serviceSocket.getInputStream()));
|
|
int c = 0;
|
|
while (c != '#') {
|
|
c = in.read();
|
|
if (c == 0) {
|
|
System.out.println("reading null bytes");
|
|
System.exit(1);
|
|
}
|
|
sb.append((char) c);
|
|
}
|
|
}catch(IOException e){
|
|
System.out.println("Service thread " + this.getId() + ": " + e);
|
|
}
|
|
|
|
String inp = sb.toString();
|
|
this.requestStr = inp.substring(0, inp.length() - 1).split(";");
|
|
|
|
// returns [0]: author, [1]: city
|
|
return this.requestStr;
|
|
}
|
|
|
|
|
|
//Parse the request command and execute the query
|
|
public boolean attendRequest()
|
|
{
|
|
boolean flagRequestAttended = true;
|
|
|
|
this.outcome = null;
|
|
|
|
String sql = "select book.title, book.publisher, book.genre, book.rrp, count(*) as \"number_available\" from bookcopy join book on bookcopy.bookid = book.bookid where\n" +
|
|
"\tlibraryid = (select libraryid from \"library\" where city = ?) and\n" +
|
|
"\tbookcopy.bookid in (select bookid from book where authorid = (select authorid from author where familyname = ?))" +
|
|
// "\t and (onloan = false or onloan is null)\n" +
|
|
"group by book.title, book.publisher, book.genre, book.rrp;";
|
|
// city then author name
|
|
|
|
try {
|
|
//Connet to the database
|
|
Properties connectionProps = new Properties();
|
|
connectionProps.put("user", USERNAME);
|
|
connectionProps.put("password", PASSWORD);
|
|
Connection conn = DriverManager.getConnection(URL, connectionProps);
|
|
|
|
//Make the query
|
|
PreparedStatement q = conn.prepareStatement(sql);
|
|
q.setString(1, this.requestStr[1]); // city
|
|
q.setString(2, this.requestStr[0]); // author surname
|
|
|
|
//Process query
|
|
ResultSet res = q.executeQuery();
|
|
RowSetFactory aFactory = RowSetProvider.newFactory() ;
|
|
CachedRowSet crs = aFactory.createCachedRowSet();
|
|
crs.populate(res);
|
|
outcome = crs;
|
|
|
|
//Clean up
|
|
res.close();
|
|
q.close();
|
|
conn.close();
|
|
|
|
} catch (Exception e)
|
|
{ System.out.println(e); }
|
|
|
|
return flagRequestAttended;
|
|
}
|
|
|
|
|
|
|
|
//Wrap and return service outcome
|
|
public void returnServiceOutcome(){
|
|
try {
|
|
//Return outcome
|
|
ObjectOutputStream output = new ObjectOutputStream(serviceSocket.getOutputStream());
|
|
output.writeObject(outcome);
|
|
|
|
System.out.println("Service thread " + this.getId() + ": Service outcome returned; " + this.outcome);
|
|
|
|
//Terminating connection of the service socket
|
|
output.close();
|
|
serviceSocket.close();
|
|
}catch (IOException e){
|
|
System.out.println("Service thread " + this.getId() + ": " + e);
|
|
}
|
|
}
|
|
|
|
|
|
//The service thread run() method
|
|
public void run()
|
|
{
|
|
try {
|
|
System.out.println("\n============================================\n");
|
|
//Retrieve the service request from the socket
|
|
this.retrieveRequest();
|
|
System.out.println("Service thread " + this.getId() + ": Request retrieved: "
|
|
+ "author->" + this.requestStr[0] + "; library->" + this.requestStr[1]);
|
|
|
|
//Attend the request
|
|
boolean tmp = this.attendRequest();
|
|
|
|
//Send back the outcome of the request
|
|
if (!tmp)
|
|
System.out.println("Service thread " + this.getId() + ": Unable to provide service.");
|
|
this.returnServiceOutcome();
|
|
|
|
}catch (Exception e){
|
|
System.out.println("Service thread " + this.getId() + ": " + e);
|
|
}
|
|
//Terminate service thread (by exiting run() method)
|
|
System.out.println("Service thread " + this.getId() + ": Finished service.");
|
|
}
|
|
|
|
}
|