diff options
Diffstat (limited to 'src/main/java/at/ac/tuwien/sepm')
4 files changed, 164 insertions, 435 deletions
diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java index 070b3fb..0bb25b8 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java @@ -1,18 +1,12 @@  package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException;  import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; -import java.lang.invoke.MethodHandles;  import java.sql.Connection;  import java.sql.PreparedStatement;  import java.sql.ResultSet; @@ -20,143 +14,71 @@ import java.sql.SQLException;  import java.sql.Timestamp;  import java.util.EnumSet;  import java.util.HashSet; -import java.util.LinkedList; -import java.util.List;  import java.util.Objects;  import java.util.Set;  import java.util.stream.Collectors; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.springframework.lang.NonNull;  import org.springframework.stereotype.Repository;  @Repository  public class DBOperationDAO implements OperationDAO {      private JDBCConnectionManager jdbcConnectionManager; -    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); +    private VehicleDAO vehicleDAO; -    public DBOperationDAO(JDBCConnectionManager j) { -        jdbcConnectionManager = j; -        try { - -            getVehicleId = jdbcConnectionManager.getConnection().prepareStatement(GET_VEHICLE_ID); - -            getVehicle = jdbcConnectionManager.getConnection().prepareStatement(GET_VEHICLE); - -            getVehicleVersion = -                    jdbcConnectionManager.getConnection().prepareStatement(GET_VEHICLE_VERSION); - -            getRegistrations = -                    jdbcConnectionManager.getConnection().prepareStatement(GET_REGISTRATIONS); - -            getEmployee = jdbcConnectionManager.getConnection().prepareStatement(GET_EMPLOYEE); - -            getEmployeeVersion = -                    jdbcConnectionManager.getConnection().prepareStatement(GET_EMPLOYEE_VERSION); - -        } catch (SQLException e) { - -            LOG.error( -                    "SQLException occurred while preparing Statements. Error message: {} ", -                    e.getMessage()); - -            // TODO: nothing should be thrown here -            throw new IllegalStateException("TODO: fix me"); -            // throw new PersistenceException(e); -        } +    public DBOperationDAO(JDBCConnectionManager jdbcConnectionManager, VehicleDAO vehicleDAO) { +        this.jdbcConnectionManager = jdbcConnectionManager; +        this.vehicleDAO = vehicleDAO;      }      @Override -    public long add(Operation operation) throws PersistenceException { -        if (operation == null) { -            throw new PersistenceException("Das der Datenbank übergebene Objekt ist fehlerhaft!"); -        } -        PreparedStatement pstmt = null; +    public long add(@NonNull Operation o) throws PersistenceException { +        String sql = +                "INSERT INTO Operation(opCode, severity, created, destination, additionalInfo," +                        + "            status) VALUES (?, ?, ?, ?, ?, ?)"; +        String sql2 = "INSERT INTO VehicleOperation(vehicleId, operationId) VALUES (?, ?)"; +        long operationId; +          try { -            pstmt = -                    jdbcConnectionManager -                            .getConnection() -                            .prepareStatement( -                                    "INSERT INTO operation(opCode, severity, " -                                            + "created, destination, additionalInfo, status) values (?,?,?,?,?,?)", -                                    java.sql.Statement.RETURN_GENERATED_KEYS); +            Connection con = jdbcConnectionManager.getConnection(); +            con.setAutoCommit(false); +            try (PreparedStatement pstmt = con.prepareStatement(sql)) { +                pstmt.setString(1, o.opCode()); +                pstmt.setInt(2, o.severity().ordinal()); +                pstmt.setTimestamp(3, Timestamp.from(Objects.requireNonNull(o.created()))); +                pstmt.setString(4, o.destination()); +                pstmt.setString(5, o.additionalInfo()); +                pstmt.setInt(6, o.status().ordinal()); +                pstmt.executeUpdate(); -            if (operation.opCode() == null) { -                throw new PersistenceException("Code darf nicht null sein!"); -            } else if (operation.opCode().length() > 20) -                throw new PersistenceException( -                        "Länge des OP-Codes überschreitet erlaubte Länge von 100 Zeichen!"); -            else pstmt.setString(1, operation.opCode()); -            /*switch (operation.severity()) { -                case A: -                    pstmt.setInt(2, 0); -                    break; -                case B: -                    pstmt.setInt(2, 1); -                    break; -                case C: -                    pstmt.setInt(2, 2); -                    break; -                case D: -                    pstmt.setInt(2, 3); -                    break; -                case E: -                    pstmt.setInt(2, 4); -                    break; -                case O: -                    pstmt.setInt(2, 5); -                    break; -                default: -                    throw new PersistenceException( -                            "Schwere des Einsatzes konnte nicht validiert werden!"); -            }*/ -            pstmt.setString(2, operation.severity().name()); -            if (operation.created() != null) { -                pstmt.setTimestamp(3, Timestamp.from(Objects.requireNonNull(operation.created()))); -            } else { -                throw new PersistenceException("Zeitpunkt der Erstellung darf nicht null sein!"); -            } +                try (ResultSet rs = pstmt.getGeneratedKeys()) { +                    if (!rs.next()) throw new PersistenceException("Failed to persist operation"); -            if (operation.destination() == null) { -                throw new PersistenceException("Einsatzort darf nicht null sein!"); -            } else if (operation.destination().length() > 100) { -                throw new PersistenceException( -                        "Länge der Adresse überschreitet erlaubte Länge von 100 Zeichen!"); -            } else { -                pstmt.setString(4, operation.destination()); +                    operationId = rs.getLong(1); +                }              } -            if (operation.additionalInfo().length() > 100) -                throw new PersistenceException( -                        "Länge der zusätzlichen Information überschreitet erlaubte Länge von 100 Zeichen!"); -            else pstmt.setString(5, operation.additionalInfo()); -            if (operation.status() == null) { -                throw new PersistenceException("Status darf nicht null sein!"); -            } else if (operation.status().toString().length() > 100) { -                throw new PersistenceException( -                        "Länge des Status überschreitet erlaubte Länge von 100 Zeichen!"); -            } else { -                pstmt.setString(6, operation.status().toString()); + +            try (PreparedStatement pstmt = con.prepareStatement(sql2)) { +                pstmt.setLong(2, operationId); + +                for (long id : (Iterable<Long>) o.vehicles().stream().map(Vehicle::id)::iterator) { +                    pstmt.setLong(1, id); +                    pstmt.addBatch(); +                } + +                pstmt.executeBatch();              } -            pstmt.executeUpdate(); -            ResultSet rs = pstmt.getGeneratedKeys(); -            if (rs.next()) return rs.getInt(1); -            else throw new PersistenceException("Einsatz konnte nicht gespeichert werden"); +            con.commit(); +            con.setAutoCommit(true); +            return operationId;          } catch (SQLException e) {              throw new PersistenceException(e); -        } finally { -            if (pstmt != null) { -                try { -                    pstmt.close(); -                } catch (SQLException e) { -                    throw new PersistenceException( -                            "Verbindung zur Datenbank konnte nicht geschlossen werden!", e); -                } -            }          }      }      @Override -    public void update(Operation o) throws ElementNotFoundException, PersistenceException { +    public void update(@NonNull Operation o) throws ElementNotFoundException, PersistenceException { +        // Note this will, by design, not update created          String sql =                  "UPDATE Operation SET opCode = ?, severity = ?, destination = ?,"                          + " additionalInfo = ?, status = ? WHERE id = ?"; @@ -175,7 +97,7 @@ public class DBOperationDAO implements OperationDAO {                  pstmt.setLong(6, o.id());                  if (pstmt.executeUpdate() != 1) -                    throw new ElementNotFoundException("No such operationId exists: " + pstmt); +                    throw new ElementNotFoundException("No such operationId exists");              }              try (PreparedStatement pstmt = con.prepareStatement(sql2)) { @@ -202,19 +124,21 @@ public class DBOperationDAO implements OperationDAO {      @Override      public Operation get(long operationId) throws ElementNotFoundException, PersistenceException { -        if (operationId <= 0) -            throw new ElementNotFoundException("Es wurde eine falsche ID übergeben!"); -          String sql = "Select * from operation where id = ?"; -        try (PreparedStatement pstmt = -                jdbcConnectionManager.getConnection().prepareStatement(sql)) { -            pstmt.setLong(1, operationId); -            pstmt.execute(); -            ResultSet rs = pstmt.getResultSet(); -            if (rs.next()) { -                return operationFromRS(rs); -            } else throw new ElementNotFoundException("No element could be found!"); +        try { +            Connection con = jdbcConnectionManager.getConnection(); +            try (PreparedStatement pstmt = con.prepareStatement(sql)) { +                pstmt.setLong(1, operationId); +                pstmt.execute(); + +                try (ResultSet rs = pstmt.getResultSet()) { +                    if (!rs.next()) +                        throw new ElementNotFoundException("No such element could be found"); + +                    return operationFromRS(rs); +                } +            }          } catch (SQLException e) {              throw new PersistenceException(e);          } @@ -240,7 +164,6 @@ public class DBOperationDAO implements OperationDAO {                  // Object[] arr = statuses.stream().map(Enum::ordinal).toArray();                  // pstmt.setArray(1, con.createArrayOf("INT", arr)); -                // TODO: this should set the vehicles as well                  try (ResultSet rs = pstmt.executeQuery()) {                      while (rs.next()) operations.add(operationFromRS(rs));                  } @@ -253,194 +176,42 @@ public class DBOperationDAO implements OperationDAO {      }      private Operation operationFromRS(ResultSet rs) throws PersistenceException, SQLException { +        Long operationId = rs.getLong("id"); +          return Operation.builder() -                .id(rs.getLong("id")) +                .id(operationId)                  .opCode(rs.getString("opCode"))                  .severity(Severity.valueOf(rs.getString("severity")))                  .status(Status.valueOf(rs.getString("status"))) -                .vehicles(getVehiclesFromOperationId(rs.getLong("id"))) +                .vehicles(getVehiclesFromOperationId(operationId))                  .created(rs.getTimestamp("created").toInstant())                  .destination(rs.getString("destination"))                  .additionalInfo(rs.getString("additionalInfo"))                  .build();      } -    private static final String GET_VEHICLE_ID = -            "SELECT vehicleId FROM VehicleOperation WHERE operationId = ? ;"; - -    private final PreparedStatement getVehicleId; -      private Set<Vehicle> getVehiclesFromOperationId(long operationId) throws PersistenceException { +        String sql = "SELECT vehicleId FROM VehicleOperation WHERE operationId = ?";          Set<Vehicle> vehicles = new HashSet<>(); -        try { -            getVehicleId.setLong(1, operationId); -            try (ResultSet resultSet = getVehicleId.executeQuery()) { -                while (resultSet.next()) { -                    vehicles.add(getVehicle(resultSet.getLong("vehicleId"))); -                } -            } -        } catch (SQLException e) { -            LOG.error( -                    "SQLException occurred while getting VehicleId from OperationId. Error message: {}", -                    e.getMessage()); -            throw new PersistenceException(e); -        } -        return vehicles; -    } - -    private static String GET_VEHICLE = "SELECT * FROM Vehicle WHERE id = ? ;"; - -    private final PreparedStatement getVehicle; - -    private Vehicle getVehicle(long vehicleId) throws PersistenceException { -        try { -            getVehicle.setLong(1, vehicleId); -            try (ResultSet resultSet = getVehicle.executeQuery()) { -                resultSet.next(); -                return getVehicleVersion( -                        resultSet.getLong("id"), -                        resultSet.getLong("version"), -                        resultSet.getString("status")); -            } -        } catch (SQLException e) { -            LOG.error( -                    "SQLException occurred while getting Vehicle by id. Error message: {}", -                    e.getMessage()); -            throw new PersistenceException(e); -        } -    } -    private static String GET_VEHICLE_VERSION = "SELECT * FROM VehicleVersion WHERE id = ? ;"; - -    private final PreparedStatement getVehicleVersion; - -    private Vehicle getVehicleVersion(long vehicleId, long versionId, String status) -            throws PersistenceException {          try { -            getVehicleVersion.setLong(1, versionId); -            try (ResultSet resultSet = getVehicleVersion.executeQuery()) { -                resultSet.next(); -                return Vehicle.builder() -                        .id(vehicleId) -                        .name(resultSet.getString("name")) -                        .constructionType( -                                ConstructionType.valueOf(resultSet.getString("constructionType"))) -                        .type(VehicleType.valueOf(resultSet.getString("type"))) -                        .status(Vehicle.Status.valueOf(status)) -                        .hasNef(resultSet.getBoolean("hasNef")) -                        .registrations(getRegistrations(vehicleId)) -                        .build(); -            } -        } catch (SQLException e) { -            LOG.error( -                    "SQLException occurred while getting VehicleVersion. Error message: {}", -                    e.getMessage()); -            throw new PersistenceException(e); -        } -    } - -    private static String GET_REGISTRATIONS = "SELECT * FROM Registration WHERE id = ? ;"; - -    private final PreparedStatement getRegistrations; +            Connection con = jdbcConnectionManager.getConnection(); +            try (PreparedStatement pstmt = con.prepareStatement(sql)) { +                pstmt.setLong(1, operationId); +                pstmt.execute(); -    private List<Registration> getRegistrations(long vehicleId) throws PersistenceException { -        List<Registration> registrations = new LinkedList<>(); -        try { -            getRegistrations.setLong(1, vehicleId); -            try (ResultSet resultSet = getRegistrations.executeQuery()) { -                while (resultSet.next()) { -                    long registrationId = resultSet.getLong("id"); -                    registrations.add( -                            Registration.builder() -                                    .id(registrationId) -                                    .start(resultSet.getTimestamp("start").toInstant()) -                                    .end(resultSet.getTimestamp("end").toInstant()) -                                    .employee(getEmployee(resultSet.getLong("employeeId"))) -                                    .build()); +                try (ResultSet rs = pstmt.getResultSet()) { +                    while (rs.next()) { +                        vehicles.add(vehicleDAO.get(rs.getLong("vehicleId"))); +                    }                  }              }          } catch (SQLException e) { -            LOG.error( -                    "SQLException occurred while getting Registration. Error message: {}", -                    e.getMessage());              throw new PersistenceException(e); +        } catch (ElementNotFoundException e) { +            throw new PersistenceException("VehicleOperation contained nonexistent vehicle", e);          } -        return registrations; -    } -    private static String GET_EMPLOYEE = "SELECT version FROM Employee WHERE id = ? ;"; - -    private final PreparedStatement getEmployee; - -    private Employee getEmployee(long employeeId) throws PersistenceException { -        try { -            getEmployee.setLong(1, employeeId); -            try (ResultSet resultSet = getEmployee.executeQuery()) { -                resultSet.next(); -                return getEmployeeVersion(employeeId, resultSet.getLong("version")); -            } -        } catch (SQLException e) { -            LOG.error( -                    "SQLException occurred while getting Employee. Error message: {}", -                    e.getMessage()); -            throw new PersistenceException(e); -        } -    } - -    private static String GET_EMPLOYEE_VERSION = "SELECT * FROM EmployeeVersion WHERE id = ? ;"; - -    private final PreparedStatement getEmployeeVersion; - -    private Employee getEmployeeVersion(long employeeId, long versionId) -            throws PersistenceException { -        try { -            getEmployeeVersion.setLong(1, versionId); -            try (ResultSet resultSet = getEmployeeVersion.executeQuery()) { -                resultSet.next(); -                return Employee.builder() -                        .id(employeeId) -                        .name(resultSet.getString("name")) -                        .birthday(resultSet.getDate("birthday").toLocalDate()) -                        .educationLevel( -                                EducationLevel.valueOf(resultSet.getString("educationLevel"))) -                        .isDriver(resultSet.getBoolean("isDriver")) -                        .isPilot(resultSet.getBoolean("isPilot")) -                        .build(); -            } -        } catch (SQLException e) { -            LOG.error( -                    "SQLException occurred while getting EmployeeVersion. Error message: {}", -                    e.getMessage()); -            throw new PersistenceException(e); -        } -    } - -    @Override -    public int connectVehicleToOperation(long vehicleID, long operationID) -            throws PersistenceException { -        PreparedStatement pstmt = null; -        try { -            pstmt = -                    jdbcConnectionManager -                            .getConnection() -                            .prepareStatement( -                                    "insert into VehicleOperation(vehicleId, operationId)" -                                            + "values (?,?)"); -            pstmt.setLong(1, vehicleID); -            pstmt.setLong(2, operationID); -            pstmt.executeUpdate(); -        } catch (SQLException e) { -            throw new PersistenceException("Die Werte konnten nicht gespeichert werden!"); -        } finally { -            if (pstmt != null) { -                try { -                    pstmt.close(); -                } catch (SQLException e) { -                    throw new PersistenceException( -                            "Verbindung zur Datenbank konnte nicht geschlossen werden!", e); -                } -            } -        } -        return 1; +        return vehicles;      }  } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAO.java index da90cc8..d82f768 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAO.java @@ -45,6 +45,4 @@ public interface OperationDAO {       * @throws PersistenceException if loading the stored operations failed       */      Set<Operation> list(EnumSet<Status> statuses) throws PersistenceException; - -    int connectVehicleToOperation(long vehicleID, long operationID) throws PersistenceException;  } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java index 74d6457..4663d76 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java @@ -26,10 +26,9 @@ import org.springframework.stereotype.Service;  @Service  public class OperationServiceImpl implements OperationService { -    // TODO: anders? -    private OperationDAO operationDAO;      private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); +    private final OperationDAO operationDAO;      private final VehicleDAO vehicleDAO;      public OperationServiceImpl(OperationDAO operationDAO, VehicleDAO vehicleDAO) { @@ -38,91 +37,30 @@ public class OperationServiceImpl implements OperationService {      }      @Override -    public long add(Operation operation) throws InvalidOperationException, ServiceException { -        Set<Vehicle> vehicles = operation.vehicles(); -        boolean rtw = false; -        if (faultyInput(operation.opCode())) { -            throw new InvalidOperationException("Code ist ungültig!"); -        } -        if (faultyInput(operation.destination())) { -            throw new InvalidOperationException("Adresse ist ungültig!"); -        } -        if (operation.vehicles().size() == 0) { -            throw new InvalidOperationException( -                    "Es muss mindestens ein Fahrzeug ausgewählt werden!"); -        } -        for (Vehicle vehicle : vehicles) { -            if (vehicle.status() == Vehicle.Status.ABGEMELDET -                    || (vehicle.status() != Vehicle.Status.FREI_FUNK -                            && vehicle.status() != Vehicle.Status.FREI_WACHE)) -                throw new InvalidOperationException( -                        "Abgemeldete Fahrzeuge dürfen nicht zu einem Einsatz geschickt werden!"); -            /*if (vehicle.type() == VehicleType.NEF && !rtw) { -                for (Vehicle vehicleA : vehicles) { -                    if (vehicleA.type() == VehicleType.RTW && vehicleA.hasNef()) { -                        rtw = true; -                        break; -                    } -                } -                if (!rtw) -                    throw new InvalidOperationException( -                            "Zu einem Fahrzeug des Typs NEF muss auch ein Fahrzeug des Typs RTW mit NEF-Halterung geschickt werden!"); -            }*/ -            /* if (vehicle.type() == VehicleType.NAH && !rtw) { -                for (Vehicle vehicleA : vehicles) { -                    if (vehicleA.type() == VehicleType.RTW) { -                        rtw = true; -                        break; -                    } -                } -                if (!rtw) -                    throw new InvalidOperationException( -                            "Zu einem Fahrzeug des Typs NAH muss auch ein Fahrzeug des Typs RTW geschickt werden!"); -            }*/ -        } -        String[] codeParts = operation.opCode().split("-"); -        String severity = ""; -        for (int i = 0; i < codeParts[1].length(); i++) { -            if (((int) (codeParts[1].charAt(i)) >= 65 && (int) (codeParts[1].charAt(i)) <= 79) -                    || ((int) (codeParts[1].charAt(i)) >= 97 -                            && (int) (codeParts[1].charAt(i)) <= 111)) { -                severity = "" + codeParts[1].charAt(i); -                break; -            } -        } -        try { -            operation = operation.toBuilder().severity(Severity.valueOf(severity)).build(); -        } catch (IllegalArgumentException e) { -            throw new InvalidOperationException( -                    "Der Schweregrad des Einsatzes konnte nicht ausgelesen werden!"); -        } -        operation = operation.toBuilder().status(Status.ACTIVE).build(); +    public long add(Operation o) throws InvalidOperationException, ServiceException { +        if (o.created() != null) throw new InvalidOperationException("Created must not be set"); -        long operationId; -        try { -            operationId = operationDAO.add(operation); -        } catch (PersistenceException e) { -            throw new ServiceException(e); -        } +        if (o.status() != Status.ACTIVE) +            LOG.warn("Status was set but will be overridden"); // TODO: nullable instead?? -        for (Vehicle vehicle : vehicles) { -            try { -                operationDAO.connectVehicleToOperation(vehicle.id(), operationId); -            } catch (PersistenceException e) { -                throw new ServiceException(e); +        try { +            for (long id : (Iterable<Long>) o.vehicles().stream().map(Vehicle::id)::iterator) { +                Vehicle v = vehicleDAO.get(id); +                VehicleServiceImpl.validateVehicle(v);              } -        } -        return operationId; -    } +            validateOperation(o); -    private boolean faultyInput(String name) { -        if (name == null) return true; -        else if (name.isEmpty()) return true; -        for (int i = 0; i < name.length(); i++) { -            if (name.charAt(i) != ' ') return false; +            return operationDAO.add( +                    o.toBuilder().created(Instant.now()).status(Status.ACTIVE).build()); +        } catch (PersistenceException e) { +            LOG.error("PersistenceException while adding operation: {}", e); +            throw new ServiceException(e); +        } catch (InvalidVehicleException e) { +            throw new InvalidOperationException("Enthaltenes Fahrzeug ist invalid", e); +        } catch (ElementNotFoundException e) { +            throw new InvalidOperationException("Enthaltenes Fahrzeug existiert nicht", e);          } -        return true;      }      @Override @@ -131,28 +69,29 @@ public class OperationServiceImpl implements OperationService {          Set<Vehicle> vs = new HashSet<>();          try { -            if (operationId <= 0) throw new InvalidOperationException("OperationId is invalid"); +            if (operationId <= 0) throw new InvalidOperationException("OperationId ist invalid");              Operation o = operationDAO.get(operationId);              validateOperation(o);              if (o.status() != Status.ACTIVE) -                throw new InvalidOperationException( -                        "Can't request vehicles for a nonactive operation"); +                throw new InvalidOperationException("Einsatz ist inaktiv"); -            if (!o.status().equals(Status.ACTIVE)) -                throw new InvalidOperationException("Can't add vehicles to a nonactive operation"); +            if (o.created() == null) +                throw new InvalidOperationException("Created darf nicht leer sein");              for (Long id : vehicleIds) { -                if (id <= 0) throw new InvalidVehicleException("VehicleId is invalid"); +                if (id <= 0) throw new InvalidVehicleException("VehicleId ist invalid");                  try {                      Vehicle v = vehicleDAO.get(id); +                    VehicleServiceImpl.validateVehicle(v);                      if (v.status() == Vehicle.Status.ABGEMELDET) -                        throw new InvalidVehicleException("Can't request nonactive vehicles"); +                        throw new InvalidVehicleException( +                                "Kann keine inaktiven Fahrzeuge anfordern");                      vs.add(v);                  } catch (ElementNotFoundException e) { -                    throw new InvalidVehicleException("VehicleId does not exist"); +                    throw new InvalidVehicleException("VehicleId ist invalid");                  }              } @@ -161,55 +100,23 @@ public class OperationServiceImpl implements OperationService {              operationDAO.update(o.toBuilder().vehicles(vs).build());          } catch (ElementNotFoundException e) { -            throw new InvalidOperationException("No such operationId exists"); +            throw new InvalidOperationException("Kein Einsatz mit dieser id existiert");          } catch (PersistenceException e) { +            LOG.error("PersistenceException while requesting vehicles: {}", e);              throw new ServiceException(e);          }      } -    private static final Pattern opCodePattern = Pattern.compile("(?:\\w{1,3}-\\d{0,2})(.)(?:.*)"); - -    private void validateOperation(Operation o) throws InvalidOperationException { -        if (o.id() <= 0) throw new InvalidOperationException("Id is invalid"); - -        if (o.opCode().trim().isEmpty()) throw new InvalidOperationException("opCode is invalid"); - -        Matcher m = opCodePattern.matcher(o.opCode()); -        if (!m.matches()) throw new InvalidOperationException("opCode is invalid"); - -        if (!m.group(1).equals(o.severity().toString())) -            throw new InvalidOperationException("Severity is invalid"); - -        if (o.vehicles().isEmpty()) -            throw new InvalidOperationException("No vehicles assigned to operation"); - -        Instant created = o.created(); -        if (created == null) throw new InvalidOperationException("Created can't be empty"); - -        if (created.isAfter(Instant.now())) -            throw new InvalidOperationException("Vehicle was created in the future"); - -        if (o.destination().trim().isEmpty()) -            throw new InvalidOperationException("Destination can't be empty"); -    } -      @Override      public void complete(long operationId, Status status)              throws InvalidOperationException, ServiceException { -        Operation operation; -        try { -            operation = operationDAO.get(operationId); -        } catch (ElementNotFoundException e) { -            throw new InvalidOperationException(e); -        } catch (PersistenceException e) { -            throw new ServiceException(e); -        } -        operation = operation.toBuilder().status(status).build();          try { -            operationDAO.update(operation); +            Operation o = operationDAO.get(operationId); +            operationDAO.update(o.toBuilder().status(status).build());          } catch (ElementNotFoundException e) {              throw new InvalidOperationException(e);          } catch (PersistenceException e) { +            LOG.error("PersistenceException while completing operation: {}", e);              throw new ServiceException(e);          }      } @@ -217,18 +124,68 @@ public class OperationServiceImpl implements OperationService {      @Override      public SortedSet<Vehicle> rankVehicles(long operationId)              throws InvalidOperationException, ServiceException { -        return null; +        throw new UnsupportedOperationException();      }      @Override      public Set<Operation> list(EnumSet<Status> statuses) throws ServiceException {          try { -            return operationDAO.list(statuses); +            Set<Operation> operations = operationDAO.list(statuses); +            for (Operation o : operations) validateOperation(o); + +            return operations;          } catch (PersistenceException e) { -            LOG.debug( -                    "Caught PersistenceException. Throwing ServiceException. Message: {}", -                    e.getMessage()); +            LOG.error("PersistenceException while listing operations", e);              throw new ServiceException(e); +        } catch (InvalidOperationException e) { +            // database returned invalid values +            LOG.error("DB returned invalid operation: {}", e); +            throw new ServiceException("DB returned invalid operation", e);          }      } + +    private static void validateOperation(Operation o) throws InvalidOperationException { +        if (o.id() <= 0) throw new InvalidOperationException("Id is invalid"); + +        if (o.opCode().trim().isEmpty()) throw new InvalidOperationException("opCode is invalid"); + +        if (extractSeverityFromOpCode(o.opCode()) != o.severity()) +            throw new InvalidOperationException("Einsatzcode ist invalid"); + +        if (o.vehicles().isEmpty()) +            throw new InvalidOperationException( +                    "Es muss mindestens ein Fahrzeug ausgewählt werden!"); + +        for (Vehicle v : o.vehicles()) { +            try { +                VehicleServiceImpl.validateVehicle(v); +            } catch (InvalidVehicleException e) { +                throw new InvalidOperationException("Fahrzeug " + v.name() + " ist invalid" + e); +            } + +            if (v.status() != Vehicle.Status.FREI_FUNK && v.status() != Vehicle.Status.FREI_WACHE) +                throw new InvalidOperationException( +                        "Fahrzeug nicht verfügbar (" + v.status() + ")"); + +            // TODO: validate if NEF/RTW/NAH conditions? +        } + +        Instant created = o.created(); +        if (created != null && created.isAfter(Instant.now())) +            throw new InvalidOperationException("Fahrzeug wurde in der Zukunft erstellt"); + +        if (o.destination().trim().isEmpty()) +            throw new InvalidOperationException("Adresse darf nicht leer sein"); +    } + +    private static final Pattern opCodePattern = Pattern.compile("(?:\\w{1,3}-\\d{0,2})(.)(?:.*)"); + +    private static Severity extractSeverityFromOpCode(String opCode) +            throws InvalidOperationException { +        Matcher m = opCodePattern.matcher(opCode); + +        if (!m.matches()) throw new InvalidOperationException("Einsatzcode ist invalid"); + +        return Severity.valueOf(m.group(1)); +    }  } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java index da995c4..8b317ce 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java @@ -12,6 +12,7 @@ import java.util.EnumSet;  import java.util.Set;  import java.util.stream.Collectors;  import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils;  @Service  public class VehicleServiceImpl implements VehicleService { @@ -23,6 +24,8 @@ public class VehicleServiceImpl implements VehicleService {      }      public long add(Vehicle vehicle) throws InvalidVehicleException, ServiceException { +        if (CollectionUtils.isEmpty(vehicle.registrations())) +            throw new InvalidVehicleException("Vehicle can't be created with registrations");          validateVehicle(vehicle);          try { @@ -45,7 +48,7 @@ public class VehicleServiceImpl implements VehicleService {          return vehicle;      } -    private void validateVehicle(Vehicle vehicle) throws InvalidVehicleException, ServiceException { +    protected static void validateVehicle(Vehicle vehicle) throws InvalidVehicleException {          switch (vehicle.type()) {              case RTW:                  if (vehicle.constructionType() == ConstructionType.NORMAL) { @@ -81,7 +84,7 @@ public class VehicleServiceImpl implements VehicleService {              case BKTW:                  break;              default: -                throw new ServiceException("not a Valid type"); +                throw new IllegalStateException("BUG: invalid vehicle type" + vehicle.type());          }      }  | 
