diff options
Diffstat (limited to 'src/main/java/at')
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(); +    } +}  | 
