package com.example.scheduler_server; import java.io.*; import java.net.*; import java.util.Locale; /* Name: UserThread Description: This class handles messages sent from the clients, and the required parsing to be used for in the Shift and Schedule classes. */ public class UserThread extends Thread { private final Socket socket; private final ScheduleServer server; private PrintWriter writer; private final DataBaseQuery dbQuery; /* Name: UserThread Parameters: Socket socket: socket for communicating to the client. ScheduleServer server: The class responsible for establishing the first connection to a new client and creating a UserThread for it. DataBaseQuery dbQuery: Class responsible for connecting to the database, and containing all the methods on it. Description: Constructor class that gets the input stream to be read when client messages are sent. Return: UserThread */ public UserThread(Socket socket, ScheduleServer server, DataBaseQuery dbQuery) { this.socket = socket; this.server = server; this.dbQuery = dbQuery; } /* Name: Run Description: Responsible for handling and parsing messages from a client. This is also where the new user-thread begins. */ public void run() { try { InputStream input = socket.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(input)); OutputStream output = socket.getOutputStream(); writer = new PrintWriter(output, true); String serverMessage; String clientMessage; serverMessage = dbQuery.staff.allEmployees(); sendMessage(serverMessage); serverMessage = dbQuery.schedule.allShifts(); sendMessage(serverMessage); serverMessage = dbQuery.availability.allAvailabilities(); sendMessage(serverMessage); serverMessage = dbQuery.timeOff.allTimeOff(); sendMessage(serverMessage); serverMessage = dbQuery.positions.allPositions(); sendMessage(serverMessage); do { clientMessage = reader.readLine(); String[] args = clientMessage.split("/"); System.out.println(clientMessage); switch (args[0]) { case "addEmployee": if(args.length == 7){ try { String newEmployee = dbQuery.staff.addEmployee(args[1], args[2], args[3], args[4], args[5], Float.parseFloat(args[6])); if (!newEmployee.isEmpty()){ String newEmployeeAvailability = dbQuery.availability .newEmployeeAvailability(Integer.parseInt(newEmployee.split(",")[0])); server.broadcast("addEmployee/" + newEmployee); server.broadcast("newEmployeeAvailability/" + newEmployeeAvailability); } } catch (Exception exception) { System.out.println("Error: Formatting exception while adding employee"); exception.printStackTrace(); } } break; case "editEmployee": if(args.length == 8){ try { String editedEmployee = dbQuery.staff.editEmployee(Integer.parseInt(args[1]), args[2], args[3], args[4], args[5], args[6], Float.parseFloat(args[7])); if (!editedEmployee.isEmpty()){ server.broadcast("editEmployee/" + editedEmployee); } } catch (Exception exception) { System.out.println("Error: Formatting exception while adding employee"); exception.printStackTrace(); } } case "removeEmployee": try { int employeeID = Integer.parseInt(args[1]); dbQuery.schedule.removeAllShiftsByID(employeeID); dbQuery.timeOff.removeAllTimeOffByID(employeeID); dbQuery.availability.removeEmployeeAvailability(employeeID); if (employeeID == dbQuery.staff.removeEmployee(employeeID)) { server.broadcast("removeEmployee/" + employeeID); server.broadcast("removeEmployeeAvailability/" + employeeID); server.broadcast("removeAllShiftsByID/" + employeeID); server.broadcast("removeAllTimeOffByID/" + employeeID); } } catch (NumberFormatException exception) { System.out.println("Error: Formatting exception while removing employee"); exception.printStackTrace(); } break; case "editShift": try { String editedShift = dbQuery.schedule.editShift(Integer.parseInt(args[1]), args[2], args[3], args[4], args[5], Integer.parseInt(args[6])); if (!editedShift.isEmpty()) { server.broadcast("editShift/" + editedShift); } } catch (NumberFormatException exception) { System.out.println("Error: Formatting exception while editing shift"); exception.printStackTrace(); } break; case "addShift": try { String newShift = dbQuery.schedule.addShift(Integer.parseInt(args[1]), args[2], Integer.parseInt(args[3]), Integer.parseInt(args[4]), args[5]); if (!newShift.isEmpty()){ server.broadcast("addShift/" + newShift); } } catch (NumberFormatException exception) { System.out.println("Error: Formatting exception while adding shift"); exception.printStackTrace(); } break; case "editShiftAvailability": try { String editedShiftAvailability = dbQuery.schedule.editShiftAvailability(Integer.parseInt(args[1]), args[2]); if (!editedShiftAvailability.isEmpty()) { server.broadcast("editShiftAvailability/" + args[1] + "/" + args[2]); } } catch (NumberFormatException exception) { System.out.println("Error: Formatting exception while setting time off approval"); exception.printStackTrace(); } break; case "removeShift": try { int shiftID = Integer.parseInt(args[1]); if (shiftID == dbQuery.schedule.removeShiftByID(shiftID)) { server.broadcast("removeShift/" + shiftID); } } catch (NumberFormatException exception) { System.out.println("Error: Formatting exception while removing shift"); exception.printStackTrace(); } break; case "editAvailability": try { String editedAvailability = dbQuery.availability.editAvailability(Integer.parseInt(args[1]), Integer.parseInt(args[2]), Integer.parseInt(args[3]), Integer.parseInt(args[4])); if (!editedAvailability.isEmpty()) { server.broadcast("editedAvailability/" + editedAvailability); } } catch (NumberFormatException exception) { System.out.println("Error: Formatting exception while editing availability"); exception.printStackTrace(); } break; case "addTimeOff": try { String newTimeOff = dbQuery.timeOff.addTimeOff(Integer.parseInt(args[1]), args[2], args[3], false, args[4]); if (!newTimeOff.isEmpty()) { server.broadcast("addTimeOff/" + newTimeOff); } } catch (NumberFormatException exception) { System.out.println("Error: Formatting exception while add time off"); exception.printStackTrace(); } break; case "removeTimeOff": try { int timeOffID = Integer.parseInt(args[1]); if (timeOffID == dbQuery.timeOff.removeTimeOff(Integer.parseInt(args[1]))) { server.broadcast("removeTimeOff/" + timeOffID); } } catch (NumberFormatException exception) { System.out.println("Error: Formatting exception while removing time off"); exception.printStackTrace(); } break; case "setTimeOffApproval": try { String newTimeOffApproval = dbQuery.timeOff.setTimeOffApproval(Integer.parseInt(args[1]), args[2]); if (!newTimeOffApproval.isEmpty()) { server.broadcast("timeOffApproval/" + newTimeOffApproval); } } catch (NumberFormatException exception) { System.out.println("Error: Formatting exception while setting time off approval"); exception.printStackTrace(); } break; case "addPosition": try { String newPosition = dbQuery.positions.addPosition(args[1], Integer.parseInt(args[2])); if (!newPosition.isEmpty()) { server.broadcast("addPosition/" + newPosition); } } catch (NumberFormatException exception) { System.out.println("Error: Formatting exception while setting time off approval"); exception.printStackTrace(); } break; case "editPosition": try { String editedPosition = dbQuery.positions.editPosition(args[1], Float.parseFloat(args[2])); if (!editedPosition.isEmpty()) { server.broadcast("addPosition/" + editedPosition); } } catch (NumberFormatException exception) { System.out.println("Error: Formatting exception while setting time off approval"); exception.printStackTrace(); } break; case "removePosition": try { dbQuery.staff.removePositionAllEmployees(args[1]); String removedPosition = dbQuery.positions.removePosition(args[1]); if (removedPosition.equalsIgnoreCase(args[1])) { server.broadcast("removePositionAllEmployees/" + args[1].toLowerCase(Locale.ROOT)); server.broadcast("removePosition/" + args[1].toLowerCase(Locale.ROOT)); } } catch (NumberFormatException exception) { System.out.println("Error: Formatting exception while setting time off approval"); exception.printStackTrace(); } break; case "addEmployeePosition": try { String addedPosition = dbQuery.staff.addPosition(Integer.parseInt(args[1]), args[2]); if (!addedPosition.isEmpty()) { server.broadcast("addEmployeePosition/" + addedPosition); } } catch (NumberFormatException exception) { System.out.println("Error: Formatting exception while setting time off approval"); exception.printStackTrace(); } break; case "removeEmployeePosition": try { String removedPosition = dbQuery.staff.removePosition(Integer.parseInt(args[1]), args[2]); if (!removedPosition.isEmpty()) { server.broadcast("removeEmployeePosition/" + removedPosition); } } catch (NumberFormatException exception) { System.out.println("Error: Formatting exception while setting time off approval"); exception.printStackTrace(); } break; case "checkIn": try { int shiftID = Integer.parseInt(args[1]); int checkedIn = dbQuery.schedule.checkIn(shiftID); if (shiftID == checkedIn) { server.broadcast("checkedIn/" + shiftID); } } catch (NumberFormatException exception) { exception.printStackTrace(); } break; case "allEmployees": //Returns all Employees serverMessage = dbQuery.staff.allEmployees(); sendMessage(serverMessage); break; case "allShifts": serverMessage = dbQuery.schedule.allShifts(); sendMessage(serverMessage); break; case "allAvailabilities": serverMessage = dbQuery.availability.allAvailabilities(); sendMessage(serverMessage); break; case "allTimeOff": serverMessage = dbQuery.timeOff.allTimeOff(); sendMessage(serverMessage); break; } } while (!clientMessage.equals("logout")); server.removeUser(this); socket.close(); } catch (IOException exception) { System.out.println("Error in UserThread: " + exception.getMessage()); exception.printStackTrace(); } } /* Name: sendMessage Parameters: String message: message to be sent. Description: Sends a message to the client of this thread. Return: void */ void sendMessage(String message) { writer.println(message); } }