Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package control; import control.comparators.PeriodComparator; import control.comparators.RoomAmountComparator; import control.comparators.RoomMaximumComparator; import control.comparators.RoomMinimumComparator; import exceptions.DatabaseException; import java.util.ArrayList; import model.Employee; import model.LimitQualification; import model.Room; import model.RoomQualification; import model.TimeInvestment; import model.TimePeriod; import org.joda.time.LocalDateTime; import technicalServices.persistence.TimeInvestmentHandler; /** * * @author Benjamin */ public class TimeInvestmentControl { public void addTimeInvestments(ArrayList<TimeInvestment> shifts) throws DatabaseException { TimeInvestmentHandler.getInstance().addTimeInvestments(shifts); } public ArrayList<TimeInvestment> getUnassignedTimeInvestments() throws DatabaseException { return TimeInvestmentHandler.getInstance().getUnassignedTimeInvestments(); } /** * Denne metode tildeler rum til medarbejdere. * * @param periodStart * @param periodEnd * @return Returnerer en liste af timeInvestments der har fet sine rum * tildelt. * @throws exceptions.DatabaseException */ public ArrayList<TimeInvestment> assignRooms(LocalDateTime periodStart, LocalDateTime periodEnd) throws DatabaseException { ArrayList<TimeInvestment> unassignedShifts = getUnassignedTimeInvestments(); unassignedShifts = getShiftsInPeriod(unassignedShifts, periodStart, periodEnd); ArrayList<RoomQualification> roomQualifications = Xray.getInstance().getQualificationControl() .getRoomQualifications(); ArrayList<LimitQualification> limitQualifications = Xray.getInstance().getQualificationControl() .getLimitQualifications(); ArrayList<TimeInvestment> assignedShifts = new ArrayList<>(); //Sortr liste af vagter ud fra denne prioritet: 1: dato, 2: timer, 3: minutter //4: Antal tilgngelige rum for medarbejder (lavest frst) 5: fornavn 6: efternavn. unassignedShifts.sort(new RoomAmountComparator(roomQualifications)); //Gennemlbnign af shifts, til tildeling af rum. for (int i = 0; i < unassignedShifts.size(); i++) { ArrayList<Room> rooms = getEmployeeRooms(unassignedShifts.get(i).getEmployee(), roomQualifications); TimeInvestment assignedShift = unassignedShifts.get(i); if (assignedShift.getRoom() == null) { assignedShift.setRoom(roomPriority(assignedShifts, rooms, assignedShift, limitQualifications)); } if (assignedShift.getRoom() != null) { assignedShifts.add(assignedShift); } else { //Vagten har ikke fet tildelt et rum, konsekvens abstraheret. } } updateShifts(assignedShifts); return assignedShifts; } /** * Denne metode finder det rum der har hjest prioritet. * * @param timeInvestments liste over tidsinvesteringer (tildelinger af rum * til medarbejdere). * @param rooms liste over rum. * @return Det hjst-prioriterede rum. */ private Room roomPriority(ArrayList<TimeInvestment> timeInvestments, ArrayList<Room> rooms, TimeInvestment currentShift, ArrayList<LimitQualification> limitQualifications) throws DatabaseException { //Room objekt som starter med en null pointer, bliver uanset hvad defineret //senere. Room prioritizedRoom = null; //Tl tildelinger til specifikke rum op for medarbejderen sluttet til //currentShift. S hvis rumX er blevet tildelt 5 gange til medarbejderen //i currentShift's tidsperiode, vil denne RoomAssignmentCounter blive 5, //og have rum reference til rumX. countDateAssignmentsOfRoomForEmp(rooms, currentShift, timeInvestments); //Tl hvor mange gange de forskellige rum er blevet tildelt i currentShifts //starttidspunkt. Tllingen bestr i at alle Room-objekter i rooms fr talt //op p deres count felt, s dette passer med antal tildelinger. countDateAssignmentsOfRoom(rooms, currentShift, timeInvestments); ArrayList<Room> roomsLimitNotReached = getRoomsLimitNotReached(currentShift.getEmployee(), limitQualifications); countDateAssignmentsOfRoom(roomsLimitNotReached, currentShift, timeInvestments); if (!roomsLimitNotReached.isEmpty()) { //Her inde bliver alle rum der stadig mangler at opfylde //limit p limitQualifications behandlet. prioritizedRoom = getRoomMinMaxCompared(roomsLimitNotReached, currentShift); } else { prioritizedRoom = getRoomMinMaxCompared(rooms, currentShift); } return prioritizedRoom; } /** * Henter alle de rum som en specifik medarbejder - ud fra sine * rumKvalifikationer - kan blive tildelt. * * @param employee den specifikke medarbejder. * @param roomQualifications en liste af rumKvalifikationer. * @return Den liste af rum som den specifikke medarbejder er kvalificeret * til. */ public ArrayList<Room> getEmployeeRooms(Employee employee, ArrayList<RoomQualification> roomQualifications) { ArrayList<Room> employeeRooms = new ArrayList<>(); //Lb den givne liste af rumKvalifikationer igennem. for (int i = 0; i < roomQualifications.size(); i++) { //Listen af medarbejdere p den kvalifikation for-lkken er net til. ArrayList<Employee> employees = roomQualifications.get(i).getEmployees(); for (int j = 0; j < employees.size(); j++) { //Liner sgning efter den specifikke medarbejder. if (employees.get(j).getId() == employee.getId()) { //Alle de rum som den kvalifikation er tilsluttet. ArrayList<Room> rooms = roomQualifications.get(i).getRooms(); for (int k = 0; k < rooms.size(); k++) { //tilfj til listen over rum, den specifikke medarbejder, //kvalificeret til. Tilfj dem kun hvis de er bne. if (rooms.get(k).getRoomState() == 1) { //Hvis ikke det nuvrende rum allerede findes i listen. if (!isAllreadyInList(rooms.get(k), employeeRooms)) { employeeRooms.add(rooms.get(k)); } } } } } } return employeeRooms; } /** * Returnerer en liste over alle de rum som ikke har opnet sine * begrnsninger, baseret p en liste af limitQualifications. * * @param employee * @param limitQualifications * @return en liste over alle de rum som ikke har opnet sine begrnsninger. */ private ArrayList<Room> getRoomsLimitNotReached(Employee employee, ArrayList<LimitQualification> limitQualifications) { ArrayList<Room> roomsLimitNotReached = new ArrayList<>(); //Lb den givne liste af limitKvalifikationer igennem. for (int i = 0; i < limitQualifications.size(); i++) { //Listen af medarbejdere p den kvalifikation for-lkken er net til. ArrayList<Employee> employees = limitQualifications.get(i).getEmployees(); for (int j = 0; j < employees.size(); j++) { //Liner sgning efter den specifikke medarbejder. if (employees.get(j).getId() == employee.getId()) { //Alle de rum som den kvalifikation er tilsluttet. ArrayList<Room> limitRooms = limitQualifications.get(i).getRooms(); for (int k = 0; k < limitRooms.size(); k++) { Room limitRoom = limitRooms.get(k); //tilfj til listen over rum, den specifikke medarbejder, //er kvalificeret til. Tilfj dem kun hvis de er bne. if (limitRoom.getRoomState() == 1) { //Hvis ikke det nuvrende rum allerede findes i listen. if (!isAllreadyInList(limitRoom, roomsLimitNotReached)) { //Hvis begrnsningen endnu ikke er net s tilfj //til roomsLimitNotReached. if (limitRoom.getCount() < limitQualifications.get(i).getLimit()) { roomsLimitNotReached.add(limitRoom); } } } } } } } return roomsLimitNotReached; } /** * Formlet med denne metode er at tlle n op p et rum i en given liste af * rum for hver gang dette rum er blevet tildelt en medarbejder ved hjlp af * et TimeInvestment-objekt. P en given vagts starttidspunkt. P denne mde * kan man stole p at alle rum i den givne liste har et count felt der * passer til den rigtige dato, frem for at vre tidslst (feltet angiver * kun et count, og er ligeglad med tiden, denne funktionalitet sikrer at * tiden stemmer). * * @param rooms * @param currentShift * @param timeInvestments */ public void countDateAssignmentsOfRoom(ArrayList<Room> rooms, TimeInvestment currentShift, ArrayList<TimeInvestment> timeInvestments) { //Nulstil roomObjekternes count felt. for (Room room : rooms) { room.setCount(0); } if (timeInvestments.size() > 0) { for (int i = 0; i < timeInvestments.size(); i++) { String roomName = timeInvestments.get(i).getRoom().getRoomName(); //Liner sgning. Hvis det givne rum findes s skal dets tller, //tlle n op. for (int j = 0; j < rooms.size(); j++) { if (roomName.equals(rooms.get(j).getRoomName())) { TimeInvestment currentTI = timeInvestments.get(i); LocalDateTime date = currentShift.getStartTime(); LocalDateTime periodStart = currentTI.getStartTime(); LocalDateTime periodEnd = new LocalDateTime(periodStart); periodEnd = periodEnd.plus(currentTI.getHours()); periodEnd = periodEnd.plus(currentTI.getMinutes()); if (Xray.getInstance().isDateInPeriod(date, periodStart, periodEnd)) { rooms.get(j).increment(); break; //break OK i sgning for optimering. } break; } } } } } /** * Tller counters op p den employee som currentShift refererer til. * * @param rooms * @param currentShift * @param timeInvestments * @throws DatabaseException */ public void countDateAssignmentsOfRoomForEmp(ArrayList<Room> rooms, TimeInvestment currentShift, ArrayList<TimeInvestment> timeInvestments) throws DatabaseException { Employee employee = currentShift.getEmployee(); //Opret roomAssignment counters p currentShift's employee. createCounters(employee); ArrayList<TimeInvestment> empTimeInvestments = getEmpTimeInvestments(timeInvestments, currentShift); if (timeInvestments.size() > 0) { for (int i = 0; i < empTimeInvestments.size(); i++) { String roomName = empTimeInvestments.get(i).getRoom().getRoomName(); //Liner sgning. Hvis det givne rum findes s skal dets tller, //i den passende roomCounter p employee tlle n op. for (int j = 0; j < rooms.size(); j++) { if (roomName.equals(rooms.get(j).getRoomName())) { employee.increment(rooms.get(j)); break; //break OK i sgning for optimering. } } } } } /** * Returnerer en liste af vagter som hrer til currentShift's employee, og * som er i samme tidsperiode som currentShift. * * @param timeInvestments den totale mngde af tidsinvesteringer. * @param currentShift den nuvrende vagt. * @return */ public ArrayList<TimeInvestment> getEmpTimeInvestments(ArrayList<TimeInvestment> timeInvestments, TimeInvestment currentShift) { ArrayList<TimeInvestment> employeeShifts = new ArrayList<>(); for (TimeInvestment timeInvestment : timeInvestments) { if (timeInvestment.getEmployee().getId() == currentShift.getEmployee().getId()) { employeeShifts.add(timeInvestment); } } return employeeShifts; } /** * Tilfjer en liste af roomAssignmentCounters til den givne employee's * counters felt. * * @param employee employee hvis liste af counters skal opdateres. * @throws DatabaseException */ public void createCounters(Employee employee) throws DatabaseException { ArrayList<Room> rooms; rooms = Xray.getInstance().getRoomControl().getRooms(); employee.getCounters().clear(); for (Room room : rooms) { employee.addCounter(new RoomAssignmentCounter(room, 0)); } } public Room getRoomMinMaxCompared(ArrayList<Room> rooms, TimeInvestment currentShift) throws DatabaseException { Room prioritizedRoom = null; TimePeriodControl timePeriodControl = Xray.getInstance().getTimePeriodControl(); //Hent liste af tidsperioder som currentShift bliver pvirket af. ArrayList<TimePeriod> timePeriods = timePeriodControl.getTimeperiods(currentShift); //Initialiser en liste over rum, som skal indeholde alle de rum der har en //tidsperiode-begrnsning. ArrayList<Room> roomsWithConstraints = new ArrayList<>(); //Initialiser en liste over rum, som skal indeholde alle de rum der har net //sine minimummer. ArrayList<Room> tempRoomsMinReached = new ArrayList<>(); for (int i = 0; i < rooms.size(); i++) { Room currentRoom = rooms.get(i); if (!rooms.isEmpty()) { if (timePeriods.size() > 0) { if (timePeriodControl.hasPeriodConstraint(timePeriods, currentRoom)) { roomsWithConstraints.add(currentRoom); rooms.remove(i); i--; } else { if (currentRoom.getMinOccupation() <= currentRoom.getCount()) { //Kontroller at det nuvrende rum har net sit minimum, tilfj det //til tempRoomsMinReached og fjern det fra rooms. tempRoomsMinReached.add(currentRoom); rooms.remove(i); i--; } } } } } boolean isMinReached = true; boolean isMaxReached = false; ArrayList<TimePeriod> periodsForEmp = timePeriodControl.getTimePeriodsForEmp(timePeriods, currentShift); for (int i = 0; i < periodsForEmp.size(); i++) { TimePeriod period = periodsForEmp.get(i); //rsc giver mulighed for at vide hvor mange gange currentShift's //person er blevet tildelt det rum, iterationen er net til. RoomAssignmentCounter rsc = currentShift.getEmployee().getRoomAssignmentCounter(period.getRoom()); //Fjern fra listen hvis maximummet er opnet. if (period.getMax() <= rsc.getCount()) { periodsForEmp.remove(period); } } ArrayList<RoomAssignmentCounter> racs = currentShift.getEmployee().getCounters(); //Hvis der er rum med begrnsninger i form af timePeriods s g dem igennem. if (!periodsForEmp.isEmpty()) { //Sorter listen af tidsperioder, sdan at det vigtigste rum refererer //den frste tidsperiode i listen. periodsForEmp.sort(new PeriodComparator(currentShift.getEmployee())); prioritizedRoom = periodsForEmp.get(0).getRoom(); isMinReached = isMinReached(periodsForEmp, currentShift); isMaxReached = isMaxReached(periodsForEmp, currentShift); } if (isMinReached && !isMaxReached) { if (!rooms.isEmpty()) { rooms.sort(new RoomMinimumComparator(currentShift.getEmployee())); //Prioriter det rum der er blevet tildelt frrest gange. (hjest prioritet //m vre p plads 0). prioritizedRoom = rooms.get(0); } else { for (int i = 0; i < tempRoomsMinReached.size(); i++) { if (!tempRoomsMinReached.isEmpty()) { if (tempRoomsMinReached.get(i).getMaxOccupation() <= tempRoomsMinReached.get(i) .getCount()) { tempRoomsMinReached.remove(i); i--; } } } tempRoomsMinReached.sort(new RoomMaximumComparator()); if (!tempRoomsMinReached.isEmpty()) { prioritizedRoom = tempRoomsMinReached.get(0); } } } return prioritizedRoom; } public boolean isMinReached(ArrayList<TimePeriod> timePeriods, TimeInvestment currentShift) { boolean minReached = true; for (TimePeriod timePeriod : timePeriods) { Employee thisEmp = currentShift.getEmployee(); RoomAssignmentCounter thisRac = thisEmp.getRoomAssignmentCounter(timePeriod.getRoom()); if (timePeriod.getMin() > thisRac.getCount()) { minReached = false; } } return minReached; } public boolean isMaxReached(ArrayList<TimePeriod> timePeriods, TimeInvestment currentShift) { boolean maxReached = false; for (TimePeriod timePeriod : timePeriods) { Employee thisEmp = currentShift.getEmployee(); RoomAssignmentCounter thisRac = thisEmp.getRoomAssignmentCounter(timePeriod.getRoom()); if (timePeriod.getMax() <= thisRac.getCount()) { maxReached = true; } } return maxReached; } /** * Metode til at finde vagter p en given dato og i en given tidsperiode, i * en given liste. * * @param shifts liste af vagter der skal sges i. * @param periodStart * @param periodEnd * @return en liste af alle vagter i en given tidsperiode p en given dato. */ public ArrayList<TimeInvestment> getShiftsInPeriod(ArrayList<TimeInvestment> shifts, LocalDateTime periodStart, LocalDateTime periodEnd) { ArrayList<TimeInvestment> shiftsInPeriod = new ArrayList<>(); for (int j = 0; j < shifts.size(); j++) { boolean isInPeriod = Xray.getInstance().isDateInPeriod(shifts.get(j).getStartTime(), periodStart, periodEnd); if (isInPeriod) { shiftsInPeriod.add(shifts.get(j)); } } return shiftsInPeriod; } public boolean isAllreadyInList(Room room, ArrayList<Room> rooms) { boolean allreadyInList = false; for (int i = 0; i < rooms.size(); i++) { if (rooms.get(i).getRoomName().equals(room.getRoomName())) { allreadyInList = true; } } return allreadyInList; } public ArrayList<TimeInvestment> getAssignedTimeInvestments() throws DatabaseException { return TimeInvestmentHandler.getInstance().getAssignedTimeInvestments(); } private void updateShifts(ArrayList<TimeInvestment> assignedShifts) throws DatabaseException { for (int i = 0; i < assignedShifts.size(); i++) { System.out.println(assignedShifts.get(i)); TimeInvestmentHandler.getInstance().updateTimeInvestment(assignedShifts.get(i)); } } }