diff options
author | Tharre <tharre3@gmail.com> | 2018-05-24 02:43:44 +0200 |
---|---|---|
committer | Tharre <tharre3@gmail.com> | 2018-05-24 03:28:26 +0200 |
commit | 5f74bbf608b2a2159841f892e0334fd238216600 (patch) | |
tree | 238776a0409125fad58d699751a305faccd29f91 /src/main | |
parent | c16fd1d735698f2fbab7ffaf2557058107e5997f (diff) | |
download | sepm-groupproject-5f74bbf608b2a2159841f892e0334fd238216600.tar.gz sepm-groupproject-5f74bbf608b2a2159841f892e0334fd238216600.tar.xz sepm-groupproject-5f74bbf608b2a2159841f892e0334fd238216600.zip |
Fix and cleanup Operation dao+service #25963
Diffstat (limited to 'src/main')
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); + public DBOperationDAO(JDBCConnectionManager jdbcConnectionManager, VehicleDAO vehicleDAO) { + this.jdbcConnectionManager = jdbcConnectionManager; + this.vehicleDAO = vehicleDAO; + } - getEmployee = jdbcConnectionManager.getConnection().prepareStatement(GET_EMPLOYEE); + @Override + 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; - getEmployeeVersion = - jdbcConnectionManager.getConnection().prepareStatement(GET_EMPLOYEE_VERSION); + try { + 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(); - } catch (SQLException e) { + try (ResultSet rs = pstmt.getGeneratedKeys()) { + if (!rs.next()) throw new PersistenceException("Failed to persist operation"); - LOG.error( - "SQLException occurred while preparing Statements. Error message: {} ", - e.getMessage()); + operationId = rs.getLong(1); + } + } - // TODO: nothing should be thrown here - throw new IllegalStateException("TODO: fix me"); - // throw new PersistenceException(e); - } - } + try (PreparedStatement pstmt = con.prepareStatement(sql2)) { + pstmt.setLong(2, operationId); - @Override - public long add(Operation operation) throws PersistenceException { - if (operation == null) { - throw new PersistenceException("Das der Datenbank übergebene Objekt ist fehlerhaft!"); - } - PreparedStatement pstmt = null; - try { - pstmt = - jdbcConnectionManager - .getConnection() - .prepareStatement( - "INSERT INTO operation(opCode, severity, " - + "created, destination, additionalInfo, status) values (?,?,?,?,?,?)", - java.sql.Statement.RETURN_GENERATED_KEYS); - - 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!"); - } + for (long id : (Iterable<Long>) o.vehicles().stream().map(Vehicle::id)::iterator) { + pstmt.setLong(1, id); + pstmt.addBatch(); + } - 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()); - } - 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()); + 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); - } - 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); + } catch (ElementNotFoundException e) { + throw new PersistenceException("VehicleOperation contained nonexistent vehicle", 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()); } } |