diff options
Diffstat (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto')
6 files changed, 425 insertions, 0 deletions
diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Employee.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Employee.java new file mode 100644 index 0000000..f45550e --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Employee.java @@ -0,0 +1,51 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import com.google.auto.value.AutoValue; +import java.time.LocalDate; + +@AutoValue +public abstract class Employee { + public enum EducationLevel { + RS, + NFS, + NKV, + NKA, + NKI, + NA + } + + public abstract long id(); + + public abstract String name(); + + public abstract LocalDate birthday(); + + public abstract EducationLevel educationLevel(); + + public abstract boolean isDriver(); + + public abstract boolean isPilot(); + + public static Builder builder() { + return new AutoValue_Employee.Builder().id(0); + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder id(long id); + + public abstract Builder name(String name); + + public abstract Builder birthday(LocalDate birthday); + + public abstract Builder educationLevel(EducationLevel educationLevel); + + public abstract Builder isDriver(boolean isDriver); + + public abstract Builder isPilot(boolean isPilot); + + public abstract Employee build(); + } + + public abstract Builder toBuilder(); +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/EmployeeValidator.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/EmployeeValidator.java new file mode 100644 index 0000000..b03fa04 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/EmployeeValidator.java @@ -0,0 +1,23 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; + +public class EmployeeValidator { + + public static boolean validate(Employee employee) throws InvalidEmployeeException { + + if (employee.name() == null || employee.name().trim().length() == 0) { + throw new InvalidEmployeeException("Name darf nicht leer sein!"); + } + + if (employee.birthday() == null) { + throw new InvalidEmployeeException("Geburtsdatum darf nicht leer sein!"); + } + + if (employee.educationLevel() == null) { + throw new InvalidEmployeeException("Ausbildungsgrad darf nicht leer sein!"); + } + + return true; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Operation.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Operation.java new file mode 100644 index 0000000..e119622 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Operation.java @@ -0,0 +1,70 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import com.google.auto.value.AutoValue; +import java.time.Instant; +import java.util.Set; +import javax.annotation.Nullable; + +@AutoValue +public abstract class Operation { + public enum Severity { + A, + B, + C, + D, + E, + O, + } + + public enum Status { + ACTIVE, + COMPLETED, + CANCELLED, + } + + public abstract long id(); + + public abstract String opCode(); + + @Nullable + public abstract Severity severity(); + + public abstract Status status(); + + public abstract Set<Vehicle> vehicles(); + + @Nullable + public abstract Instant created(); + + public abstract String destination(); + + @Nullable + public abstract String additionalInfo(); + + public static Builder builder() { + return new AutoValue_Operation.Builder().id(0); + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder id(long id); + + public abstract Builder opCode(String opCode); + + public abstract Builder severity(Severity severity); + + public abstract Builder status(Status status); + + public abstract Builder vehicles(Set<Vehicle> vehicles); + + public abstract Builder created(Instant created); + + public abstract Builder destination(String destination); + + public abstract Builder additionalInfo(String additionalInfo); + + public abstract Operation build(); + } + + public abstract Builder toBuilder(); +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Registration.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Registration.java new file mode 100644 index 0000000..a12c038 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Registration.java @@ -0,0 +1,34 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import com.google.auto.value.AutoValue; +import java.time.Instant; + +@AutoValue +public abstract class Registration { + public abstract long id(); + + public abstract Instant start(); + + public abstract Instant end(); + + public abstract Employee employee(); + + public static Builder builder() { + return new AutoValue_Registration.Builder().id(0); + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder id(long id); + + public abstract Builder start(Instant start); + + public abstract Builder end(Instant end); + + public abstract Builder employee(Employee employee); + + public abstract Registration build(); + } + + public abstract Builder toBuilder(); +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/RegistrationValidator.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/RegistrationValidator.java new file mode 100644 index 0000000..a2cb8c1 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/RegistrationValidator.java @@ -0,0 +1,174 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidRegistrationException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +public class RegistrationValidator { + + private RegistrationValidator() {} + + public static void validate(Vehicle vehicle, Set<Registration> registrations) + throws InvalidVehicleException, InvalidRegistrationException { + /* + Vehicles and Employees are assumed to be valid. + They have been checked at creation, and for them to be checked again, access to + VehicleValidator and EmployeeValidator are needed, which are not available at this time. + */ + /* + The method used here goes as follows: All given employees are inspected in regards to their + qualifications, and added to the appropriate lists of the roles they could fill. + For example, an NFS, who is also a driver, would be added to the lists driverIds, nfsIds + and rsIds (because an NFS can always substitute an RS). + Afterwards, the number of people is checked according to the chosen vehicle type, and if + the number is okay, the program tries to find a valid combination of roles for the vehicle. + For example, for an RTW, first a driver is chosen, their ID marked as found in the aptly + titled HashMap, and then for the second RS, the list of RS is checked, excluding the chosen + driver. If no other valid RS is found, the next possible driver is chosen, and so on. If no + valid combination is found, an InvalidRegistrationException is thrown. + */ + List<Long> pilotIds = new LinkedList<>(); + List<Long> driverIds = new LinkedList<>(); + List<Long> naIds = new LinkedList<>(); + List<Long> nfsIds = new LinkedList<>(); + List<Long> rsIds = new LinkedList<>(); + HashMap<Long, Boolean> found = + new HashMap<>(); // needed later in DFS, checks that no person is chosen twice + int total = 0; + for (Registration registration : registrations) { + total++; + if (found.put(registration.employee().id(), false) != null) { + throw new InvalidRegistrationException( + "Person mit der ID: " + + registration.employee().id() + + " wurde mehrmals hinzugefügt!"); + } + if (registration.employee().isPilot()) { + pilotIds.add(registration.employee().id()); + } + if (registration.employee().isDriver()) { + driverIds.add(registration.employee().id()); + } + if (registration.employee().educationLevel() == EducationLevel.NA) { + naIds.add(registration.employee().id()); + nfsIds.add(registration.employee().id()); + rsIds.add(registration.employee().id()); + } else if (isNFS(registration.employee())) { + nfsIds.add(registration.employee().id()); + rsIds.add(registration.employee().id()); + } else { // only RS left + rsIds.add(registration.employee().id()); + } + } + if (total <= 0) { + throw new InvalidRegistrationException("Kein Personal ausgewählt!"); + } + if (vehicle.type() == VehicleType.NAH) { + /* + NAH + 1 Pilot + 1 NFS + 1 NA + 3-4 Personen + */ + if (total < 3) { + throw new InvalidRegistrationException("Zu wenig Personal für NAH!"); + } else if (total > 4) { + throw new InvalidRegistrationException("Zu viel Personal für NAH!"); + } + for (long pilot_id : pilotIds) { + found.put(pilot_id, true); + for (long na_id : naIds) { + if (found.get(na_id)) continue; + found.put(na_id, true); + for (long nfs_id : nfsIds) { + if (found.get(nfs_id)) continue; + return; + } + found.put(na_id, false); + } + found.put(pilot_id, false); + } + throw new InvalidRegistrationException( + "Keine gültige Kombination von Personen für NAH!"); + } else if (vehicle.type() == VehicleType.NEF) { + /* + NEF + 1 Driver (has to be NFS) + 1 NA + */ + if (total < 2) { + throw new InvalidRegistrationException("Zu wenig Personal für NEF!"); + } else if (total > 3) { + throw new InvalidRegistrationException("Zu viel Personal für NEF!"); + } + for (long driver_id : driverIds) { + if (!nfsIds.contains(driver_id)) + continue; // if possible driver is not NFS, skip him + found.put(driver_id, true); + for (long na_id : naIds) { + if (found.get(na_id)) continue; + return; + } + found.put(driver_id, false); + } + throw new InvalidRegistrationException( + "Keine gültige Kombination von Personen für NEF!"); + } else if (vehicle.type() == VehicleType.BKTW) { + /* + BKTW + 1 Driver + */ + if (total > 3) { + throw new InvalidRegistrationException("Zu viel Personal für BKTW!"); + } + if (!driverIds.isEmpty()) { + return; + } + throw new InvalidRegistrationException("Kein Fahrer gefunden für BKTW!"); + } else { // KTW or RTW, both have the same requirements + /* + RTW/KTW + 1 Driver + 1 RS + */ + if (total < 2) { + throw new InvalidRegistrationException( + "Zu wenig Personal für " + vehicle.type().name() + "!"); + } else if (total > 4) { + throw new InvalidRegistrationException( + "Zu viel Persoanl für " + vehicle.type().name() + "!"); + } + for (long driver_id : driverIds) { // driver includes rs + found.put(driver_id, true); + for (long rs_id : rsIds) { + if (found.get(rs_id)) continue; + return; + } + } + throw new InvalidRegistrationException( + "Keine gültige Kombination von Personen für " + vehicle.type().name() + "!"); + } + } + + private static boolean isNFS(Employee employee) { + EducationLevel educationLevel = employee.educationLevel(); + switch (educationLevel) { + case NFS: + return true; + case NKA: + return true; + case NKI: + return true; + case NKV: + return true; + default: + return false; + } + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Vehicle.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Vehicle.java new file mode 100644 index 0000000..c2033f5 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Vehicle.java @@ -0,0 +1,73 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import com.google.auto.value.AutoValue; +import java.util.List; +import javax.annotation.Nullable; + +@AutoValue +public abstract class Vehicle { + public enum ConstructionType { + NORMAL, + HOCHDACH, + MITTELHOCHDACH, + } + + public enum VehicleType { + BKTW, + KTW_B, + KTW, + RTW, + NEF, + NAH, + } + + public enum Status { + ABGEMELDET, + FREI_WACHE, + FREI_FUNK, + ZUM_BERUFUNGSORT, + AM_BERUFUNGSORT, + ZUM_ZIELORT, + AM_ZIELORT, + } + + public abstract long id(); + + public abstract String name(); + + public abstract ConstructionType constructionType(); + + public abstract VehicleType type(); + + public abstract Status status(); + + public abstract boolean hasNef(); + + @Nullable + public abstract List<Registration> registrations(); + + public static Builder builder() { + return new AutoValue_Vehicle.Builder().id(0); + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder id(long id); + + public abstract Builder name(String name); + + public abstract Builder constructionType(ConstructionType constructionType); + + public abstract Builder type(VehicleType type); + + public abstract Builder status(Status status); + + public abstract Builder hasNef(boolean hasNef); + + public abstract Builder registrations(List<Registration> registrations); + + public abstract Vehicle build(); + } + + public abstract Builder toBuilder(); +} |