From 9ca5b384b4143529a3c9bc80bff39dab635aee1c Mon Sep 17 00:00:00 2001
From: Tharre <tharre3@gmail.com>
Date: Sat, 12 May 2018 00:00:59 +0200
Subject: Implement requestVehicles() in service+DAO #25953

---
 .../einsatzverwaltung/dao/DBOperationDAO.java      | 46 ++++++++++++-
 .../service/OperationServiceImpl.java              | 79 +++++++++++++++++++++-
 2 files changed, 121 insertions(+), 4 deletions(-)

(limited to 'src/main')

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 476f968..68185d6 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
@@ -2,9 +2,11 @@ package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao;
 
 import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation;
 import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status;
+import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle;
 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.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -112,7 +114,49 @@ public class DBOperationDAO implements OperationDAO {
     }
 
     @Override
-    public void update(Operation operation) throws ElementNotFoundException, PersistenceException {}
+    public void update(Operation o) throws ElementNotFoundException, PersistenceException {
+        String sql =
+                "UPDATE Operation SET opCode = ?, severity = ?, destination = ?,"
+                        + " additionalInfo = ?, status = ? WHERE id = ?";
+        String sql2 = "DELETE FROM VehicleOperation WHERE operationId = ?";
+        String sql3 = "INSERT INTO VehicleOperation(vehicleId, operationId) VALUES (?, ?)";
+
+        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.setString(3, o.destination());
+                pstmt.setString(4, o.additionalInfo());
+                pstmt.setInt(5, o.status().ordinal());
+                pstmt.setLong(6, o.id());
+
+                if (pstmt.executeUpdate() != 1)
+                    throw new ElementNotFoundException("No such operationId exists: " + pstmt);
+            }
+
+            try (PreparedStatement pstmt = con.prepareStatement(sql2)) {
+                pstmt.setLong(1, o.id());
+                pstmt.executeUpdate();
+            }
+
+            try (PreparedStatement pstmt = con.prepareStatement(sql3)) {
+                pstmt.setLong(2, o.id());
+
+                for (long id : (Iterable<Long>) o.vehicles().stream().map(Vehicle::id)::iterator) {
+                    pstmt.setLong(1, id);
+                    pstmt.addBatch();
+                }
+
+                pstmt.executeBatch();
+            }
+            con.commit();
+            con.setAutoCommit(true);
+        } catch (SQLException e) {
+            throw new PersistenceException(e);
+        }
+    }
 
     @Override
     public Operation get(long operationId) throws ElementNotFoundException, 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 a6be111..ba4eb7f 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
@@ -1,17 +1,23 @@
 package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service;
 
 import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.OperationDAO;
+import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.VehicleDAO;
 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.Vehicle;
+import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException;
 import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException;
 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.time.Instant;
 import java.util.EnumSet;
+import java.util.HashSet;
 import java.util.Set;
 import java.util.SortedSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import org.springframework.stereotype.Service;
 
 @Service
@@ -20,8 +26,11 @@ public class OperationServiceImpl implements OperationService {
     // TODO: anders?
     private OperationDAO operationDAO;
 
-    public OperationServiceImpl(OperationDAO dao) {
-        this.operationDAO = dao;
+    private final VehicleDAO vehicleDAO;
+
+    public OperationServiceImpl(OperationDAO operationDAO, VehicleDAO vehicleDAO) {
+        this.operationDAO = operationDAO;
+        this.vehicleDAO = vehicleDAO;
     }
 
     @Override
@@ -114,7 +123,71 @@ public class OperationServiceImpl implements OperationService {
 
     @Override
     public void requestVehicles(long operationId, Set<Long> vehicleIds)
-            throws InvalidOperationException, InvalidVehicleException, ServiceException {}
+            throws InvalidOperationException, InvalidVehicleException, ServiceException {
+        Set<Vehicle> vs = new HashSet<>();
+
+        try {
+            if (operationId <= 0) throw new InvalidOperationException("OperationId is invalid");
+            Operation o = operationDAO.get(operationId);
+            validateOperation(o);
+
+            if (o.status() != Status.ACTIVE)
+                throw new InvalidOperationException(
+                        "Can't request vehicles for a nonactive operation");
+
+            if (!o.status().equals(Status.ACTIVE))
+                throw new InvalidOperationException("Can't add vehicles to a nonactive operation");
+
+            for (Long id : vehicleIds) {
+                if (id <= 0) throw new InvalidVehicleException("VehicleId is invalid");
+
+                try {
+                    Vehicle v = vehicleDAO.get(id);
+                    if (v.status() == Vehicle.Status.ABGEMELDET)
+                        throw new InvalidVehicleException("Can't request nonactive vehicles");
+
+                    vs.add(v);
+                } catch (ElementNotFoundException e) {
+                    throw new InvalidVehicleException("VehicleId does not exist");
+                }
+            }
+
+            vs.addAll(o.vehicles());
+            if (vs.equals(o.vehicles())) return;
+
+            operationDAO.update(o.toBuilder().vehicles(vs).build());
+        } catch (ElementNotFoundException e) {
+            throw new InvalidOperationException("No such operationId exists");
+        } catch (PersistenceException 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)
-- 
cgit v1.2.3-70-g09d2