diff options
author | Felix Kehrer <felix.kehrer@gmail.com> | 2018-05-04 15:58:45 +0200 |
---|---|---|
committer | Felix Kehrer <felix.kehrer@gmail.com> | 2018-05-07 14:42:05 +0200 |
commit | 05c7e29e8d7cd474963b7636f54c3d6f1e4bd390 (patch) | |
tree | 75dc31998262993bf22c84974b56f25fe6476f2a | |
parent | 9537613b77696bf3f7b7ecec28b464c17fbe34db (diff) | |
download | sepm-groupproject-05c7e29e8d7cd474963b7636f54c3d6f1e4bd390.tar.gz sepm-groupproject-05c7e29e8d7cd474963b7636f54c3d6f1e4bd390.tar.xz sepm-groupproject-05c7e29e8d7cd474963b7636f54c3d6f1e4bd390.zip |
Implemented RegistrationService using RegistrationValidator
2 files changed, 239 insertions, 0 deletions
diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/RegistrationValidator.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/RegistrationValidator.java new file mode 100644 index 0000000..ac6c1f2 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/RegistrationValidator.java @@ -0,0 +1,194 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto; + +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidRegistrationException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RegistrationValidator { + + private static final Logger LOG = LoggerFactory.getLogger(RegistrationValidator.class); + + private RegistrationValidator() {} + + public static void validate(Vehicle vehicle, List<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) { + LOG.info("Employee with ID {} was added twice", registration.employee().id()); + throw new InvalidRegistrationException( + "Person with the ID: " + + registration.employee().id() + + " was added more than once!"); + } + 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) { + LOG.info("No employees were added"); + 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) { + LOG.info("Too few employees for NAH"); + throw new InvalidRegistrationException("Zu wenig Personal für NAH!"); + } else if (total > 4) { + LOG.info("Too many employees for NAH"); + 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; + LOG.info("Valid combination found for NAH"); + return; + } + found.put(na_id, false); + } + found.put(pilot_id, false); + } + LOG.info("No valid combination of employees found for NAH"); + 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) { + LOG.info("Too few employees for NEF"); + throw new InvalidRegistrationException("Zu wenig Personal für NEF!"); + } else if (total > 3) { + LOG.info("Too many employees for NEF"); + 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; + LOG.info("Valid combinaion found for NEF"); + return; + } + found.put(driver_id, false); + } + LOG.info("No valid combination of employees found for NEF"); + throw new InvalidRegistrationException( + "Keine gültige Kombination von Personen für NEF!"); + } else if (vehicle.type() == VehicleType.BKTW) { + /* + BKTW + 1 Driver + */ + if (total > 3) { + LOG.info("Too many employees for BKTW"); + throw new InvalidRegistrationException("Zu viel Personal für BKTW!"); + } + if (!driverIds.isEmpty()) { + LOG.info("Valid combination found for BKTW"); + return; + } + LOG.info("No driver was found for BKTW"); + 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) { + LOG.info("Too few employees for {}", vehicle.type().name()); + throw new InvalidRegistrationException( + "Zu wenig Personal für " + vehicle.type().name() + "!"); + } else if (total > 4) { + LOG.info("Too many employees for {}", vehicle.type().name()); + 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; + LOG.info("Valid combination found for {}", vehicle.type().name()); + return; + } + } + LOG.info("No valid combination of employees found for {}", vehicle.type().name()); + 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/einsatzverwaltung/service/SimpleRegistrationService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/SimpleRegistrationService.java new file mode 100644 index 0000000..5b26e39 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/SimpleRegistrationService.java @@ -0,0 +1,45 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; + +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.RegistrationDAO; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.RegistrationValidator; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; +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.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class SimpleRegistrationService implements RegistrationService { + + private static final Logger LOG = LoggerFactory.getLogger(SimpleRegistrationService.class); + + private final RegistrationDAO registrationDAO; + + @Autowired + public SimpleRegistrationService(RegistrationDAO registrationDAO) { + this.registrationDAO = registrationDAO; + } + + @Override + public List<Long> add(Vehicle vehicle, List<Registration> registrations) + throws InvalidVehicleException, InvalidRegistrationException, ServiceException { + RegistrationValidator.validate(vehicle, registrations); + try { + return registrationDAO.add(vehicle.id(), registrations); + } catch (PersistenceException e) { + LOG.warn("PersistenceException caught, throwing matching ServiceException"); + throw new ServiceException(e); + } + } + + @Override + public void remove(long registrationId) throws InvalidRegistrationException, ServiceException { + throw new UnsupportedOperationException(); + } +} |