From 17556e5701442e9c2a7e219c5d93734812344ebe Mon Sep 17 00:00:00 2001 From: Dominic Rogetzer Date: Mon, 18 Jun 2018 20:13:05 +0200 Subject: Rename 'einsatzverwaltung' to 'missioncontrol' + remove TODO [#25963] --- .../controller/ArchiveOperationController.java | 213 ++++++++++++ .../controller/CreateCarController.java | 231 +++++++++++++ .../controller/CreateNewEmployeeController.java | 174 ++++++++++ .../controller/CreateOperationController.java | 371 +++++++++++++++++++++ .../controller/CustomListItemController.java | 24 ++ .../DetailArchiveOperationController.java | 77 +++++ .../controller/EmployeeListController.java | 133 ++++++++ .../controller/EmployeeListItemController.java | 87 +++++ .../controller/FilterEmployeesController.java | 65 ++++ .../missioncontrol/controller/Helper.java | 34 ++ .../controller/ManageEmployeesController.java | 120 +++++++ .../controller/OperationDetailsController.java | 169 ++++++++++ .../controller/OperationInArchiveController.java | 65 ++++ .../controller/RegistrationWindowController.java | 279 ++++++++++++++++ .../controller/VehiclePaneController.java | 118 +++++++ .../groupphase/missioncontrol/dao/EmployeeDAO.java | 44 +++ .../missioncontrol/dao/EmployeeDatabaseDAO.java | 144 ++++++++ .../missioncontrol/dao/OperationDAO.java | 48 +++ .../missioncontrol/dao/OperationDatabaseDAO.java | 221 ++++++++++++ .../missioncontrol/dao/RegistrationDAO.java | 28 ++ .../dao/RegistrationDatabaseDAO.java | 130 ++++++++ .../groupphase/missioncontrol/dao/VehicleDAO.java | 54 +++ .../missioncontrol/dao/VehicleDatabaseDAO.java | 211 ++++++++++++ .../groupphase/missioncontrol/dto/Employee.java | 51 +++ .../missioncontrol/dto/EmployeeValidator.java | 23 ++ .../groupphase/missioncontrol/dto/Operation.java | 70 ++++ .../missioncontrol/dto/Registration.java | 34 ++ .../missioncontrol/dto/RegistrationValidator.java | 174 ++++++++++ .../groupphase/missioncontrol/dto/Vehicle.java | 73 ++++ .../missioncontrol/service/EmployeeService.java | 46 +++ .../service/EmployeeServiceImpl.java | 59 ++++ .../missioncontrol/service/OperationService.java | 70 ++++ .../service/OperationServiceImpl.java | 286 ++++++++++++++++ .../service/RegistrationService.java | 32 ++ .../service/RegistrationServiceImpl.java | 52 +++ .../missioncontrol/service/VehicleService.java | 49 +++ .../missioncontrol/service/VehicleServiceImpl.java | 116 +++++++ 37 files changed, 4175 insertions(+) create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CustomListItemController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/DetailArchiveOperationController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListItemController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/FilterEmployeesController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/Helper.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ManageEmployeesController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationInArchiveController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/VehiclePaneController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAO.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDatabaseDAO.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAO.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAO.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAO.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Employee.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/EmployeeValidator.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Operation.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Registration.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/RegistrationValidator.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Vehicle.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeService.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceImpl.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationService.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceImpl.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationService.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleService.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleServiceImpl.java (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java new file mode 100644 index 0000000..6e0c89d --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java @@ -0,0 +1,213 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.OperationService; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.Arrays; +import java.util.Collection; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.FlowPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class ArchiveOperationController { + + private static final Logger LOG = LoggerFactory.getLogger(ArchiveOperationController.class); + + @FXML private ImageView imvVehicleDetail; + @FXML private Label lblStatus; + @FXML private AnchorPane apMainDetails; + @FXML private Label lblOperations; + @FXML private Label lblCompleted; + @FXML private Label lblCancelled; + @FXML private AnchorPane backApMain; + @FXML private AnchorPane backApDetails; + @FXML private AnchorPane archiveOperationAP; + @FXML private AnchorPane apDetails; + @FXML private Label lblCodeHeader; + @FXML private Label lblOpCode; + @FXML private Label lblVehicles; + @FXML private Label lblDate; + @FXML private Label lblAddress; + @FXML private FlowPane fpVehicles; + private final OperationService operationService; + @FXML private FlowPane archiveOperationFlowPane; + private final CreateOperationController createOperationController; + private Set list = new HashSet<>(); + private final SpringFXMLLoader fxmlLoader; + + public ArchiveOperationController( + OperationService operationService, + CreateOperationController createOperationController, + SpringFXMLLoader fxmlLoader) { + this.operationService = operationService; + this.createOperationController = createOperationController; + this.fxmlLoader = fxmlLoader; + } + + @FXML + private void initialize() { + update(); + } + + public void update() { + archiveOperationFlowPane.getChildren().clear(); + list.clear(); + try { + list.addAll(operationService.list(EnumSet.of(Status.CANCELLED, Status.COMPLETED))); + long cancelledAmount = 0; + long completedAmount = 0; + for (Operation operation : list) { + if (operation.status() == Status.CANCELLED) cancelledAmount++; + else completedAmount++; + } + lblCancelled.setText("storniert: " + cancelledAmount); + lblCompleted.setText("abgeschlossen: " + completedAmount); + lblOperations.setText("Einsätze: " + list.size()); + } catch (ServiceException e) { + LOG.error("ServiceException in update().", e); + showServiceExceptionAlertAndWait("Die Einsätze konnten nicht geladen werden!"); + ; + } + setFlowPane(); + } + + private void setFlowPane() { + try { + archiveOperationFlowPane.getChildren().clear(); + for (Operation operation : sortSet(list)) { + OperationInArchiveController opInAController = + OperationInArchiveController.create(); + opInAController.set(operation); + opInAController + .getRoot() + .setOnMouseClicked( + event -> { + detailOperation = operation; + backApMain.setVisible(false); + apMainDetails.setVisible(false); + backApDetails.setVisible(true); + setOperation(); + setDetailsVisible(true); + imvVehicleDetail.setImage(new Image("/images/Vehicle.png")); + }); + archiveOperationFlowPane.getChildren().add(opInAController.getRoot()); + } + } catch (IOException e) { + LOG.error("IOException in setFlowPane(). ", e); + showServiceExceptionAlertAndWait("Die Elemente konnten nicht geladen werden!"); + } + } + + private Operation detailOperation; + + private List sortSet(Set operationsSet) { + Operation[] array = operationsSet.toArray(new Operation[operationsSet.size()]); + for (int i = array.length - 1; i > 0; i--) { + for (int j = 0; j < i; j++) { + LocalDateTime first = + LocalDateTime.ofInstant( + Objects.requireNonNull(array[j].created()), ZoneOffset.UTC); + LocalDateTime second = + LocalDateTime.ofInstant( + Objects.requireNonNull(array[j + 1].created()), ZoneOffset.UTC); + if (first.isBefore(second)) { + Operation help = array[j]; + array[j] = array[j + 1]; + array[j + 1] = help; + } + } + } + return Arrays.asList(array); + } + + private void setOperation() { + lblCodeHeader.setText(detailOperation.opCode()); + if (detailOperation.created() != null) { + LocalDateTime dateTime = + LocalDateTime.ofInstant( + Objects.requireNonNull(detailOperation.created()), ZoneOffset.UTC); + lblDate.setText( + "am " + + dateTime.getDayOfMonth() + + "." + + dateTime.getMonth().getValue() + + "." + + dateTime.getYear()); + } else { + lblDate.setText("---"); + } + lblStatus.setText( + "Status: " + + (detailOperation.status() == Status.CANCELLED + ? "storniert" + : "abgeschlossen")); + lblOpCode.setText(detailOperation.opCode()); + Collection elements = + detailOperation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList()); + String result = String.join(", ", elements); + + lblVehicles.setText(result); + lblAddress.setText(detailOperation.destination()); + + fpVehicles.getChildren().clear(); + try { + for (Vehicle vehicle : detailOperation.vehicles()) { + DetailArchiveOperationController controller = null; + + controller = DetailArchiveOperationController.create(fxmlLoader); + + controller.set(vehicle); + fpVehicles.getChildren().add(controller.getRoot()); + } + } catch (IOException e) { + LOG.error("IOException in setOperation(). ", e); + showServiceExceptionAlertAndWait("Die Element konnte nicht geladen werden!"); + } + } + + private void setDetailsVisible(boolean b) { + apDetails.setVisible(b); + } + + public void backClicked() { + LOG.debug("Hyperlink \"Zurück\" in archive detail view clicked."); + fpVehicles.getChildren().clear(); + setDetailsVisible(false); + backApDetails.setVisible(false); + apMainDetails.setVisible(true); + backApMain.setVisible(true); + } + + public void backToMain() { + LOG.debug("Hyperlink \"Zurück\" in archive main view clicked."); + this.setVisible(false); + createOperationController.setVisible(true); + } + + void setVisible(boolean b) { + archiveOperationAP.setVisible(b); + backApMain.setVisible(b); + apMainDetails.setVisible(b); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java new file mode 100644 index 0000000..aa76535 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java @@ -0,0 +1,231 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showSuccessAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.io.IOException; +import java.util.EnumSet; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javafx.collections.FXCollections; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ChoiceBox; +import javafx.scene.input.MouseButton; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.FlowPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class CreateCarController { + + @FXML private AnchorPane createCarAP; + @FXML private ChoiceBox cmbCtype; + @FXML private ChoiceBox cmbTyp; + + @FXML private Button btnCreate; + @FXML private CheckBox cbxNEF; + @FXML private FlowPane fpVehicleList; + private final CreateOperationController createOperationController; + + private static final Logger LOG = LoggerFactory.getLogger(CreateCarController.class); + private final VehicleService vehicleService; + private boolean update = false; + private long vid = -1; + + private Vehicle chooseVehicle; + + public CreateCarController( + CreateOperationController createOperationController, VehicleService vehicleService) { + this.createOperationController = createOperationController; + this.vehicleService = vehicleService; + } + + @FXML + private void initialize() { + fpVehicleList.setHgap(5); + fpVehicleList.setVgap(5); + + cmbCtype.setItems( + FXCollections.observableArrayList( + Stream.of( + ConstructionType.NORMAL, + ConstructionType.MITTELHOCHDACH, + ConstructionType.HOCHDACH) + .map(Enum::toString) + .collect(Collectors.toList()))); + cmbCtype.setValue(ConstructionType.NORMAL.toString()); + cmbTyp.setItems( + FXCollections.observableArrayList( + Stream.of( + VehicleType.BKTW, + VehicleType.KTW_B, + VehicleType.KTW, + VehicleType.RTW, + VehicleType.NEF, + VehicleType.NAH) + .map(Enum::toString) + .collect(Collectors.toList()))); + cmbTyp.setValue(VehicleType.BKTW.toString()); + + updateVehiclePane(); + } + + @FXML + private void createCar(ActionEvent actionEvent) { + + if (!update) { + LOG.debug("Button \"Erstellen\" clicked."); + Vehicle vehicle = + Vehicle.builder() + .constructionType(parseConstructionType()) + .type(parseType()) + .name("") + .status(Status.ABGEMELDET) + .hasNef(cbxNEF.isSelected()) + .build(); + try { + vehicleService.add(vehicle); + setToStart(); + } catch (InvalidVehicleException e) { + LOG.debug("Validation of Vehicle failed"); + showValidationErrorAlertAndWait(e.getMessage()); + setToStart(); + return; + } catch (ServiceException e) { + LOG.error("ServiceException in createCar(). ", e); + showServiceExceptionAlertAndWait( + "Ein Fehler beim Erstellen des Fahrzeuges ist aufgetreten."); + setToStart(); + return; + } + showSuccessAlertAndWait("Auto wurde erfolgreich angelegt."); + } else { + LOG.debug("Button \"Speichern\" clicked."); + try { + Vehicle vehicle = + Vehicle.builder() + .id(vid) + .constructionType(parseConstructionType()) + .type(parseType()) + .name("") + .status(Status.ABGEMELDET) + .hasNef(cbxNEF.isSelected()) + .build(); + vehicleService.update(vehicle); + setToStart(); + chooseVehicle = null; + } catch (InvalidVehicleException e) { + LOG.debug("Validation of Vehicle failed"); + showValidationErrorAlertAndWait(e.getMessage()); + setToStart(); + return; + } catch (ServiceException e) { + LOG.error("ServiceException in createCar(). ", e); + showServiceExceptionAlertAndWait(e.getMessage()); + setToStart(); + return; + } + showSuccessAlertAndWait("Auto wurde erfolgreich bearbeitet."); + } + + updateVehiclePane(); + } + + private ConstructionType parseConstructionType() { + if (cmbCtype.getSelectionModel().getSelectedItem() == null) { + return ConstructionType.NORMAL; + } + return ConstructionType.valueOf(cmbCtype.getSelectionModel().getSelectedItem()); + } + + private VehicleType parseType() { + if (cmbTyp.getSelectionModel().getSelectedItem() == null) { + return VehicleType.BKTW; + } + return VehicleType.valueOf(cmbTyp.getSelectionModel().getSelectedItem()); + } + + private void setToStart() { + btnCreate.setText("Erstellen"); + cbxNEF.setSelected(false); + cmbTyp.setValue(VehicleType.BKTW.name()); + cmbCtype.setValue(ConstructionType.NORMAL.name()); + update = false; + } + + private void updateVehicle(Vehicle vehicle) { + + cmbCtype.setValue(vehicle.constructionType().name()); + cmbTyp.setValue(vehicle.type().name()); + cbxNEF.setSelected(vehicle.hasNef()); + btnCreate.setText("Speichern"); + vid = vehicle.id(); + update = true; + chooseVehicle = vehicle; + } + + public void setVisible(boolean b) { + createCarAP.setVisible(b); + } + + @FXML + private void backToMain() { + LOG.debug("Hyperlink \"zurück\" clicked."); + this.setVisible(false); + createOperationController.setVisible(true); + } + + private void updateVehiclePane() { + try { + fpVehicleList.getChildren().clear(); + + Set vehicles; + + vehicles = vehicleService.list(EnumSet.of(Status.ABGEMELDET)); + + for (Vehicle vehicle : vehicles) { + VehiclePaneController controller = VehiclePaneController.createVehiclePane(); + + controller.setData(vehicle, false, false); + controller + .getRootElement() + .setOnMouseClicked( + event -> { + if (event.getButton().equals(MouseButton.PRIMARY)) { + if (chooseVehicle == null || vehicle == chooseVehicle) { + if (update == false) { + chooseVehicle = vehicle; + updateVehicle(vehicle); + controller.setSelected(true); + } else { + setToStart(); + controller.setSelected(false); + + chooseVehicle = null; + } + } + } + }); + + fpVehicleList.getChildren().add(controller.getRootElement()); + } + } catch (ServiceException | IOException e) { + LOG.error("Exception in updateVehiclePane(). ", e); + showServiceExceptionAlertAndWait(e.getMessage()); + } + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeController.java new file mode 100644 index 0000000..433bfa6 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeController.java @@ -0,0 +1,174 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showSuccessAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.EmployeeService; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; +import java.io.IOException; +import java.time.LocalDate; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javafx.collections.FXCollections; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ChoiceBox; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Controller; + +@Controller +@Scope("prototype") +public class CreateNewEmployeeController { + + private static final Logger LOG = LoggerFactory.getLogger(CreateNewEmployeeController.class); + private final EmployeeService employeeService; + + @FXML private Label lblHeader; + @FXML private CheckBox inputIsDriver; + @FXML private CheckBox inputIsPilot; + @FXML private TextField inputName; + @FXML private ChoiceBox inputQualification; + @FXML private Button btnCreate; + + private Node rootElement; + private Employee employee; + private boolean isEdit; + + private Runnable consumerCancelClicked; + private Runnable consumerCreateClicked; + + public CreateNewEmployeeController(EmployeeService employeeService) { + this.employeeService = employeeService; + } + + @FXML + private void initialize() { + inputQualification.setItems( + FXCollections.observableArrayList( + Stream.of( + EducationLevel.RS, + EducationLevel.NFS, + EducationLevel.NKV, + EducationLevel.NKA, + EducationLevel.NKI, + EducationLevel.NA) + .map(Enum::toString) + .collect(Collectors.toList()))); + + inputQualification.setValue(EducationLevel.RS.toString()); + employee = + Employee.builder() + .name("") + .educationLevel(EducationLevel.RS) + .isDriver(false) + .isPilot(false) + .birthday(LocalDate.MIN) + .build(); + } + + @FXML + private void onCancelClicked() { + LOG.debug("Hyperlink \"abbrechen\" clicked."); + if (consumerCancelClicked != null) { + consumerCancelClicked.run(); + } + } + + @FXML + private void onCreateClicked() { + LOG.debug("Button {} clicked.", btnCreate.getText()); + + employee = + employee.toBuilder() + .name(inputName.getText()) + .educationLevel(parseEducationLevel()) + .birthday(LocalDate.MIN) // TODO: change UI to include birthday field + .isDriver(inputIsDriver.isSelected()) + .isPilot(inputIsPilot.isSelected()) + .build(); + + try { + if (isEdit) { + employeeService.update(employee); + } else { + employeeService.add(employee); + } + } catch (InvalidEmployeeException e) { + LOG.debug("Validation for Employee failed"); + showValidationErrorAlertAndWait(e.getMessage()); + return; + } catch (ServiceException e) { + LOG.error("ServiceException in onCreateClicked(). ", e); + showServiceExceptionAlertAndWait( + "Der Eintrag konnte nicht gespeichert werden. Bitte versuchen Sie es erneut."); + return; + } + + showSuccessAlertAndWait( + "Der/die MitarbeiterIn wurde erfolgreich angelegt und gespeichert!"); + + if (consumerCreateClicked != null) { + consumerCreateClicked.run(); + } + } + + private EducationLevel parseEducationLevel() { + if (inputQualification.getSelectionModel().getSelectedItem() == null) { + return EducationLevel.RS; + } + return EducationLevel.valueOf(inputQualification.getSelectionModel().getSelectedItem()); + } + + private void setData(Employee employee) { + isEdit = true; + this.employee = employee; + inputName.setText(employee.name()); + inputQualification.setValue(employee.educationLevel().name()); + inputIsDriver.setSelected(employee.isDriver()); + inputIsPilot.setSelected(employee.isPilot()); + lblHeader.setText("Person bearbeiten"); + btnCreate.setText("Speichern"); + } + + public static CreateNewEmployeeController createCreateNewEmployeeController( + SpringFXMLLoader fxmlLoader, Employee employee) throws IOException { + CreateNewEmployeeController controller = createCreateNewEmployeeController(fxmlLoader); + controller.setData(employee); + return controller; + } + + public static CreateNewEmployeeController createCreateNewEmployeeController( + SpringFXMLLoader fxmlLoader) throws IOException { + FXMLWrapper wrapper = + fxmlLoader.loadAndWrap( + "/fxml/createNewEmployee.fxml", CreateNewEmployeeController.class); + Node root = (Node) wrapper.getLoadedObject(); + CreateNewEmployeeController controller = wrapper.getController(); + controller.rootElement = root; + return controller; + } + + public Node getRootElement() { + return rootElement; + } + + public void setConsumerCancelClicked(Runnable consumerCancelClicked) { + this.consumerCancelClicked = consumerCancelClicked; + } + + public void setConsumerCreateClicked(Runnable consumerCreateClicked) { + this.consumerCreateClicked = consumerCreateClicked; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java new file mode 100644 index 0000000..b237265 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java @@ -0,0 +1,371 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showSuccessAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.OperationService; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; +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.ServiceException; +import java.io.IOException; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import javafx.collections.FXCollections; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.ContextMenu; +import javafx.scene.control.Label; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.control.MenuItem; +import javafx.scene.control.TextField; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; +import javafx.scene.input.MouseButton; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.FlowPane; +import javafx.scene.layout.GridPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class CreateOperationController { + + private static final Logger LOG = LoggerFactory.getLogger(CreateOperationController.class); + + public AnchorPane apCreateOperation; + @FXML private GridPane grdWindowContainer; + @FXML private TextField txtCode; + @FXML private TextField txtAddress; + @FXML private TextField txtNote; + @FXML private Button btnCreateOperation; + @FXML private ListView lvVehicles; + @FXML private ListView lvActiveOperations; + @FXML private Label lblChosenVehicles; + @FXML private AnchorPane apInvisible; + @FXML private OperationDetailsController operationDetailsController; + @FXML private ManageEmployeesController manageEmployeesController; + @FXML private CreateCarController createCarController; + @FXML private RegistrationWindowController registrationWindowController; + @FXML private ArchiveOperationController archiveOperationController; + @FXML private FlowPane fpVehicles; + + private LinkedList chosenVehicles = new LinkedList<>(); + + private final OperationService operationService; + private final VehicleService vehicleService; + + public CreateOperationController( + OperationService operationService, VehicleService vehicleService) { + this.operationService = operationService; + this.vehicleService = vehicleService; + } + + @FXML + private void initialize() { + + lblChosenVehicles.setText("keine ausgewählt"); + lvActiveOperations.setCellFactory(param -> generateOpCodeListItem()); + + lvActiveOperations.setOnMouseClicked( + event -> { + if (event.getClickCount() == 2) { + if (lvActiveOperations.getSelectionModel().getSelectedItem() == null) { + return; + } + openDetailsWindow(lvActiveOperations.getSelectionModel().getSelectedItem()); + } + }); + + setVisible(true); + createCarController.setVisible(false); + registrationWindowController.setVisible(false); + } + + public void updateList() { + try { + fpVehicles.getChildren().clear(); + + // TODO: this should probably be handled differently + Set vehicles; + if (txtCode.getText().isEmpty()) { + vehicles = + vehicleService.list( + EnumSet.complementOf(EnumSet.of(Vehicle.Status.ABGEMELDET))); + } else { + vehicles = operationService.rankVehicles(txtCode.getText()); + } + + for (Vehicle vehicle : vehicles) { + VehiclePaneController controller = VehiclePaneController.createVehiclePane(); + + controller.setData(vehicle, true, false); + controller + .getRootElement() + .setOnMouseClicked( + event -> { + if (event.getButton().equals(MouseButton.SECONDARY)) { + createContextMenu(vehicle, vehicleService) + .show( + controller.getRootElement(), + event.getScreenX(), + event.getScreenY()); + } else { + if (chosenVehicles.contains(vehicle)) { + chosenVehicles.remove(vehicle); + controller.setSelected(false); + } else { + chosenVehicles.add(vehicle); + controller.setSelected(true); + } + + StringBuilder result = new StringBuilder(); + for (int i = 0; i < chosenVehicles.size(); i++) { + if (i == chosenVehicles.size() - 1) { + result.append(chosenVehicles.get(i).name()); + } else { + result.append(chosenVehicles.get(i).name()) + .append(", "); + } + } + if (result.toString().equals("")) { + lblChosenVehicles.setText("keine ausgewählt"); + } else { + lblChosenVehicles.setText(result.toString()); + } + } + }); + + if (chosenVehicles.stream().anyMatch(v -> v.id() == vehicle.id())) + controller.setSelected(true); + + fpVehicles.getChildren().add(controller.getRootElement()); + } + } catch (ServiceException | IOException e) { + LOG.error("Exception in updateList(). ", e); + showServiceExceptionAlertAndWait( + "Beim Erstellen des Ranking ist ein Fehler aufgetreten."); + } catch (InvalidOperationException e) { + LOG.debug("Validation error in updateList(). ", e); + showValidationErrorAlertAndWait(e.getMessage()); + } + try { + lvActiveOperations.setItems( + FXCollections.observableArrayList( + operationService.list(EnumSet.of(Status.ACTIVE)))); + } catch (ServiceException e) { + LOG.error("ServiceException in updateList(). ", e); + showServiceExceptionAlertAndWait( + "Beim Holen der aktiven Einsätze ist ein Fehler aufgetreten"); + } + } + + private ContextMenu createContextMenu(Vehicle data, VehicleService vehicleService) { + ContextMenu menu = new ContextMenu(); + + for (Vehicle.Status status : Vehicle.Status.values()) { + if (status == Vehicle.Status.ABGEMELDET) { + continue; + } + + MenuItem mi = new MenuItem(status.name()); + + if (status == Vehicle.Status.FREI_FUNK || status == Vehicle.Status.FREI_WACHE) { + mi.getStyleClass().add("mi-free"); + } else { + mi.getStyleClass().add("mi-other"); + } + + mi.setOnAction( + event -> { + try { + vehicleService.update(data.toBuilder().status(status).build()); + this.updateList(); + } catch (InvalidVehicleException e) { + LOG.debug( + "Validation error in createContextMenu(). (mi.setOnAction) ", + e); + showValidationErrorAlertAndWait(e.getMessage()); + } catch (ServiceException e) { + LOG.error("Exception in createContextMenu(). (mi.setOnAction) ", e); + showServiceExceptionAlertAndWait( + "Beim Aktualisieren der Fahrzeuge ist ein Fehler aufgetreten."); + } + }); + + menu.getItems().add(mi); + } + + MenuItem abmelden = new MenuItem("abmelden"); + + abmelden.setOnAction( + event -> { + try { + List registrations = data.registrations(); + assert registrations + != null; // Otherwise the element shouldn't be in the list. + + List newRegistrations = new ArrayList<>(); + Instant now = Instant.now(); + + for (Registration registration : registrations) { + if (registration.start().isBefore(now) + && registration.end().isAfter(now)) { + newRegistrations.add( + registration + .toBuilder() + .end(Instant.now().minus(1, ChronoUnit.SECONDS)) + .build()); + } else newRegistrations.add(registration); + } + + vehicleService.update( + data.toBuilder() + .registrations(newRegistrations) + .status(Vehicle.Status.ABGEMELDET) + .build()); + + this.updateList(); + } catch (InvalidVehicleException e) { + LOG.debug( + "Validation error in createContextMenu(). (abmelden.setOnAction) ", + e); + showValidationErrorAlertAndWait(e.getMessage()); + } catch (ServiceException e) { + LOG.error("Exception in createContextMenu(). (abmelden.setOnAction) ", e); + showServiceExceptionAlertAndWait( + "Beim Aktualisieren der Fahrzeuge ist ein Fehler aufgetreten."); + } + }); + + menu.getItems().add(abmelden); + return menu; + } + + @FXML + protected void createOperationClicked() { + LOG.debug("Button \"Erstellen\" clicked."); + Vehicle[] vehicles = new Vehicle[chosenVehicles.size()]; + for (int i = 0; i < chosenVehicles.size(); i++) { + vehicles[i] = chosenVehicles.get(i); + } + Operation operation = + Operation.builder() + .additionalInfo(txtNote.getText()) + .destination(txtAddress.getText()) + .opCode(txtCode.getText()) + .status(Status.ACTIVE) + .vehicles(Set.of(vehicles)) + .build(); + try { + operationService.add(operation); + } catch (ServiceException e) { + LOG.error("Exception in createOperationClicked(). ", e); + showServiceExceptionAlertAndWait( + "Beim Erstellen des Einsatzes ist ein Fehler aufgetreten."); + return; + } catch (InvalidOperationException e) { + LOG.debug("Validation error in createOperationClicked(). ", e); + showValidationErrorAlertAndWait(e.getMessage()); + return; + } + showSuccessAlertAndWait("Der Einsatz wurde erfolgreich gespeichert."); + updateList(); + lblChosenVehicles.setText("keine ausgewählt"); + txtAddress.setText(""); + txtCode.setText(""); + txtNote.setText(""); + chosenVehicles = new LinkedList<>(); + } + + @FXML + private void onRegistrationLinkClicked() { + LOG.debug("Hyperlink \"Anmeldungen\" clicked."); + openRegistrationWindow(); + } + + @FXML + private void onEmployeeLinkClicked() { + LOG.debug("Hyperlink \"Personen\" clicked."); + openCreateNewEmployeeWindow(); + } + + @FXML + private void onVehicleLinkClicked() { + LOG.debug("Hyperlink \"Fahrzeuge\" clicked."); + openCreateCarWindow(); + } + + @FXML + private void onArchivLinkClicked() { + LOG.debug("Hyperlink \"Archiv\" clicked."); + archiveOperationController.update(); + openArchivWindow(); + } + + private void openArchivWindow() { + archiveOperationController.setVisible(true); + this.setVisible(false); + } + + void setVisible(boolean b) { + apInvisible.setVisible(!b); + grdWindowContainer.setVisible(!b); + + updateList(); + } + + private void openDetailsWindow(Operation operation) { + operationDetailsController.initOperation(operation); + this.setVisible(false); + } + + private void openCreateNewEmployeeWindow() { + this.setVisible(false); + manageEmployeesController.setVisible(true); + } + + private void openCreateCarWindow() { + this.setVisible(false); + createCarController.setVisible(true); + } + + private void openRegistrationWindow() { + this.setVisible(false); + registrationWindowController.setVisible(true); + } + + @FXML + private void onOperationCodeChanged(KeyEvent keyEvent) { + if (keyEvent.getCode() == KeyCode.ENTER) { + updateList(); + } + } + + static ListCell generateOpCodeListItem() { + return new ListCell<>() { + @Override + protected void updateItem(Operation item, boolean empty) { + super.updateItem(item, empty); + + if (empty || item == null || item.opCode() == null) { + setText(null); + } else { + setText(item.opCode()); + } + } + }; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CustomListItemController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CustomListItemController.java new file mode 100644 index 0000000..ced0c10 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CustomListItemController.java @@ -0,0 +1,24 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import javafx.scene.Node; + +public abstract class CustomListItemController { + + protected Node rootElement; + + public Node getRootElement() { + return rootElement; + } + + public void setSelected(boolean selected) { + rootElement.getStyleClass().clear(); + + if (selected) { + rootElement.getStyleClass().add("bg-yellow"); + rootElement.getStyleClass().add("shadowed"); + } else { + rootElement.getStyleClass().add("bg-white"); + rootElement.getStyleClass().add("shadowed"); + } + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/DetailArchiveOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/DetailArchiveOperationController.java new file mode 100644 index 0000000..32630a5 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/DetailArchiveOperationController.java @@ -0,0 +1,77 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; +import java.io.IOException; +import java.util.Objects; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.layout.VBox; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class DetailArchiveOperationController { + private static final Logger LOG = + LoggerFactory.getLogger(DetailArchiveOperationController.class); + + @FXML private VBox vBoxVehicle; + @FXML private VBox vBoxPeople; + private final SpringFXMLLoader fxmlLoader; + + public DetailArchiveOperationController(SpringFXMLLoader fxmlLoader) { + this.fxmlLoader = fxmlLoader; + } + + static DetailArchiveOperationController create(SpringFXMLLoader fxmlLoader) throws IOException { + FXMLWrapper wrapper = + fxmlLoader.loadAndWrap( + "/fxml/DetailArchiveOperation.fxml", + DetailArchiveOperationController.class); + + Node root = (Node) wrapper.getLoadedObject(); + DetailArchiveOperationController result = wrapper.getController(); + result.rootElement = root; + + return result; + } + + public Node getRoot() { + return rootElement; + } + + private Node rootElement; + + public void set(Vehicle vehicle) { + VehiclePaneController controller; + try { + controller = VehiclePaneController.createVehiclePane(); + controller.setData(vehicle, false, false); + vBoxVehicle.getChildren().add(controller.getRootElement()); + } catch (IOException e) { + LOG.error("IOException in set(Vehicle). (vBoxVehicle) ", e); + showServiceExceptionAlertAndWait( + "Ein interner Fehler ist aufgetreten. Bitte wenden Sie sich an den/die SystemadministratorIn."); + } + try { + for (int i = 0; i < Objects.requireNonNull(vehicle.registrations()).size(); i++) { + Employee employee = + Objects.requireNonNull(vehicle.registrations()).get(i).employee(); + + EmployeeListItemController employeeListItemController = + EmployeeListItemController.createEmployeeListItemController( + fxmlLoader, employee); + vBoxPeople.getChildren().add(employeeListItemController.getRootElement()); + } + } catch (IOException e) { + LOG.error("IOException in set(Vehicle). (vBoxPeople) ", e); + showServiceExceptionAlertAndWait( + "Ein interner Fehler ist aufgetreten. Bitte wenden Sie sich an den/die SystemadministratorIn."); + } + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListController.java new file mode 100644 index 0000000..12f6bff --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListController.java @@ -0,0 +1,133 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; +import javafx.fxml.FXML; +import javafx.geometry.Insets; +import javafx.scene.Node; +import javafx.scene.layout.FlowPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Controller; + +@Controller +@Scope("prototype") +public class EmployeeListController { + + private static final Logger LOG = LoggerFactory.getLogger(EmployeeListController.class); + + @FXML private FlowPane flowPaneEmployeeList; + + private Consumer onEmployeeClicked; + + private final SpringFXMLLoader fxmlLoader; + private Node rootElement; + private List employeeListItemControllers; + private Insets listItemMargins = new Insets(10, 5, 0, 5); + + public EmployeeListController(SpringFXMLLoader fxmlLoader) { + this.fxmlLoader = fxmlLoader; + this.employeeListItemControllers = new ArrayList<>(); + } + + public void setListItemMargins(Insets value) { + this.listItemMargins = value; + } + + public void setData(Set employeeList) { + setData(employeeList, null, null); + } + + public void setData(Set employeeList, Consumer onEmployeeClicked) { + setData(employeeList, onEmployeeClicked, null); + } + + public void setData( + Set employeeList, + Consumer onEmployeeClicked, + Consumer onEmployeeListItemClicked) { + + flowPaneEmployeeList.getChildren().clear(); + employeeListItemControllers.clear(); + employeeList.forEach( + employee -> + addEmployeeToFlowPane( + employee, onEmployeeClicked, onEmployeeListItemClicked)); + } + + private void addEmployeeToFlowPane( + Employee employee, + Consumer onEmployeeClicked, + Consumer onEmployeeListItemClicked) { + + try { + EmployeeListItemController controller = + EmployeeListItemController.createEmployeeListItemController( + fxmlLoader, employee); + Node rootElement = controller.getRootElement(); + flowPaneEmployeeList.getChildren().add(rootElement); + employeeListItemControllers.add(controller); + FlowPane.setMargin(rootElement, listItemMargins); + if (onEmployeeClicked != null) { + controller.setConsumerEmployeeClicked(onEmployeeClicked); + } + if (onEmployeeListItemClicked != null) { + controller.setConsumerEmployeeListItemClicked( + employeeListItemController -> { + onEmployeeListItemClicked.accept(employeeListItemController); + if (this.onEmployeeClicked != null) { + this.onEmployeeClicked.accept( + employeeListItemController.getEmployee()); + } + }); + } + } catch (IOException e) { + LOG.error("IOException in addEmployeeToFlowPane. ", e); + } + } + + private void setEmployeeSelected(Employee employee, boolean selected) { + employeeListItemControllers + .stream() + .filter(controller -> controller.getEmployee().equals(employee)) + .forEach(controller -> controller.setSelected(selected)); + } + + public void selectEmployee(Employee employee) { + setEmployeeSelected(employee, true); + } + + public void deselectEmployee(Employee employee) { + setEmployeeSelected(employee, false); + } + + public void deselectAllEmployees() { + employeeListItemControllers.forEach( + employeeListItemController -> employeeListItemController.setSelected(false)); + } + + public static EmployeeListController createEmployeeListController(SpringFXMLLoader loader) + throws IOException { + FXMLWrapper wrapper = + loader.loadAndWrap("/fxml/employeeList.fxml", EmployeeListController.class); + Node root = (Node) wrapper.getLoadedObject(); + EmployeeListController controller = wrapper.getController(); + controller.rootElement = root; + return controller; + } + + public Node getRootElement() { + return rootElement; + } + + public void setOnEmployeeClicked(Consumer onEmployeeClicked) { + this.onEmployeeClicked = onEmployeeClicked; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListItemController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListItemController.java new file mode 100644 index 0000000..543fe0d --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListItemController.java @@ -0,0 +1,87 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; +import java.io.IOException; +import java.util.function.Consumer; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Controller; + +@Controller +@Scope("prototype") +public class EmployeeListItemController extends CustomListItemController { + + @FXML private Label lblName; + @FXML private Label lblQualification; + @FXML private Label lblPilot; + @FXML private Label lblDriver; + @FXML private ImageView imgPilot; + @FXML private ImageView imgDriver; + @FXML private ImageView imgQualification; + + private Employee employee; + + private Consumer consumerEmployeeClicked; + private Consumer consumerEmployeeListItemClicked; + + @FXML + private void onEmployeeClicked() { + if (consumerEmployeeClicked != null) { + consumerEmployeeClicked.accept(employee); + } + if (consumerEmployeeListItemClicked != null) { + consumerEmployeeListItemClicked.accept(this); + } + } + + private void setData(Employee employee) { + this.employee = employee; + lblName.setText(employee.name()); + lblQualification.setText(employee.educationLevel().name()); + lblPilot.setText(String.format("%s Pilot", employee.isPilot() ? "ist" : "nicht")); + lblDriver.setText(String.format("%s Fahrer", employee.isDriver() ? "ist" : "nicht")); + imgQualification.setImage(new Image("/images/Qualification.png")); + String imgSrcPilot = + String.format("/images/%s", employee.isPilot() ? "Pilot.png" : "NotPilot.png"); + imgPilot.setImage(new Image(imgSrcPilot)); + String imgSrcDriver = + String.format("/images/%s", employee.isDriver() ? "Driver.png" : "NotDriver.png"); + imgDriver.setImage(new Image(imgSrcDriver)); + } + + public static EmployeeListItemController createEmployeeListItemController( + SpringFXMLLoader fxmlLoader, Employee employee) throws IOException { + EmployeeListItemController controller = createEmployeeListItemController(fxmlLoader); + controller.setData(employee); + return controller; + } + + public static EmployeeListItemController createEmployeeListItemController( + SpringFXMLLoader loader) throws IOException { + FXMLWrapper wrapper = + loader.loadAndWrap("/fxml/employeeListItem.fxml", EmployeeListItemController.class); + Node root = (Node) wrapper.getLoadedObject(); + EmployeeListItemController controller = wrapper.getController(); + controller.rootElement = root; + return controller; + } + + public Employee getEmployee() { + return employee; + } + + public void setConsumerEmployeeClicked(Consumer consumerEmployeeClicked) { + this.consumerEmployeeClicked = consumerEmployeeClicked; + } + + public void setConsumerEmployeeListItemClicked( + Consumer consumerEmployeeListItemClicked) { + this.consumerEmployeeListItemClicked = consumerEmployeeListItemClicked; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/FilterEmployeesController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/FilterEmployeesController.java new file mode 100644 index 0000000..a31c3e3 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/FilterEmployeesController.java @@ -0,0 +1,65 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; +import java.io.IOException; +import java.util.function.Consumer; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.TextField; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Controller; + +@Controller +@Scope("prototype") +public class FilterEmployeesController { + private static final Logger LOG = LoggerFactory.getLogger(FilterEmployeesController.class); + + @FXML private TextField inputFilterString; + + private Consumer consumerFilterTextChanged; + private Runnable consumerAddEmployeeClicked; + + private Node rootElement; + + @FXML + private void onAddEmployeeClicked() { + LOG.debug("Button \"Person hinzufügen\" clicked."); + if (consumerAddEmployeeClicked != null) { + consumerAddEmployeeClicked.run(); + } + } + + @FXML + private void onFilterTextChanged() { + LOG.debug("Filter text changed."); + if (consumerFilterTextChanged != null) { + consumerFilterTextChanged.accept(inputFilterString.getText()); + } + } + + public void setOnFilterTextChangedListener(Consumer callback) { + this.consumerFilterTextChanged = callback; + } + + public void setOnAddEmployeeClickedListener(Runnable callback) { + this.consumerAddEmployeeClicked = callback; + } + + public static FilterEmployeesController createFilterEmployeesController( + SpringFXMLLoader fxmlLoader) throws IOException { + FXMLWrapper wrapper = + fxmlLoader.loadAndWrap( + "/fxml/filterEmployeesControl.fxml", FilterEmployeesController.class); + Node root = (Node) wrapper.getLoadedObject(); + FilterEmployeesController controller = wrapper.getController(); + controller.rootElement = root; + return controller; + } + + public Node getRootElement() { + return rootElement; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/Helper.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/Helper.java new file mode 100644 index 0000000..f120eb6 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/Helper.java @@ -0,0 +1,34 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.ButtonType; + +public class Helper { + + static final String ALERT_TITLE_VALIDATION_ERROR = "Validierungsfehler"; + static final String ALERT_TITLE_SERVICE_EXCEPTION = "Fehler"; + static final String ALERT_TITLE_SUCCESS = "Erfolg"; + + private Helper() {} // SonarLint insisted to create a private constructor to hide the public one + + static void showValidationErrorAlertAndWait(String message) { + showAlertWithOkButtonAndWait(AlertType.ERROR, ALERT_TITLE_VALIDATION_ERROR, message); + } + + static void showServiceExceptionAlertAndWait(String message) { + showAlertWithOkButtonAndWait(AlertType.ERROR, ALERT_TITLE_SERVICE_EXCEPTION, message); + } + + static void showSuccessAlertAndWait(String message) { + showAlertWithOkButtonAndWait(AlertType.INFORMATION, ALERT_TITLE_SUCCESS, message); + } + + static void showAlertWithOkButtonAndWait( + AlertType alertType, String headerText, String contentText) { + Alert alert = new Alert(alertType, contentText, ButtonType.OK); + alert.setTitle(headerText); + alert.setHeaderText(headerText); + alert.showAndWait(); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ManageEmployeesController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ManageEmployeesController.java new file mode 100644 index 0000000..6138094 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ManageEmployeesController.java @@ -0,0 +1,120 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.EmployeeService; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import java.io.IOException; +import java.util.HashSet; +import java.util.stream.Collectors; +import javafx.fxml.FXML; +import javafx.scene.layout.AnchorPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class ManageEmployeesController { + + private static final Logger LOG = LoggerFactory.getLogger(ManageEmployeesController.class); + @FXML private AnchorPane listEmployeesAP; + @FXML private AnchorPane containerHeader; + @FXML private EmployeeListController employeeListController; + + private final EmployeeService employeeService; + private final SpringFXMLLoader fxmlLoader; + + private final CreateOperationController createOperationController; + + public ManageEmployeesController( + EmployeeService employeeService, + SpringFXMLLoader fxmlLoader, + CreateOperationController createOperationController) { + this.employeeService = employeeService; + this.fxmlLoader = fxmlLoader; + this.createOperationController = createOperationController; + } + + @FXML + private void initialize() { + openFilter(); + } + + private void openFilter() { + try { + FilterEmployeesController filterEmployeesController = + FilterEmployeesController.createFilterEmployeesController(fxmlLoader); + containerHeader.getChildren().clear(); + containerHeader.getChildren().add(filterEmployeesController.getRootElement()); + filterEmployeesController.setOnFilterTextChangedListener(this::updateEmployeeList); + filterEmployeesController.setOnAddEmployeeClickedListener(this::openAddEmployee); + updateEmployeeList(); + + } catch (IOException e) { + LOG.error("IOException in openFilter().", e); + } + } + + private void openAddEmployee() { + employeeListController.deselectAllEmployees(); + openEmployee(null); + } + + private void openEditEmployee(Employee employee) { + employeeListController.deselectAllEmployees(); + employeeListController.selectEmployee(employee); + openEmployee(employee); + } + + private void openEmployee(Employee employee) { + try { + CreateNewEmployeeController createNewEmployeeController = + employee == null + ? CreateNewEmployeeController.createCreateNewEmployeeController( + fxmlLoader) + : CreateNewEmployeeController.createCreateNewEmployeeController( + fxmlLoader, employee); + containerHeader.getChildren().clear(); + containerHeader.getChildren().add(createNewEmployeeController.getRootElement()); + createNewEmployeeController.setConsumerCancelClicked(this::openFilter); + createNewEmployeeController.setConsumerCreateClicked(this::openFilter); + } catch (IOException e) { + LOG.error("IOException in openEmployee(). ", e); + } + } + + private void updateEmployeeList() { + updateEmployeeList(""); + } + + private void updateEmployeeList(String searchString) { + + try { + employeeListController.setData( + employeeService + .list() + .stream() + .filter( + employee -> + searchString.trim().isEmpty() + || employee.name() + .toLowerCase() + .contains(searchString.toLowerCase())) + .collect(Collectors.toCollection(HashSet::new)), + this::openEditEmployee); + + } catch (ServiceException e) { + LOG.error("ServiceException in updateEmployeeList(). ", e); + } + } + + public void setVisible(boolean b) { + listEmployeesAP.setVisible(b); + } + + public void backToMain() { + LOG.debug("Hyperlink \"Zurück\" clicked."); + this.setVisible(false); + createOperationController.setVisible(true); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java new file mode 100644 index 0000000..0476fc6 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java @@ -0,0 +1,169 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showAlertWithOkButtonAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showSuccessAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.OperationService; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; +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.ServiceException; +import java.io.IOException; +import java.util.Collection; +import java.util.EnumSet; +import java.util.Set; +import java.util.stream.Collectors; +import javafx.collections.FXCollections; +import javafx.fxml.FXML; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ListView; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.FlowPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class OperationDetailsController { + private static final Logger LOG = LoggerFactory.getLogger(OperationDetailsController.class); + + public Operation operation; + private final OperationService operationService; + private final VehicleService vehicleService; + private final CreateOperationController createOperationController; + @FXML private FlowPane fpVehicles; + @FXML private ListView lvActiveOperations; + @FXML private Label lblChosenVehicles; + @FXML private Button btnCloseOperation; + @FXML private Button btnCancelOperation; + @FXML private Label lblCode, lblAdditionalInfo, lblAddress; + @FXML private AnchorPane operationDetailsAP; + + public OperationDetailsController( + OperationService operationService, + VehicleService vehicleService, + CreateOperationController createOperationController) { + this.operationService = operationService; + this.vehicleService = vehicleService; + this.createOperationController = createOperationController; + } + + @FXML + private void initialize() { + lvActiveOperations.setCellFactory( + param -> CreateOperationController.generateOpCodeListItem()); + lvActiveOperations.setOnMouseClicked( + event -> { + if (event.getClickCount() == 2) { + if (lvActiveOperations.getSelectionModel().getSelectedItem() == null) { + return; + } + initOperation(lvActiveOperations.getSelectionModel().getSelectedItem()); + } + }); + } + + private void updateFlowPane() { + try { + fpVehicles.getChildren().clear(); + for (Vehicle vehicle : operation.vehicles()) { + VehiclePaneController controller = VehiclePaneController.createVehiclePane(); + controller.setData(vehicle, true, true); + controller.getBtnRequest().setOnAction(e -> requestVehicleClicked(controller)); + fpVehicles.getChildren().add(controller.getRootElement()); + } + } catch (IOException e) { + LOG.error("Error while updating list.", e); + showServiceExceptionAlertAndWait("Error while updating list."); + } + } + + void initOperation(Operation operation) { + fillActiveList(); + this.operation = operation; + lblCode.setText(operation.opCode()); + Collection vehicleNames = + operation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList()); + String result = String.join(", ", vehicleNames); + lblChosenVehicles.setText(result.toString()); + lblAdditionalInfo.setText(operation.additionalInfo()); + lblAddress.setText(operation.destination()); + updateFlowPane(); + operationDetailsAP.setVisible(true); + } + + private void fillActiveList() { + try { + lvActiveOperations.setItems( + FXCollections.observableArrayList( + operationService.list(EnumSet.of(Status.ACTIVE)))); + } catch (ServiceException e) { + LOG.error("ServiceException in fillActiveList(). ", e); + showServiceExceptionAlertAndWait(e.getMessage()); + } + } + + @FXML + public void closeOperationClicked() { + LOG.debug("Button \"Abschließen\" clicked."); + try { + operationService.complete(operation.id(), Status.COMPLETED); + } catch (InvalidOperationException e) { + LOG.debug("Validation error in closeOperationClicked(). ", e); + showAlertWithOkButtonAndWait(AlertType.ERROR, "Validierungsfehler", e.getMessage()); + return; + } catch (ServiceException e) { + LOG.error("Exception in closeOperationClicked(). ", e); + showServiceExceptionAlertAndWait(e.getMessage()); + return; + } + showSuccessAlertAndWait("Der Einsatz wurde erfolgreich aktualisiert"); + createOperationController.updateList(); + closeWindow(); + } + + public void cancelOperationClicked() { + LOG.debug("Button \"Stornieren\" clicked."); + try { + operationService.complete(operation.id(), Status.CANCELLED); + } catch (InvalidOperationException e) { + LOG.debug("Validation error in cancelOperationClicked(). ", e); + showValidationErrorAlertAndWait(e.getMessage()); + return; + } catch (ServiceException e) { + LOG.error("Exception in cancelOperationClicked(). ", e); + showServiceExceptionAlertAndWait(e.getMessage()); + return; + } + showSuccessAlertAndWait("Der Einsatz wurde erfolgreich aktualisiert"); + createOperationController.updateList(); + closeWindow(); + } + + private void requestVehicleClicked(VehiclePaneController v) { + LOG.debug("Button \"Nachfordern\" clicked."); + + try { + operationService.requestVehicles(operation.id(), Set.of(v.getData().id())); + } catch (ServiceException | InvalidOperationException | InvalidVehicleException e) { + LOG.error("Exception in requestVehicleClicked()", e); + showServiceExceptionAlertAndWait(e.getMessage()); + return; + } + showSuccessAlertAndWait("Das Fahrzeug wurde erfolgreich angefordert"); + createOperationController.updateList(); + } + + public void closeWindow() { + LOG.debug("Hyperlink \"Zurück\" clicked."); + operationDetailsAP.setVisible(false); + this.createOperationController.setVisible(true); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationInArchiveController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationInArchiveController.java new file mode 100644 index 0000000..17f0f55 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationInArchiveController.java @@ -0,0 +1,65 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.Collection; +import java.util.Objects; +import java.util.stream.Collectors; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Node; +import javafx.scene.text.Text; + +public class OperationInArchiveController { + + @FXML private Text txtAddress; + @FXML private Text txtVehicles; + @FXML private Text txtDate; + @FXML private Text txtOpCode; + + static OperationInArchiveController create() throws IOException { + FXMLLoader fxmlLoader = + new FXMLLoader( + OperationInArchiveController.class.getResource( + "/fxml/OperationInArchive.fxml")); + Node root = fxmlLoader.load(); + OperationInArchiveController result = fxmlLoader.getController(); + result.rootElement = root; + + return result; + } + + public Node getRoot() { + return rootElement; + } + + private Node rootElement; + + public void set(Operation operation) { + txtAddress.setText(operation.destination()); + String date = "am "; + if (operation.created() != null) { + LocalDateTime myDateTime = + LocalDateTime.ofInstant( + Objects.requireNonNull(operation.created()), ZoneOffset.UTC); + date += + myDateTime.getDayOfMonth() + + "." + + myDateTime.getMonth().getValue() + + "." + + myDateTime.getYear(); + txtDate.setText(date); + } else { + txtDate.setText("---"); + } + txtOpCode.setText(operation.opCode()); + Collection elements = + operation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList()); + String result = String.join(", ", elements); + + txtVehicles.setText(result); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java new file mode 100644 index 0000000..9c47fe4 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java @@ -0,0 +1,279 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.EmployeeService; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.RegistrationService; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; +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.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import java.io.IOException; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.geometry.Insets; +import javafx.scene.Node; +import javafx.scene.control.ChoiceBox; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; +import javafx.scene.input.KeyEvent; +import javafx.scene.input.MouseButton; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.VBox; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class RegistrationWindowController { + + private static final Logger LOG = LoggerFactory.getLogger(RegistrationWindowController.class); + + private final EmployeeService employeeService; + private final VehicleService vehicleService; + private final RegistrationService registrationService; + private final CreateOperationController createOperationController; + private final SpringFXMLLoader fxmlLoader; + + @FXML private GridPane root; + @FXML private VBox vbVehicles; + @FXML private ScrollPane listEmployee; + @FXML private ChoiceBox cbStart; + @FXML private ChoiceBox cbEnd; + @FXML private Label lVehicles; + @FXML private Label lEmployees; + @FXML private TextField tfVehicleSearch; + @FXML private TextField tfEmployeeSearch; + private EmployeeListController employeeListController; + + private Vehicle chosenVehicle; + private List chosenEmployees = new LinkedList<>(); + + public RegistrationWindowController( + EmployeeService employeeService, + VehicleService vehicleService, + CreateOperationController createOperationController, + RegistrationService registrationService, + SpringFXMLLoader fxmlLoader) { + this.employeeService = employeeService; + this.vehicleService = vehicleService; + this.createOperationController = createOperationController; + this.registrationService = registrationService; + this.fxmlLoader = fxmlLoader; + } + + @FXML + private void initialize() throws IOException { + employeeListController = EmployeeListController.createEmployeeListController(fxmlLoader); + employeeListController.setListItemMargins(new Insets(10, 6, 0, 6)); + // listEmployee. .getChildren().add(employeeListController.getRootElement()); + Node emplList = employeeListController.getRootElement(); + // emplList.(360); + listEmployee.setContent(emplList); + + ObservableList hours = + FXCollections.observableArrayList( + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23); + cbStart.setItems(hours); + cbStart.setValue(0); + cbEnd.setItems(hours); + cbEnd.setValue(12); + + reset(); + } + + private void updateEmplList() { + employeeListController.deselectAllEmployees(); + + try { + Set employees = + employeeService + .list() + .stream() + .filter( + e -> + e.name() + .toLowerCase() + .contains( + tfEmployeeSearch + .getText() + .toLowerCase())) + .collect(Collectors.toCollection(HashSet::new)); + employeeListController.setData( + employees, + selection -> { + if (selection == null) { + return; + } else if (chosenEmployees.contains(selection)) { + chosenEmployees.remove(selection); + } else { + chosenEmployees.add(selection); + } + + StringBuilder text = new StringBuilder(); + boolean first = true; + for (Employee employee : chosenEmployees) { + if (!first) { + text.append(", "); + } + text.append(employee.name()); + first = false; + } + lEmployees.setText(text.toString()); + }, + contr -> contr.setSelected(chosenEmployees.contains(contr.getEmployee()))); + + employees.forEach( + e -> { + if (chosenEmployees.contains(e)) employeeListController.selectEmployee(e); + }); + } catch (ServiceException e) { + LOG.error("ServiceException in updateEmplList(). ", e); + showServiceExceptionAlertAndWait( + "Beim Auflisten des Personals ist ein Fehler aufgetreten."); + } + } + + private void updateVehList() { + vbVehicles.getChildren().clear(); + + try { + Set vehicles = vehicleService.list(EnumSet.of(Status.ABGEMELDET)); + + boolean anyMatch = false; + + for (Vehicle vehicle : vehicles) { + if (!vehicle.name().toLowerCase().contains(tfVehicleSearch.getText().toLowerCase())) + continue; + + anyMatch = true; + + VehiclePaneController vp = VehiclePaneController.createVehiclePane(); + vp.setData(vehicle, false, false); + vbVehicles.getChildren().add(vp.getRootElement()); + + vp.getRootElement() + .setOnMouseClicked( + event -> { + if (event.getButton() == MouseButton.PRIMARY) { + chosenVehicle = vehicle; + lVehicles.setText(chosenVehicle.name()); + updateVehList(); + } + }); + if (chosenVehicle != null && chosenVehicle.id() == vehicle.id()) + vp.setSelected(true); + } + + if (!anyMatch) { + // Kind of ugly, but best way to get the size of a VehiclePane + VehiclePaneController vp = VehiclePaneController.createVehiclePane(); + vp.getRootElement().setVisible(false); + vbVehicles.getChildren().add(vp.getRootElement()); + } + } catch (ServiceException e) { + LOG.error("ServiceException in updateVehList(). ", e); + showServiceExceptionAlertAndWait( + "Beim Auflisten der Fahrzeuge ist ein Fehler aufgetreten"); + } catch (IOException e) { + LOG.error("IOException in updateVehList(). ", e); + showServiceExceptionAlertAndWait("Beim Laden der Fahrzeuge ist ein Fehler aufgetreten"); + } + } + + public void cancel() { + LOG.debug("Hyperlink \"schließen\" clicked"); + reset(); + this.setVisible(false); + createOperationController.setVisible(true); + } + + private void reset() { + chosenEmployees.clear(); + chosenVehicle = null; + tfEmployeeSearch.setText(""); + tfVehicleSearch.setText(""); + lEmployees.setText("-"); + lVehicles.setText("-"); + updateVehList(); + updateEmplList(); + } + + public void create() { + LOG.debug("Button \"ERSTELLEN\" clicked"); + + Set registrations = new HashSet<>(); + try { + if (chosenVehicle == null) { + throw new InvalidVehicleException("no Vehicle"); + } + for (Employee employee : chosenEmployees) { + registrations.add( + Registration.builder() + .id(chosenVehicle.id()) + .employee(employee) + .start( + LocalDateTime.of( + LocalDate.now(), + LocalTime.of(cbStart.getValue(), 0)) + .toInstant(OffsetDateTime.now().getOffset())) + .end( + LocalDateTime.of( + LocalDate.now(), + LocalTime.of(cbEnd.getValue(), 0)) + .toInstant(OffsetDateTime.now().getOffset())) + .build()); + } + + registrationService.add(chosenVehicle.id(), registrations); + chosenEmployees.clear(); + // ((Stage) lVehicles.getScene().getWindow()).close(); + this.setVisible(false); + createOperationController.setVisible(true); + reset(); + } catch (InvalidVehicleException e) { + LOG.debug("Validation of Vehicle in Registration failed."); + showValidationErrorAlertAndWait("Das spezifizierte Fahrzeug ist nicht gültig."); + } catch (ServiceException e) { + LOG.error("ServiceException in create(). ", e); + showServiceExceptionAlertAndWait( + "Beim Erstellen der Anmeldung ist ein Fehler aufgetreten."); + } catch (InvalidRegistrationException e) { + LOG.debug("Validation of Registration failed."); + showValidationErrorAlertAndWait( + "Die gewählte Kombination von Fahrzeug und Personal ist nicht gültig!"); + } + } + + public void setVisible(boolean b) { + root.setVisible(b); + reset(); + } + + public void tfVehicleSearch_TextChanged(KeyEvent keyEvent) { + updateVehList(); + } + + public void tfEmployeeSearch_TextChanged(KeyEvent keyEvent) { + updateEmplList(); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/VehiclePaneController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/VehiclePaneController.java new file mode 100644 index 0000000..66b45d2 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/VehiclePaneController.java @@ -0,0 +1,118 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; +import java.io.IOException; +import java.time.Instant; +import java.util.List; +import java.util.Optional; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.text.Text; + +public class VehiclePaneController extends CustomListItemController { + + public static VehiclePaneController createVehiclePane() throws IOException { + FXMLLoader fxmlLoader = + new FXMLLoader(VehiclePaneController.class.getResource("/fxml/vehiclePane.fxml")); + Node root = fxmlLoader.load(); + VehiclePaneController result = fxmlLoader.getController(); + result.rootElement = root; + + return result; + } + + @FXML private Label txtStatus; + @FXML private Text txtType; + @FXML private Text txtNumber; + @FXML private ImageView ivNEF; + @FXML private Text txtNEF; + @FXML private ImageView ivQualification; + @FXML private Text txtQualification; + @FXML private Text txtRooftype; + @FXML private Button btnRequest; + + private Vehicle data; + + public Vehicle getData() { + return data; + } + + /** + * * Set the displayed data of this VehiclePane. + * + * @param vehicle The data to display. + * @param showStatusInfo If true, the highest qualification of the vehicle's active registration + * and the vehicle's status will be shown. + */ + public void setData(Vehicle vehicle, boolean showStatusInfo, boolean showRequestVehicle) { + txtType.setText(vehicle.type().name()); + String constrType = vehicle.constructionType().name(); + txtRooftype.setText( + constrType.substring(0, 1).toUpperCase() + constrType.substring(1).toLowerCase()); + txtNumber.setText("-" + vehicle.id()); + if (vehicle.hasNef()) { + ivNEF.setImage(new Image("images/NEF.png")); + txtNEF.setText("hat NEF-Halterung"); + } else { + ivNEF.setImage(new Image("images/NotNEF.png")); + txtNEF.setText("keine NEF-Halterung"); + } + + if (showRequestVehicle) { + btnRequest.setVisible(true); + btnRequest.setManaged(true); + } else { + btnRequest.setVisible(false); + btnRequest.setManaged(false); + } + + if (showStatusInfo) { + txtStatus.setText(vehicle.status().name()); + if (vehicle.status() == Status.FREI_FUNK || vehicle.status() == Status.FREI_WACHE) { + txtStatus.getStyleClass().add("bg-status-green"); + } else { + txtStatus.getStyleClass().add("bg-status-orange"); + } + + Instant now = Instant.now(); + List regs = vehicle.registrations(); + + if (regs == null) { + return; + } + + Optional edu = + regs.stream() + .filter(reg -> reg.start().isBefore(now) && reg.end().isAfter(now)) + .map(reg -> reg.employee().educationLevel()) + .max(EducationLevel::compareTo); + + if (!edu.isPresent()) { + return; + } + + txtQualification.setText(edu.get().name()); + } else { + txtQualification.setVisible(false); + txtQualification.setManaged(false); + ivQualification.setVisible(false); + ivQualification.setManaged(false); + + txtStatus.setVisible(false); + } + + this.data = vehicle; + } + + public Button getBtnRequest() { + return btnRequest; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAO.java new file mode 100644 index 0000000..d8ac513 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAO.java @@ -0,0 +1,44 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import java.util.Set; + +public interface EmployeeDAO { + + /** + * Persist the given employee. + * + * @param employee that should be stored + * @return the id that was assigned + * @throws PersistenceException if the employee could not be persisted + */ + long add(Employee employee) throws PersistenceException; + + /** + * Update the given employee. + * + * @param employee that should be updated + * @throws ElementNotFoundException if no employee with the given id exists + * @throws PersistenceException if the employee could not be updated + */ + void update(Employee employee) throws ElementNotFoundException, PersistenceException; + + /** + * Get all stored employees. + * + * @return list containing all stored employees + * @throws PersistenceException if loading the stored employees failed + */ + Set list() throws PersistenceException; + + /** + * Remove employee with the given id from the store. + * + * @param id of the employee that should be removed + * @throws ElementNotFoundException if no employee with the given id exists + * @throws PersistenceException if the employee could not be removed + */ + void remove(long id) throws ElementNotFoundException, PersistenceException; +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDatabaseDAO.java new file mode 100644 index 0000000..889b0fc --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDatabaseDAO.java @@ -0,0 +1,144 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; +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; +import java.sql.Statement; +import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; +import org.springframework.stereotype.Repository; + +@Repository +public class EmployeeDatabaseDAO implements EmployeeDAO { + + private JDBCConnectionManager jdbcConnectionManager; + + public EmployeeDatabaseDAO(JDBCConnectionManager jdbcConnectionManager) { + this.jdbcConnectionManager = jdbcConnectionManager; + } + + private long createEmployeeVersion(Connection con, Employee e) + throws PersistenceException, SQLException { + String sql = + "INSERT INTO EmployeeVersion(name, birthday, educationLevel, isDriver, isPilot) " + + "VALUES(?, ?, ?, ?, ?)"; + + try (PreparedStatement pstmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + pstmt.setString(1, e.name()); + pstmt.setObject(2, e.birthday()); + pstmt.setInt(3, e.educationLevel().ordinal()); + pstmt.setBoolean(4, e.isDriver()); + pstmt.setBoolean(5, e.isPilot()); + pstmt.executeUpdate(); + + try (ResultSet rs = pstmt.getGeneratedKeys()) { + if (!rs.next()) throw new PersistenceException("Failed to insert EmployeeVersion"); + + return rs.getLong(1); + } + } + } + + @Override + public long add(Employee employee) throws PersistenceException { + String sql = "INSERT INTO Employee(version) VALUES(?)"; + + try { + Connection con = jdbcConnectionManager.getConnection(); + con.setAutoCommit(false); + + long versionId = createEmployeeVersion(con, employee); + + try (PreparedStatement pstmt = + con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + pstmt.setLong(1, versionId); + pstmt.executeUpdate(); + + try (ResultSet rs = pstmt.getGeneratedKeys()) { + if (!rs.next()) { + con.rollback(); + throw new PersistenceException("Failed to insert Employee"); + } + + con.commit(); + return rs.getLong(1); + } + } + } catch (SQLException e) { + jdbcConnectionManager.rollbackConnection(); + throw new PersistenceException(e); + } + } + + @Override + public void update(Employee employee) throws ElementNotFoundException, PersistenceException { + String sql = "UPDATE Employee SET version = ? WHERE id = ?"; + + try { + Connection con = jdbcConnectionManager.getConnection(); + con.setAutoCommit(false); + + long versionId = createEmployeeVersion(con, employee); + + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setLong(1, versionId); + pstmt.setLong(2, employee.id()); + + if (pstmt.executeUpdate() != 1) { + con.rollback(); + throw new ElementNotFoundException("No such employeeId exists"); + } + } + + con.commit(); + } catch (SQLException e) { + jdbcConnectionManager.rollbackConnection(); + throw new PersistenceException(e); + } + } + + @Override + public Set list() throws PersistenceException { + String sql = + "SELECT emp.id, v.name, v.birthday, v.educationLevel, v.isDriver, v.isPilot " + + "FROM employee emp " + + "JOIN EmployeeVersion v ON v.id = emp.version"; + + try { + Connection con = jdbcConnectionManager.getConnection(); + Set employees = new HashSet<>(); + + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + try (ResultSet rs = pstmt.executeQuery()) { + while (rs.next()) { + employees.add( + Employee.builder() + .id(rs.getLong(1)) + .name(rs.getString(2)) + .birthday(rs.getObject(3, LocalDate.class)) + .educationLevel(EducationLevel.valueOf(rs.getString(4))) + .isDriver(rs.getBoolean(5)) + .isPilot(rs.getBoolean(6)) + .build()); + } + } + } + + return employees; + } catch (SQLException e) { + throw new PersistenceException(e); + } + } + + @Override + public void remove(long id) throws ElementNotFoundException, PersistenceException { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAO.java new file mode 100644 index 0000000..c0ef5d4 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAO.java @@ -0,0 +1,48 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import java.util.EnumSet; +import java.util.Set; + +public interface OperationDAO { + + /** + * Persist the given operation. + * + * @param operation that should be stored + * @return the id that was assigned + * @throws PersistenceException if the operation could not be persisted + */ + long add(Operation operation) throws PersistenceException; + + /** + * Update the given operation. + * + * @param operation that should be updated + * @throws ElementNotFoundException if no operation with the given id exists + * @throws PersistenceException if the operation could not be updated + */ + void update(Operation operation) throws ElementNotFoundException, PersistenceException; + + /** + * Returns the operation with the given id. + * + * @param operationId id of the operation that should be returned + * @return operation with the given id + * @throws ElementNotFoundException if no operation with the given id exists + * @throws PersistenceException if the operation could not be loaded + */ + Operation get(long operationId) throws ElementNotFoundException, PersistenceException; + + /** + * Get all stored operations with matching status. + * + * @param statuses set containing all statuses that should be matched + * @return list containing all matched operations + * @throws PersistenceException if loading the stored operations failed + */ + Set list(EnumSet statuses) throws PersistenceException; +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java new file mode 100644 index 0000000..1641720 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java @@ -0,0 +1,221 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Severity; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.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; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; +import org.springframework.lang.NonNull; +import org.springframework.stereotype.Repository; + +@Repository +public class OperationDatabaseDAO implements OperationDAO { + + private JDBCConnectionManager jdbcConnectionManager; + private VehicleDAO vehicleDAO; + + public OperationDatabaseDAO( + JDBCConnectionManager jdbcConnectionManager, VehicleDAO vehicleDAO) { + this.jdbcConnectionManager = jdbcConnectionManager; + this.vehicleDAO = vehicleDAO; + } + + @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; + + 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.setObject(3, OffsetDateTime.ofInstant(o.created(), ZoneId.systemDefault())); + pstmt.setString(4, o.destination()); + pstmt.setString(5, o.additionalInfo()); + pstmt.setInt(6, o.status().ordinal()); + pstmt.executeUpdate(); + + try (ResultSet rs = pstmt.getGeneratedKeys()) { + if (!rs.next()) throw new PersistenceException("Failed to persist operation"); + + operationId = rs.getLong(1); + } + } + + try (PreparedStatement pstmt = con.prepareStatement(sql2)) { + pstmt.setLong(2, operationId); + + for (long id : (Iterable) o.vehicles().stream().map(Vehicle::id)::iterator) { + pstmt.setLong(1, id); + pstmt.addBatch(); + } + + pstmt.executeBatch(); + } + con.commit(); + return operationId; + } catch (SQLException e) { + jdbcConnectionManager.rollbackConnection(); + throw new PersistenceException(e); + } + } + + @Override + 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 = ?"; + 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"); + } + + 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) o.vehicles().stream().map(Vehicle::id)::iterator) { + pstmt.setLong(1, id); + pstmt.addBatch(); + } + + pstmt.executeBatch(); + } + con.commit(); + } catch (SQLException e) { + jdbcConnectionManager.rollbackConnection(); + throw new PersistenceException(e); + } + } + + @Override + public Operation get(long operationId) throws ElementNotFoundException, PersistenceException { + String sql = "Select * from operation where id = ?"; + + 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); + } + } + + @Override + public Set list(EnumSet statuses) throws PersistenceException { + // This hack exists because H2 currently has a bug that prevents IN (?) with an array of + // ids, i.e. pstmt.setArray(1, con.createArrayOf("INT", intarray) from working. See + // commented code below. + + // SELECT * FROM Operation WHERE status IN ('COMPLETED', 'CANCELLED') is BUGGED on H2! + // for this reason we use the ordinal values instead + String str = + statuses.stream() + .map(e -> Integer.toString(e.ordinal())) + .collect(Collectors.joining(",")); + + String sql = "SELECT * FROM Operation WHERE status IN (" + str + ")"; + Set operations = new HashSet<>(); + + try { + Connection con = jdbcConnectionManager.getConnection(); + + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + // Object[] arr = statuses.stream().map(Enum::ordinal).toArray(); + // pstmt.setArray(1, con.createArrayOf("INT", arr)); + + try (ResultSet rs = pstmt.executeQuery()) { + while (rs.next()) operations.add(operationFromRS(rs)); + } + } + + return operations; + } catch (SQLException e) { + throw new PersistenceException(e); + } + } + + private Operation operationFromRS(ResultSet rs) throws PersistenceException, SQLException { + Long operationId = rs.getLong("id"); + + return Operation.builder() + .id(operationId) + .opCode(rs.getString("opCode")) + .severity(Severity.valueOf(rs.getString("severity"))) + .status(Status.valueOf(rs.getString("status"))) + .vehicles(getVehiclesFromOperationId(operationId)) + .created((rs.getObject("created", OffsetDateTime.class)).toInstant()) + .destination(rs.getString("destination")) + .additionalInfo(rs.getString("additionalInfo")) + .build(); + } + + private Set getVehiclesFromOperationId(long operationId) throws PersistenceException { + String sql = "SELECT vehicleId FROM VehicleOperation WHERE operationId = ?"; + Set vehicles = new HashSet<>(); + + try { + Connection con = jdbcConnectionManager.getConnection(); + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setLong(1, operationId); + pstmt.execute(); + + try (ResultSet rs = pstmt.getResultSet()) { + while (rs.next()) { + vehicles.add(vehicleDAO.get(rs.getLong("vehicleId"))); + } + } + } + } catch (SQLException e) { + throw new PersistenceException(e); + } catch (ElementNotFoundException e) { + throw new PersistenceException("VehicleOperation contained nonexistent vehicle", e); + } + + return vehicles; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAO.java new file mode 100644 index 0000000..02e742c --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAO.java @@ -0,0 +1,28 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import java.util.Set; + +public interface RegistrationDAO { + + /** + * Persist the given registration. + * + * @param vehicleId the id of the target vehicle + * @param registrations that should be stored + * @return a list of the ids that were assigned + * @throws PersistenceException if the registration could not be persisted + */ + Set add(long vehicleId, Set registrations) throws PersistenceException; + + /** + * Make registration with the given id inactive. + * + * @param id of the registration that should be made inactive + * @throws ElementNotFoundException if no registration with the given id exists + * @throws PersistenceException if the registration could not be made inactive + */ + void remove(long id) throws ElementNotFoundException, PersistenceException; +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java new file mode 100644 index 0000000..1006a33 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java @@ -0,0 +1,130 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +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; +import java.sql.Statement; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +@Repository +public class RegistrationDatabaseDAO implements RegistrationDAO { + + private JDBCConnectionManager jdbcConnectionManager; + private EmployeeDAO employeePersistence; + + @Autowired + public RegistrationDatabaseDAO( + JDBCConnectionManager jdbcConnectionManager, EmployeeDAO employeePersistence) { + this.jdbcConnectionManager = jdbcConnectionManager; + this.employeePersistence = employeePersistence; + } + + @Override + public Set add(long vehicleId, Set registrations) + throws PersistenceException { + String sql = + "INSERT INTO Registration (vehicleId, employeeId, start, end, active) VALUES (?,?,?,?,?)"; + String sql2 = "UPDATE Vehicle SET status = 'FREI_WACHE' WHERE id = ?;"; + + Set vehicleIds = new HashSet<>(); + + try { + Connection con = jdbcConnectionManager.getConnection(); + con.setAutoCommit(false); + + try (PreparedStatement pstmt = + con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + pstmt.setLong(1, vehicleId); + + for (Registration r : registrations) { + pstmt.setLong(2, r.employee().id()); + pstmt.setObject(3, OffsetDateTime.ofInstant(r.start(), ZoneId.systemDefault())); + pstmt.setObject(4, OffsetDateTime.ofInstant(r.end(), ZoneId.systemDefault())); + pstmt.setBoolean(5, true); + pstmt.addBatch(); + } + + pstmt.executeBatch(); + + try (ResultSet rs = pstmt.getGeneratedKeys()) { + while (rs.next()) vehicleIds.add(rs.getLong(1)); + } + } + + try (PreparedStatement pstmt = con.prepareStatement(sql2)) { + pstmt.setLong(1, vehicleId); + if (pstmt.executeUpdate() != 1) { + con.rollback(); + throw new PersistenceException("Failed to persist registration"); + } + } + + con.commit(); + return vehicleIds; + } catch (SQLException e) { + jdbcConnectionManager.rollbackConnection(); + throw new PersistenceException(e); + } + } + + @Override + public void remove(long id) throws ElementNotFoundException, PersistenceException { + throw new UnsupportedOperationException(); + } + + protected List list(long vehicleId) throws PersistenceException { + String sql = "SELECT * FROM Registration WHERE vehicleId = ?"; + + List registrationList = new ArrayList<>(); + try { + Connection con = jdbcConnectionManager.getConnection(); + + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setLong(1, vehicleId); + + try (ResultSet rs = pstmt.executeQuery()) { + while (rs.next()) { + long employeeId = rs.getLong("employeeId"); + // TODO: replace the following with employeePersistence.get once implemented + Employee emp = + employeePersistence + .list() + .stream() + .filter(employee -> employee.id() == employeeId) + .findAny() + .orElse(null); + Registration registration = + Registration.builder() + .id(rs.getLong("id")) + .start( + (rs.getObject("start", OffsetDateTime.class)) + .toInstant()) + .end( + (rs.getObject("end", OffsetDateTime.class)) + .toInstant()) + .employee(emp) + .build(); + registrationList.add(registration); + } + } + } + + return registrationList; + } catch (SQLException e) { + throw new PersistenceException(e); + } + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAO.java new file mode 100644 index 0000000..ed24498 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAO.java @@ -0,0 +1,54 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import java.util.Set; + +public interface VehicleDAO { + + /** + * Persist the given vehicle. + * + * @param vehicle that should be stored + * @return the id that was assigned + * @throws PersistenceException if the vehicle could not be persisted + */ + long add(Vehicle vehicle) throws PersistenceException; + + /** + * Update the given vehicle. + * + * @param vehicle that should be updated + * @throws ElementNotFoundException if no vehicle with the given id exists + * @throws PersistenceException if the vehicle could not be updated + */ + void update(Vehicle vehicle) throws ElementNotFoundException, PersistenceException; + + /** + * Get all stored vehicles. + * + * @return list containing all stored vehicles + * @throws PersistenceException if loading the stored vehicles failed + */ + Set list() throws PersistenceException; + + /** + * Returns the vehicle with the given id. + * + * @param vehicleId id of the vehicle that should be returned + * @return vehicle with the given id + * @throws ElementNotFoundException if no vehicle with the given id exists + * @throws PersistenceException if the vehicle could not be loaded + */ + Vehicle get(long vehicleId) throws ElementNotFoundException, PersistenceException; + + /** + * Remove vehicle with the given id from the store. + * + * @param id of the vehicle that should be removed + * @throws ElementNotFoundException if no vehicle with the given id exists + * @throws PersistenceException if the vehicle could not be removed + */ + void remove(long id) throws ElementNotFoundException, PersistenceException; +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java new file mode 100644 index 0000000..dd7c0f2 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java @@ -0,0 +1,211 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.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.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.HashSet; +import java.util.Set; +import org.springframework.stereotype.Repository; + +@Repository +public class VehicleDatabaseDAO implements VehicleDAO { + + private final JDBCConnectionManager jdbcConnectionManager; + private RegistrationDatabaseDAO registrationDatabaseDao; + + public VehicleDatabaseDAO( + JDBCConnectionManager j, RegistrationDatabaseDAO registrationDatabaseDao) { + jdbcConnectionManager = j; + this.registrationDatabaseDao = registrationDatabaseDao; + } + + @Override + public long add(Vehicle v) throws PersistenceException { + String sql = + "INSERT INTO VehicleVersion (name,hasNef,constructionType,type) VALUES (?,?,?,?)"; + String sql2 = "INSERT INTO Vehicle (version,status) VALUES (?,?)"; + String sql3 = "UPDATE VehicleVersion SET name=? WHERE id=?"; + + try { + Connection con = jdbcConnectionManager.getConnection(); + con.setAutoCommit(false); + String name = ""; + long version, id; + + try (PreparedStatement pstmt = + con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + pstmt.setString(1, name); + pstmt.setBoolean(2, v.hasNef()); + pstmt.setInt(3, v.constructionType().ordinal()); + pstmt.setString(4, v.type().name()); + pstmt.executeUpdate(); + + try (ResultSet rs = pstmt.getGeneratedKeys()) { + if (!rs.next()) + throw new PersistenceException("Failed to insert into VehicleVersion"); + + version = rs.getLong(1); + } + } + + try (PreparedStatement pstmt = + con.prepareStatement(sql2, Statement.RETURN_GENERATED_KEYS)) { + pstmt.setLong(1, version); + pstmt.setInt(2, Status.ABGEMELDET.ordinal()); + pstmt.executeUpdate(); + + try (ResultSet rs = pstmt.getGeneratedKeys()) { + if (!rs.next()) { + con.rollback(); + throw new PersistenceException("Failed to insert into Vehicle"); + } + + id = rs.getLong(1); + } + + name = v.type().name() + "-" + id; + } + + try (PreparedStatement pstmt = con.prepareStatement(sql3)) { + pstmt.setString(1, name); + pstmt.setLong(2, version); + + if (pstmt.executeUpdate() != 1) { + con.rollback(); + throw new PersistenceException("Failed to update VehicleVersion"); + } + } + + con.commit(); + return id; + } catch (SQLException e) { + jdbcConnectionManager.rollbackConnection(); + throw new PersistenceException(e); + } + } + + @Override + public void update(Vehicle v) throws ElementNotFoundException, PersistenceException { + String sql = "SELECT version FROM Vehicle WHERE id = ?"; + String sql2 = + "MERGE INTO VehicleVersion(name, constructionType, type, hasNef)" + + " KEY(name, constructionType, type, hasNef) VALUES(?, ?, ?, ?)"; + String sql3 = "UPDATE Vehicle SET version = ?, status = ? WHERE id = ?"; + + long versionId; + + try { + Connection con = jdbcConnectionManager.getConnection(); + con.setAutoCommit(false); + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setLong(1, v.id()); + + try (ResultSet rs = pstmt.executeQuery()) { + if (!rs.next()) throw new ElementNotFoundException("No such vehicleId exists"); + + versionId = rs.getLong(1); + } + } + + try (PreparedStatement pstmt = + con.prepareStatement(sql2, Statement.RETURN_GENERATED_KEYS)) { + pstmt.setString(1, v.type().name() + "-" + v.id()); + pstmt.setString(2, v.constructionType().name()); + pstmt.setString(3, v.type().name()); + pstmt.setBoolean(4, v.hasNef()); + pstmt.executeUpdate(); + + try (ResultSet rs = pstmt.getGeneratedKeys()) { + if (rs.next()) { + // version changed, update it + versionId = rs.getLong(1); + } + } + } + + try (PreparedStatement pstmt = con.prepareStatement(sql3)) { + pstmt.setLong(1, versionId); + pstmt.setString(2, v.status().name()); + pstmt.setLong(3, v.id()); + pstmt.executeUpdate(); + } + + con.commit(); + } catch (SQLException e) { + jdbcConnectionManager.rollbackConnection(); + throw new PersistenceException(e); + } + } + + @Override + public Set list() throws PersistenceException { + Set result = new HashSet<>(); + + String sql = + "Select * from VehicleVersion, Vehicle where VehicleVersion.id=Vehicle.version"; + + try (PreparedStatement pstmt = + jdbcConnectionManager.getConnection().prepareStatement(sql)) { + pstmt.executeQuery(); + try (ResultSet rs = pstmt.getResultSet()) { + while (rs.next()) { + result.add(vehicleFromRS(rs)); + } + } + } catch (SQLException e) { + throw new PersistenceException(e); + } + return result; + } + + @Override + public Vehicle get(long id) throws ElementNotFoundException, PersistenceException { + String sql = + "SELECT a.id, b.name, b.constructionType, b.type, a.status, b.hasNef" + + " FROM Vehicle a" + + " INNER JOIN VehicleVersion b" + + " ON version = b.id" + + " WHERE a.id = ?"; + + try { + Connection con = jdbcConnectionManager.getConnection(); + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setLong(1, id); + + try (ResultSet rs = pstmt.executeQuery()) { + if (!rs.first()) throw new ElementNotFoundException("No such vehicle exists"); + + return vehicleFromRS(rs); + } + } + } catch (SQLException e) { + throw new PersistenceException(e); + } + } + + @Override + public void remove(long id) throws ElementNotFoundException, PersistenceException { + throw new UnsupportedOperationException(); + } + + private Vehicle vehicleFromRS(ResultSet rs) throws SQLException, PersistenceException { + return Vehicle.builder() + .id(rs.getLong("Vehicle.id")) + .name(rs.getString("name")) + .constructionType(ConstructionType.values()[rs.getInt("constructionType")]) + .type(VehicleType.valueOf(rs.getString("type"))) + .status(Status.values()[rs.getInt("status")]) + .hasNef(rs.getBoolean("hasNef")) + .registrations(registrationDatabaseDao.list(rs.getLong("id"))) + .build(); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Employee.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Employee.java new file mode 100644 index 0000000..f45550e --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Employee.java @@ -0,0 +1,51 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import com.google.auto.value.AutoValue; +import java.time.LocalDate; + +@AutoValue +public abstract class Employee { + public enum EducationLevel { + RS, + NFS, + NKV, + NKA, + NKI, + NA + } + + public abstract long id(); + + public abstract String name(); + + public abstract LocalDate birthday(); + + public abstract EducationLevel educationLevel(); + + public abstract boolean isDriver(); + + public abstract boolean isPilot(); + + public static Builder builder() { + return new AutoValue_Employee.Builder().id(0); + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder id(long id); + + public abstract Builder name(String name); + + public abstract Builder birthday(LocalDate birthday); + + public abstract Builder educationLevel(EducationLevel educationLevel); + + public abstract Builder isDriver(boolean isDriver); + + public abstract Builder isPilot(boolean isPilot); + + public abstract Employee build(); + } + + public abstract Builder toBuilder(); +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/EmployeeValidator.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/EmployeeValidator.java new file mode 100644 index 0000000..b03fa04 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/EmployeeValidator.java @@ -0,0 +1,23 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; + +public class EmployeeValidator { + + public static boolean validate(Employee employee) throws InvalidEmployeeException { + + if (employee.name() == null || employee.name().trim().length() == 0) { + throw new InvalidEmployeeException("Name darf nicht leer sein!"); + } + + if (employee.birthday() == null) { + throw new InvalidEmployeeException("Geburtsdatum darf nicht leer sein!"); + } + + if (employee.educationLevel() == null) { + throw new InvalidEmployeeException("Ausbildungsgrad darf nicht leer sein!"); + } + + return true; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Operation.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Operation.java new file mode 100644 index 0000000..e119622 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Operation.java @@ -0,0 +1,70 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import com.google.auto.value.AutoValue; +import java.time.Instant; +import java.util.Set; +import javax.annotation.Nullable; + +@AutoValue +public abstract class Operation { + public enum Severity { + A, + B, + C, + D, + E, + O, + } + + public enum Status { + ACTIVE, + COMPLETED, + CANCELLED, + } + + public abstract long id(); + + public abstract String opCode(); + + @Nullable + public abstract Severity severity(); + + public abstract Status status(); + + public abstract Set vehicles(); + + @Nullable + public abstract Instant created(); + + public abstract String destination(); + + @Nullable + public abstract String additionalInfo(); + + public static Builder builder() { + return new AutoValue_Operation.Builder().id(0); + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder id(long id); + + public abstract Builder opCode(String opCode); + + public abstract Builder severity(Severity severity); + + public abstract Builder status(Status status); + + public abstract Builder vehicles(Set vehicles); + + public abstract Builder created(Instant created); + + public abstract Builder destination(String destination); + + public abstract Builder additionalInfo(String additionalInfo); + + public abstract Operation build(); + } + + public abstract Builder toBuilder(); +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Registration.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Registration.java new file mode 100644 index 0000000..a12c038 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Registration.java @@ -0,0 +1,34 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import com.google.auto.value.AutoValue; +import java.time.Instant; + +@AutoValue +public abstract class Registration { + public abstract long id(); + + public abstract Instant start(); + + public abstract Instant end(); + + public abstract Employee employee(); + + public static Builder builder() { + return new AutoValue_Registration.Builder().id(0); + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder id(long id); + + public abstract Builder start(Instant start); + + public abstract Builder end(Instant end); + + public abstract Builder employee(Employee employee); + + public abstract Registration build(); + } + + public abstract Builder toBuilder(); +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/RegistrationValidator.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/RegistrationValidator.java new file mode 100644 index 0000000..9512f64 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/RegistrationValidator.java @@ -0,0 +1,174 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.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 java.util.Set; + +public class RegistrationValidator { + + private RegistrationValidator() {} + + public static void validate(Vehicle vehicle, Set 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 pilotIds = new LinkedList<>(); + List driverIds = new LinkedList<>(); + List naIds = new LinkedList<>(); + List nfsIds = new LinkedList<>(); + List rsIds = new LinkedList<>(); + HashMap 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) { + throw new InvalidRegistrationException( + "Person mit der ID: " + + registration.employee().id() + + " wurde mehrmals hinzugefügt!"); + } + 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) { + 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) { + throw new InvalidRegistrationException("Zu wenig Personal für NAH!"); + } else if (total > 4) { + 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; + return; + } + found.put(na_id, false); + } + found.put(pilot_id, false); + } + 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) { + throw new InvalidRegistrationException("Zu wenig Personal für NEF!"); + } else if (total > 3) { + 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; + return; + } + found.put(driver_id, false); + } + throw new InvalidRegistrationException( + "Keine gültige Kombination von Personen für NEF!"); + } else if (vehicle.type() == VehicleType.BKTW) { + /* + BKTW + 1 Driver + */ + if (total > 3) { + throw new InvalidRegistrationException("Zu viel Personal für BKTW!"); + } + if (!driverIds.isEmpty()) { + return; + } + 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) { + throw new InvalidRegistrationException( + "Zu wenig Personal für " + vehicle.type().name() + "!"); + } else if (total > 4) { + 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; + return; + } + } + 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/missioncontrol/dto/Vehicle.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Vehicle.java new file mode 100644 index 0000000..c2033f5 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Vehicle.java @@ -0,0 +1,73 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import com.google.auto.value.AutoValue; +import java.util.List; +import javax.annotation.Nullable; + +@AutoValue +public abstract class Vehicle { + public enum ConstructionType { + NORMAL, + HOCHDACH, + MITTELHOCHDACH, + } + + public enum VehicleType { + BKTW, + KTW_B, + KTW, + RTW, + NEF, + NAH, + } + + public enum Status { + ABGEMELDET, + FREI_WACHE, + FREI_FUNK, + ZUM_BERUFUNGSORT, + AM_BERUFUNGSORT, + ZUM_ZIELORT, + AM_ZIELORT, + } + + public abstract long id(); + + public abstract String name(); + + public abstract ConstructionType constructionType(); + + public abstract VehicleType type(); + + public abstract Status status(); + + public abstract boolean hasNef(); + + @Nullable + public abstract List registrations(); + + public static Builder builder() { + return new AutoValue_Vehicle.Builder().id(0); + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder id(long id); + + public abstract Builder name(String name); + + public abstract Builder constructionType(ConstructionType constructionType); + + public abstract Builder type(VehicleType type); + + public abstract Builder status(Status status); + + public abstract Builder hasNef(boolean hasNef); + + public abstract Builder registrations(List registrations); + + public abstract Vehicle build(); + } + + public abstract Builder toBuilder(); +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeService.java new file mode 100644 index 0000000..fa4d0e6 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeService.java @@ -0,0 +1,46 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.util.Set; + +public interface EmployeeService { + + /** + * Add given employee to the store. + * + * @param employee that should be added to the store + * @return the id that was assigned + * @throws InvalidEmployeeException if the employee is invalid + * @throws ServiceException if the employee could not be persisted + */ + long add(Employee employee) throws InvalidEmployeeException, ServiceException; + + /** + * Update the given employee. + * + * @param employee that should be updated + * @return the updated employee + * @throws InvalidEmployeeException if the employee is invalid + * @throws ServiceException if the updated employee could not be persisted + */ + Employee update(Employee employee) throws InvalidEmployeeException, ServiceException; + + /** + * Get all stored employees. + * + * @return list containing all stored employees + * @throws ServiceException if loading the stored employees failed + */ + Set list() throws ServiceException; + + /** + * Remove employee with the given id from the store. + * + * @param id of the employee that should be removed + * @throws InvalidEmployeeException if given employee id is invalid or does not exist + * @throws ServiceException if the employee could not be removed from the store + */ + void remove(long id) throws InvalidEmployeeException, ServiceException; +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceImpl.java new file mode 100644 index 0000000..945fb49 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceImpl.java @@ -0,0 +1,59 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.EmployeeDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.EmployeeValidator; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.util.Set; +import org.springframework.stereotype.Service; + +@Service +public class EmployeeServiceImpl implements EmployeeService { + + private final EmployeeDAO employeePersistence; + + public EmployeeServiceImpl(EmployeeDAO employeePersistence) { + this.employeePersistence = employeePersistence; + } + + @Override + public long add(Employee employee) throws InvalidEmployeeException, ServiceException { + + EmployeeValidator.validate(employee); + try { + return employeePersistence.add(employee); + } catch (PersistenceException e) { + throw new ServiceException(e); + } + } + + @Override + public Employee update(Employee employee) throws InvalidEmployeeException, ServiceException { + + EmployeeValidator.validate(employee); + try { + employeePersistence.update(employee); + return employee; + } catch (ElementNotFoundException | PersistenceException e) { + throw new ServiceException(e); + } + } + + @Override + public Set list() throws ServiceException { + + try { + return employeePersistence.list(); + } catch (PersistenceException e) { + throw new ServiceException(e); + } + } + + @Override + public void remove(long id) throws InvalidEmployeeException, ServiceException { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationService.java new file mode 100644 index 0000000..ca1dce9 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationService.java @@ -0,0 +1,70 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +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.ServiceException; +import java.util.EnumSet; +import java.util.Set; +import java.util.SortedSet; + +public interface OperationService { + + /** + * Add given operation to the store. + * + * @param operation that should be added to the store + * @return the id that was assigned + * @throws InvalidOperationException if the operation is invalid + * @throws ServiceException if the operation could not be persisted + */ + long add(Operation operation) throws InvalidOperationException, ServiceException; + + /** + * Request new vehicles to the given operation. + * + * @param operationId id of the operation that the vehicles should be send to + * @param vehicleIds the ids of the vehicles that should be send to the given operation + * @throws InvalidOperationException if the operationId is invalid or does not exist + * @throws InvalidVehicleException if one of the vehicle ids is invalid or does not exist + * @throws ServiceException if the vehicles could not be loaded or the operation could not be + * persisted + */ + void requestVehicles(long operationId, Set vehicleIds) + throws InvalidOperationException, InvalidVehicleException, ServiceException; + + /** + * Completes the given operation with the specified status. + * + * @param operationId id of the operation that should be completed + * @param status of the completed operation, either {@link Status#COMPLETED} or {@link + * Status#CANCELLED} + * @throws InvalidOperationException if the operationId is invalid or does not exist + * @throws ServiceException if the operation could not be persisted + */ + void complete(long operationId, Status status) + throws InvalidOperationException, ServiceException; + + /** + * Get all available vehicles, sorted by how well they fit to the given opCode, starting with + * the best fitting. + * + * @param opCode the operation code that is used to determine the ranking + * @return a sorted list containing all available vehicles + * @throws InvalidOperationException if the opCode is invalid + * @throws ServiceException if loading the stored vehicles failed + */ + SortedSet rankVehicles(String opCode) + throws InvalidOperationException, ServiceException; + + /** + * Get all stored operations with matching status. + * + * @param statuses set containing all statuses that should be matched + * @return list containing all matched operations + * @throws ServiceException if loading the stored operations failed + */ + Set list(EnumSet statuses) throws ServiceException; +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceImpl.java new file mode 100644 index 0000000..baae598 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceImpl.java @@ -0,0 +1,286 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.OperationDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Severity; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType; +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.ArrayList; +import java.util.Comparator; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +@Service +public class OperationServiceImpl implements OperationService { + + private static final Logger LOG = LoggerFactory.getLogger(OperationServiceImpl.class); + + private final OperationDAO operationDAO; + private final VehicleDAO vehicleDAO; + private final VehicleService vehicleService; + + public OperationServiceImpl( + OperationDAO operationDAO, VehicleDAO vehicleDAO, VehicleService vehicleService) { + this.operationDAO = operationDAO; + this.vehicleDAO = vehicleDAO; + this.vehicleService = vehicleService; + } + + @Override + public long add(Operation o) throws InvalidOperationException, ServiceException { + if (o.created() != null) { + throw new InvalidOperationException("Erstellungszeitpunkt darf nicht gesetzt sein"); + } + + if (o.severity() != null) { + throw new InvalidOperationException("Der Schweregrad darf nicht gesetzt sein"); + } + + if (o.id() != 0) { + throw new InvalidOperationException("Einsatz-ID muss 0 sein"); + } + + if (o.status() != Status.ACTIVE) + LOG.info("Status was set but will be overridden"); // TODO: nullable instead?? + + try { + for (long id : (Iterable) o.vehicles().stream().map(Vehicle::id)::iterator) { + Vehicle v = vehicleDAO.get(id); + VehicleServiceImpl.validateVehicle(v); + + if (v.status() != Vehicle.Status.FREI_FUNK + && v.status() != Vehicle.Status.FREI_WACHE) + throw new InvalidOperationException("Fahrzeug nicht verfügbar: " + v.status()); + } + + validateOperation(o); + + return operationDAO.add( + o.toBuilder() + .created(Instant.now()) + .severity(extractSeverityFromOpCode(o.opCode())) + .status(Status.ACTIVE) + .build()); + } catch (PersistenceException e) { + throw new ServiceException(e); + } catch (InvalidVehicleException e) { + // already logged as invalid vehicle + throw new InvalidOperationException("Enthaltenes Fahrzeug ist ungültig", e); + } catch (ElementNotFoundException e) { + throw new InvalidOperationException("Enthaltenes Fahrzeug existiert nicht", e); + } + } + + @Override + public void requestVehicles(long operationId, Set vehicleIds) + throws InvalidOperationException, InvalidVehicleException, ServiceException { + Set vs = new HashSet<>(); + + try { + if (operationId <= 0) { + throw new InvalidOperationException("Einsatz-ID ist ungültig"); + } + Operation o = operationDAO.get(operationId); + validateOperation(o); + + if (o.opCode().trim().isEmpty() + || extractSeverityFromOpCode(o.opCode()) != o.severity()) { + throw new InvalidOperationException("Einsatzcode ist ungültig"); + } + + if (o.status() != Status.ACTIVE) { + throw new InvalidOperationException("Einsatz ist ungültig"); + } + + if (o.created() == null) { + throw new InvalidOperationException("Erstellungszeitpunkt darf nicht leer sein"); + } + + for (Long id : vehicleIds) { + if (id <= 0) { + throw new InvalidVehicleException("Fahrzeug-ID ist ungültig"); + } + + try { + Vehicle v = vehicleDAO.get(id); + VehicleServiceImpl.validateVehicle(v); + if (v.status() != Vehicle.Status.FREI_FUNK + && v.status() != Vehicle.Status.FREI_WACHE) + throw new InvalidOperationException( + "Fahrzeug nicht verfügbar: " + v.status()); + + vs.add(v); + } catch (ElementNotFoundException e) { + throw new InvalidVehicleException("VehicleId ist invalid"); + } + } + + vs.addAll(o.vehicles()); + if (vs.equals(o.vehicles())) return; + + operationDAO.update(o.toBuilder().vehicles(vs).build()); + } catch (ElementNotFoundException e) { + throw new InvalidOperationException("Kein Einsatz mit dieser ID existiert"); + } catch (PersistenceException e) { + throw new ServiceException(e); + } + } + + @Override + public void complete(long operationId, Status status) + throws InvalidOperationException, ServiceException { + try { + Operation o = operationDAO.get(operationId); + operationDAO.update(o.toBuilder().status(status).build()); + } catch (ElementNotFoundException e) { + throw new InvalidOperationException(e); + } catch (PersistenceException e) { + throw new ServiceException(e); + } + } + + @Override + public SortedSet rankVehicles(String opCode) + throws InvalidOperationException, ServiceException { + Set vehicles = + vehicleService.list(EnumSet.complementOf(EnumSet.of(Vehicle.Status.ABGEMELDET))); + + List> priorities = new ArrayList<>(); + Predicate ktw = v -> v.type() == VehicleType.KTW; + Predicate rtwNoNEF = v -> v.type() == VehicleType.RTW && !v.hasNef(); + Predicate rtwNEF = v -> v.type() == VehicleType.RTW && v.hasNef(); + Predicate nef = v -> v.type() == VehicleType.NEF; + Predicate nah = v -> v.type() == VehicleType.NAH; + + switch (extractSeverityFromOpCode(opCode)) { + case A: + // fallthrough + case B: + // fallthrough + case O: + priorities.add(ktw); + priorities.add(rtwNoNEF); + priorities.add(rtwNEF); + break; + case C: + priorities.add(rtwNEF); + priorities.add(rtwNoNEF); + priorities.add(ktw); + break; + case D: + priorities.add(rtwNEF); + priorities.add(nef); + priorities.add(nah); + priorities.add(rtwNoNEF); + priorities.add(ktw); + break; + case E: + priorities.add(nah); + priorities.add(nef); + priorities.add(rtwNEF); + priorities.add(rtwNoNEF); + priorities.add(ktw); + break; + } + + Comparator vehicleComparator = + (v1, v2) -> { + for (Predicate priority : priorities) { + if (priority.test(v1)) { + return -1; + } + if (priority.test(v2)) { + return +1; + } + } + return 0; + }; + + Supplier> supplier = () -> new TreeSet<>(vehicleComparator); + + return vehicles.stream().collect(Collectors.toCollection(supplier)); + } + + @Override + public Set list(EnumSet statuses) throws ServiceException { + try { + Set operations = operationDAO.list(statuses); + for (Operation o : operations) validateOperation(o); + + return operations; + } catch (PersistenceException e) { + throw new ServiceException(e); + } catch (InvalidOperationException e) { + // database returned invalid values + throw new ServiceException("DB returned invalid operation", e); + } + } + + private static void validateOperation(Operation o) throws InvalidOperationException { + 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 ungültig", e); + } + + // TODO: validate if NEF/RTW/NAH conditions? + } + + Instant created = o.created(); + if (created != null && created.isAfter(Instant.now())) { + throw new InvalidOperationException("Einsatz wurde in der Zukunft erstellt"); + } + + if (o.destination() == null || o.destination().trim().isEmpty()) { + throw new InvalidOperationException("Adresse darf nicht leer sein"); + } + + if (o.destination().length() > 100) { + throw new InvalidOperationException("Adresse darf 100 Zeichen nicht überschreiten"); + } + + if (o.additionalInfo() != null && o.additionalInfo().length() > 100) { + throw new InvalidOperationException("Anmerkung darf 100 Zeichen nicht überschreiten"); + } + } + + private static final Pattern opCodePattern = + Pattern.compile("(?:\\w{1,3}-\\d{0,2})([ABCDEO])(?:.*)"); + + private static Severity extractSeverityFromOpCode(String opCode) + throws InvalidOperationException { + Matcher m = opCodePattern.matcher(opCode); + + if (!m.matches()) { + throw new InvalidOperationException("Einsatzcode ist ungültig"); + } + + return Severity.valueOf(m.group(1)); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationService.java new file mode 100644 index 0000000..027417f --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationService.java @@ -0,0 +1,32 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +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.ServiceException; +import java.util.Set; + +public interface RegistrationService { + + /** + * Register employee to a vehicle. + * + * @param vehicleId the id of the target vehicle + * @param registrations that should be added to the vehicle + * @return the list of ids that were assigned + * @throws InvalidVehicleException if the vehicleId is invalid or does not exist + * @throws InvalidRegistrationException if the registration is invalid + * @throws ServiceException if the registration could not be persisted + */ + Set add(long vehicleId, Set registrations) + throws InvalidVehicleException, InvalidRegistrationException, ServiceException; + + /** + * Remove given registration from the store. + * + * @param registrationId the id of the registration that should be removed + * @throws InvalidRegistrationException if the registration is invalid or does not exist + * @throws ServiceException if the registration could not be removed from the store + */ + void remove(long registrationId) throws InvalidRegistrationException, ServiceException; +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java new file mode 100644 index 0000000..3ec69e7 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java @@ -0,0 +1,52 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.RegistrationDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.RegistrationValidator; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +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.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class RegistrationServiceImpl implements RegistrationService { + + private final RegistrationDAO registrationDAO; + private final VehicleDAO vehicleDAO; + + @Autowired + public RegistrationServiceImpl(RegistrationDAO registrationDAO, VehicleDAO vehicleDAO) { + this.registrationDAO = registrationDAO; + this.vehicleDAO = vehicleDAO; + } + + @Override + public Set add(long vehicleId, Set registrations) + throws InvalidVehicleException, InvalidRegistrationException, ServiceException { + + if (vehicleId <= 0) throw new InvalidVehicleException("VehicleId invalid"); + + try { + Vehicle vehicle = vehicleDAO.get(vehicleId); + + RegistrationValidator.validate(vehicle, registrations); + + return registrationDAO.add(vehicle.id(), registrations); + } catch (PersistenceException e) { + throw new ServiceException(e); + } catch (ElementNotFoundException e) { + throw new InvalidVehicleException(e); + } + } + + @Override + public void remove(long registrationId) throws InvalidRegistrationException, ServiceException { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleService.java new file mode 100644 index 0000000..d96dfb7 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleService.java @@ -0,0 +1,49 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.util.EnumSet; +import java.util.Set; + +public interface VehicleService { + + /** + * Add given vehicle to the store. + * + * @param vehicle that should be added to the store + * @return the id that was assigned + * @throws InvalidVehicleException if the vehicle is invalid + * @throws ServiceException if the vehicle could not be persisted + */ + long add(Vehicle vehicle) throws InvalidVehicleException, ServiceException; + + /** + * Update the given vehicle. + * + * @param vehicle that should be updated + * @return the updated vehicle + * @throws InvalidVehicleException if the vehicle is invalid + * @throws ServiceException if the updated vehicle could not be persisted + */ + Vehicle update(Vehicle vehicle) throws InvalidVehicleException, ServiceException; + + /** + * Get all stored vehicles with matching status. + * + * @param statuses set containing all statuses that should be matched + * @return list containing all stored vehicles + * @throws ServiceException if loading the stored vehicles failed + */ + Set list(EnumSet statuses) throws ServiceException; + + /** + * Remove vehicle with the given id from the store. + * + * @param id of the vehicle that should be removed + * @throws InvalidVehicleException if given vehicle id is invalid or does not exist + * @throws ServiceException if the vehicle could not be removed from the store + */ + void remove(long id) throws InvalidVehicleException, ServiceException; +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleServiceImpl.java new file mode 100644 index 0000000..6a035c6 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleServiceImpl.java @@ -0,0 +1,116 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +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.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 { + + private VehicleDAO vehiclePersistence; + + public VehicleServiceImpl(VehicleDAO vehiclePersistence) { + this.vehiclePersistence = vehiclePersistence; + } + + public long add(Vehicle vehicle) throws InvalidVehicleException, ServiceException { + if (!CollectionUtils.isEmpty(vehicle.registrations())) { + throw new InvalidVehicleException( + "Fahrzeug kann nicht mit Anmeldungen erstellt werden"); + } + + validateVehicle(vehicle); + try { + vehiclePersistence.add(vehicle); + } catch (PersistenceException e) { + throw new ServiceException(e); + } + return 0; + } + + public Vehicle update(Vehicle vehicle) throws InvalidVehicleException, ServiceException { + validateVehicle(vehicle); + try { + vehiclePersistence.update(vehicle); + } catch (ElementNotFoundException e) { + throw new ServiceException("Element not found", e); + } catch (PersistenceException e) { + throw new ServiceException(e); + } + return vehicle; + } + + protected static void validateVehicle(Vehicle vehicle) throws InvalidVehicleException { + switch (vehicle.type()) { + case RTW: + if (vehicle.constructionType() == ConstructionType.NORMAL) { + throw new InvalidVehicleException("RTW darf kein Normales Dach haben"); + } else if (vehicle.constructionType() == ConstructionType.MITTELHOCHDACH) { + throw new InvalidVehicleException("RTW darf kein Mittelhochdach haben"); + } + break; + case KTW: + if (vehicle.constructionType() == ConstructionType.NORMAL) { + throw new InvalidVehicleException("KTW darf kein Normales Dach haben"); + } + break; + case KTW_B: + if (vehicle.constructionType() == ConstructionType.NORMAL) { + throw new InvalidVehicleException("KTW-B darf kein Normales Dach haben"); + } + break; + case NEF: + if (vehicle.constructionType() == ConstructionType.MITTELHOCHDACH) { + throw new InvalidVehicleException("NEF darf kein Mittelhochdach haben"); + } else if (vehicle.constructionType() == ConstructionType.HOCHDACH) { + throw new InvalidVehicleException("NEF darf kein Hochdach haben"); + } + break; + case NAH: + if (vehicle.constructionType() == ConstructionType.MITTELHOCHDACH) { + throw new InvalidVehicleException("NEF darf kein Mittelhochdach haben"); + } else if (vehicle.constructionType() == ConstructionType.HOCHDACH) { + throw new InvalidVehicleException("NEF darf kein Hochdach haben"); + } + break; + case BKTW: + break; + default: + throw new IllegalStateException("BUG: invalid vehicle type" + vehicle.type()); + } + } + + @Override + public Set list(EnumSet statuses) throws ServiceException { + if (statuses == null) { + throw new ServiceException("Statuses may not be null"); + } + + Set vehicles; + + try { + vehicles = vehiclePersistence.list(); + } catch (PersistenceException e) { + throw new ServiceException(e); + } + + return vehicles.stream() + .filter(vehicle -> statuses.contains(vehicle.status())) + .collect(Collectors.toSet()); + } + + @Override + public void remove(long id) throws InvalidVehicleException, ServiceException { + throw new UnsupportedOperationException(); + } +} -- cgit v1.2.3-70-g09d2 From 2f89d8530f716b346b1985c6b59ba9e58cdf13d6 Mon Sep 17 00:00:00 2001 From: Dominic Rogetzer Date: Mon, 18 Jun 2018 20:44:31 +0200 Subject: Reuse images in EmployeeListItemController [#25963] --- .../controller/EmployeeListItemController.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListItemController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListItemController.java index 543fe0d..d445b43 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListItemController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListItemController.java @@ -30,6 +30,12 @@ public class EmployeeListItemController extends CustomListItemController { private Consumer consumerEmployeeClicked; private Consumer consumerEmployeeListItemClicked; + private static Image imageQualification = new Image("/images/Qualification.png"); + private static Image imagePilot = new Image("/images/Pilot.png"); + private static Image imageNotPilot = new Image("/images/NotPilot.png"); + private static Image imageDriver = new Image("images/Driver.png"); + private static Image imageNotDriver = new Image("images/NotDriver.png"); + @FXML private void onEmployeeClicked() { if (consumerEmployeeClicked != null) { @@ -46,13 +52,9 @@ public class EmployeeListItemController extends CustomListItemController { lblQualification.setText(employee.educationLevel().name()); lblPilot.setText(String.format("%s Pilot", employee.isPilot() ? "ist" : "nicht")); lblDriver.setText(String.format("%s Fahrer", employee.isDriver() ? "ist" : "nicht")); - imgQualification.setImage(new Image("/images/Qualification.png")); - String imgSrcPilot = - String.format("/images/%s", employee.isPilot() ? "Pilot.png" : "NotPilot.png"); - imgPilot.setImage(new Image(imgSrcPilot)); - String imgSrcDriver = - String.format("/images/%s", employee.isDriver() ? "Driver.png" : "NotDriver.png"); - imgDriver.setImage(new Image(imgSrcDriver)); + imgQualification.setImage(imageQualification); + imgPilot.setImage(employee.isPilot() ? imagePilot : imageNotPilot); + imgDriver.setImage(employee.isDriver() ? imageDriver : imageNotDriver); } public static EmployeeListItemController createEmployeeListItemController( -- cgit v1.2.3-70-g09d2 From 41eaffacce8c35e517ec5a1e7a914858a0717a1d Mon Sep 17 00:00:00 2001 From: Tharre Date: Mon, 18 Jun 2018 21:30:50 +0200 Subject: Sort imports after rename --- .../missioncontrol/controller/ArchiveOperationController.java | 2 +- .../missioncontrol/controller/CreateCarController.java | 4 ++-- .../missioncontrol/controller/CreateNewEmployeeController.java | 4 ++-- .../missioncontrol/controller/CreateOperationController.java | 6 +++--- .../missioncontrol/controller/ManageEmployeesController.java | 2 +- .../missioncontrol/controller/OperationDetailsController.java | 6 +++--- .../controller/RegistrationWindowController.java | 6 +++--- .../assignment/groupphase/missioncontrol/dao/EmployeeDAO.java | 2 +- .../groupphase/missioncontrol/dao/EmployeeDatabaseDAO.java | 4 ++-- .../assignment/groupphase/missioncontrol/dao/OperationDAO.java | 4 ++-- .../groupphase/missioncontrol/dao/OperationDatabaseDAO.java | 4 ++-- .../groupphase/missioncontrol/dao/RegistrationDAO.java | 2 +- .../groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java | 4 ++-- .../assignment/groupphase/missioncontrol/dao/VehicleDAO.java | 2 +- .../groupphase/missioncontrol/dao/VehicleDatabaseDAO.java | 4 ++-- .../groupphase/missioncontrol/dto/RegistrationValidator.java | 4 ++-- .../groupphase/missioncontrol/service/EmployeeService.java | 2 +- .../groupphase/missioncontrol/service/EmployeeServiceImpl.java | 6 +++--- .../groupphase/missioncontrol/service/OperationService.java | 6 +++--- .../missioncontrol/service/OperationServiceImpl.java | 10 +++++----- .../groupphase/missioncontrol/service/RegistrationService.java | 2 +- .../missioncontrol/service/RegistrationServiceImpl.java | 10 +++++----- .../groupphase/missioncontrol/service/VehicleService.java | 4 ++-- .../groupphase/missioncontrol/service/VehicleServiceImpl.java | 8 ++++---- .../controller/CreateNewEmployeeControllerTest.java | 2 +- .../controller/CreateNewVehicleControllerTest.java | 2 +- .../groupphase/missioncontrol/dao/EmployeeDAOTest.java | 4 ++-- .../groupphase/missioncontrol/dao/OperationDAOTest.java | 4 ++-- .../groupphase/missioncontrol/dao/RegistrationDAOTest.java | 2 +- .../groupphase/missioncontrol/dao/VehicleDAOTest.java | 4 ++-- .../groupphase/missioncontrol/service/EmployeeServiceTest.java | 8 ++++---- .../service/OperationServiceIntegrationTest.java | 6 +++--- .../missioncontrol/service/OperationServiceTest.java | 6 +++--- .../service/RegistrationServiceIntegrationTest.java | 8 ++++---- .../missioncontrol/service/RegistrationServiceTest.java | 10 +++++----- 35 files changed, 82 insertions(+), 82 deletions(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java index 6e0c89d..5b1f975 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java @@ -2,11 +2,11 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.OperationService; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; import java.io.IOException; import java.time.LocalDateTime; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java index aa76535..1dd41c7 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java @@ -4,13 +4,13 @@ import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller. import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showSuccessAlertAndWait; import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; import java.io.IOException; import java.util.EnumSet; import java.util.Set; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeController.java index 433bfa6..3e0240c 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeController.java @@ -4,11 +4,11 @@ import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller. import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showSuccessAlertAndWait; import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.EmployeeService; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; import java.io.IOException; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java index b237265..260b910 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java @@ -4,15 +4,15 @@ import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller. import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showSuccessAlertAndWait; import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; +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.ServiceException; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.OperationService; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; -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.ServiceException; import java.io.IOException; import java.time.Instant; import java.time.temporal.ChronoUnit; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ManageEmployeesController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ManageEmployeesController.java index 6138094..fa228de 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ManageEmployeesController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ManageEmployeesController.java @@ -1,8 +1,8 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.EmployeeService; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; import java.io.IOException; import java.util.HashSet; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java index 0476fc6..38d3bd1 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java @@ -5,14 +5,14 @@ import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller. import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showSuccessAlertAndWait; import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; +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.ServiceException; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.OperationService; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; -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.ServiceException; import java.io.IOException; import java.util.Collection; import java.util.EnumSet; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java index 9c47fe4..e540b9f 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java @@ -3,6 +3,9 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; +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.ServiceException; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; @@ -10,9 +13,6 @@ import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.EmployeeService; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.RegistrationService; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; -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.ServiceException; import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; import java.io.IOException; import java.time.LocalDate; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAO.java index d8ac513..675e951 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAO.java @@ -1,8 +1,8 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; 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.missioncontrol.dto.Employee; import java.util.Set; public interface EmployeeDAO { diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDatabaseDAO.java index 889b0fc..32dd6d2 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDatabaseDAO.java @@ -1,9 +1,9 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; 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.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; import java.sql.Connection; import java.sql.PreparedStatement; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAO.java index c0ef5d4..e496898 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAO.java @@ -1,9 +1,9 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; 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.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; import java.util.EnumSet; import java.util.Set; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java index 1641720..1ccb4cf 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java @@ -1,11 +1,11 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; +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.missioncontrol.dto.Operation; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Severity; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.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; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAO.java index 02e742c..4a35f86 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAO.java @@ -1,8 +1,8 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; 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.missioncontrol.dto.Registration; import java.util.Set; public interface RegistrationDAO { diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java index 1006a33..1f11024 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java @@ -1,9 +1,9 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; 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.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; import java.sql.Connection; import java.sql.PreparedStatement; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAO.java index ed24498..46d1853 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAO.java @@ -1,8 +1,8 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.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.missioncontrol.dto.Vehicle; import java.util.Set; public interface VehicleDAO { diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java index dd7c0f2..9bd7ec7 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java @@ -1,11 +1,11 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; +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.missioncontrol.dto.Vehicle; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.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.sql.Connection; import java.sql.PreparedStatement; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/RegistrationValidator.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/RegistrationValidator.java index 9512f64..a2cb8c1 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/RegistrationValidator.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/RegistrationValidator.java @@ -1,9 +1,9 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType; 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.missioncontrol.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType; import java.util.HashMap; import java.util.LinkedList; import java.util.List; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeService.java index fa4d0e6..5beabaa 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeService.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeService.java @@ -1,8 +1,8 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; import java.util.Set; public interface EmployeeService { diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceImpl.java index 945fb49..a08b03e 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceImpl.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceImpl.java @@ -1,12 +1,12 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.EmployeeDAO; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.EmployeeValidator; import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.EmployeeDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.EmployeeValidator; import java.util.Set; import org.springframework.stereotype.Service; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationService.java index ca1dce9..42b23bb 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationService.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationService.java @@ -1,11 +1,11 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; 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.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; import java.util.EnumSet; import java.util.Set; import java.util.SortedSet; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceImpl.java index baae598..0c350fe 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceImpl.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceImpl.java @@ -1,5 +1,10 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; +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 at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.OperationDAO; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; @@ -7,11 +12,6 @@ import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Seve import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType; -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.ArrayList; import java.util.Comparator; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationService.java index 027417f..91577dc 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationService.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationService.java @@ -1,9 +1,9 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; 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.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; import java.util.Set; public interface RegistrationService { diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java index 3ec69e7..eb2cd1d 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java @@ -1,15 +1,15 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.RegistrationDAO; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.RegistrationValidator; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; 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 at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.RegistrationDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.RegistrationValidator; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleService.java index d96dfb7..f8e303d 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleService.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleService.java @@ -1,9 +1,9 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; import java.util.EnumSet; import java.util.Set; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleServiceImpl.java index 6a035c6..a68720d 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleServiceImpl.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleServiceImpl.java @@ -1,13 +1,13 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; 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 at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; import java.util.EnumSet; import java.util.Set; import java.util.stream.Collectors; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeControllerTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeControllerTest.java index 2b0f793..ccd37b4 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeControllerTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeControllerTest.java @@ -6,9 +6,9 @@ import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller. import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.EmployeeService; import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.EmployeeService; import at.ac.tuwien.sepm.assignment.groupphase.util.Helper; import at.ac.tuwien.sepm.assignment.groupphase.util.HighDpiAwareApplicationTest; import javafx.scene.control.DialogPane; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewVehicleControllerTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewVehicleControllerTest.java index 282c50f..4906d64 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewVehicleControllerTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewVehicleControllerTest.java @@ -6,9 +6,9 @@ import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller. import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; import at.ac.tuwien.sepm.assignment.groupphase.util.Helper; import at.ac.tuwien.sepm.assignment.groupphase.util.HighDpiAwareApplicationTest; import javafx.scene.control.DialogPane; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAOTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAOTest.java index 8485f67..008ac57 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAOTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAOTest.java @@ -1,9 +1,9 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; 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.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; import at.ac.tuwien.sepm.assignment.groupphase.util.Helper; import at.ac.tuwien.sepm.assignment.groupphase.util.JdbcTestCase; import java.io.InputStream; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAOTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAOTest.java index a4a0829..b15b31a 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAOTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAOTest.java @@ -2,14 +2,14 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; import static org.junit.Assert.assertEquals; +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.missioncontrol.dto.Operation; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Severity; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.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.JdbcTestCase; import java.time.Instant; import java.util.Arrays; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAOTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAOTest.java index 6f7ee49..2cb54f8 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAOTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAOTest.java @@ -2,10 +2,10 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; import static org.junit.Assert.*; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; import at.ac.tuwien.sepm.assignment.groupphase.util.JdbcTestCase; import java.time.Instant; import java.time.LocalDate; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAOTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAOTest.java index 294ce10..c4d7d86 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAOTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAOTest.java @@ -1,11 +1,11 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; +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.missioncontrol.dto.Vehicle; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.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.Helper; import at.ac.tuwien.sepm.assignment.groupphase.util.JdbcTestCase; import java.io.InputStream; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceTest.java index 7a16d3e..17c0a47 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceTest.java @@ -6,14 +6,14 @@ import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.EmployeeDAO; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.EmployeeDatabaseDAO; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.EmployeeDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.EmployeeDatabaseDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; import java.time.LocalDate; import org.junit.Assert; import org.junit.Test; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceIntegrationTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceIntegrationTest.java index e380850..865a402 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceIntegrationTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceIntegrationTest.java @@ -2,6 +2,9 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; import static org.junit.Assert.assertEquals; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.EmployeeDAO; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.EmployeeDatabaseDAO; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.OperationDAO; @@ -13,9 +16,6 @@ import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDatabas import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; import at.ac.tuwien.sepm.assignment.groupphase.util.Helper; import at.ac.tuwien.sepm.assignment.groupphase.util.JdbcTestCase; import java.util.Set; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceTest.java index c232e78..4c1eaf1 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceTest.java @@ -6,6 +6,9 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +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.missioncontrol.dao.OperationDAO; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; @@ -13,9 +16,6 @@ import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Seve import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; -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 java.time.Instant; import java.util.Collections; import java.util.Set; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceIntegrationTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceIntegrationTest.java index bfe44aa..ac5c3fb 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceIntegrationTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceIntegrationTest.java @@ -1,15 +1,15 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; +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 at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.EmployeeDAO; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.EmployeeDatabaseDAO; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.RegistrationDAO; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.RegistrationDatabaseDAO; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDatabaseDAO; -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 at.ac.tuwien.sepm.assignment.groupphase.util.JdbcTestCase; import org.dbunit.dataset.IDataSet; import org.junit.Before; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceTest.java index 62982ac..b4bcff4 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceTest.java @@ -3,6 +3,11 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.when; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +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 at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.RegistrationDAO; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; @@ -13,11 +18,6 @@ import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Builde import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -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.time.Instant; import java.time.LocalDate; import java.time.temporal.ChronoUnit; -- cgit v1.2.3-70-g09d2 From fbc917477d106be774d9c093ac42319aeadf1eff Mon Sep 17 00:00:00 2001 From: Tharre Date: Mon, 18 Jun 2018 21:30:20 +0200 Subject: RequestVehicles GUI list seperation #25953 --- .../controller/OperationDetailsController.java | 24 ++++++++++++++++++---- src/main/resources/fxml/OperationDetails.fxml | 11 +++++++++- 2 files changed, 30 insertions(+), 5 deletions(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java index 38d3bd1..937a86a 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java @@ -39,6 +39,7 @@ public class OperationDetailsController { private final VehicleService vehicleService; private final CreateOperationController createOperationController; @FXML private FlowPane fpVehicles; + @FXML private FlowPane fpAdditional; @FXML private ListView lvActiveOperations; @FXML private Label lblChosenVehicles; @FXML private Button btnCloseOperation; @@ -74,12 +75,21 @@ public class OperationDetailsController { try { fpVehicles.getChildren().clear(); for (Vehicle vehicle : operation.vehicles()) { + VehiclePaneController controller = VehiclePaneController.createVehiclePane(); + controller.setData(vehicle, true, false); + fpVehicles.getChildren().add(controller.getRootElement()); + } + + fpAdditional.getChildren().clear(); + for (Vehicle vehicle : operationService.rankVehicles(operation.opCode())) { + if (operation.vehicles().contains(vehicle)) continue; + VehiclePaneController controller = VehiclePaneController.createVehiclePane(); controller.setData(vehicle, true, true); controller.getBtnRequest().setOnAction(e -> requestVehicleClicked(controller)); - fpVehicles.getChildren().add(controller.getRootElement()); + fpAdditional.getChildren().add(controller.getRootElement()); } - } catch (IOException e) { + } catch (IOException | ServiceException | InvalidOperationException e) { LOG.error("Error while updating list.", e); showServiceExceptionAlertAndWait("Error while updating list."); } @@ -150,15 +160,21 @@ public class OperationDetailsController { private void requestVehicleClicked(VehiclePaneController v) { LOG.debug("Button \"Nachfordern\" clicked."); + Vehicle vehicle; + try { - operationService.requestVehicles(operation.id(), Set.of(v.getData().id())); + vehicle = v.getData(); + if (vehicle == null) return; + + operationService.requestVehicles(operation.id(), Set.of(vehicle.id())); } catch (ServiceException | InvalidOperationException | InvalidVehicleException e) { LOG.error("Exception in requestVehicleClicked()", e); showServiceExceptionAlertAndWait(e.getMessage()); return; } showSuccessAlertAndWait("Das Fahrzeug wurde erfolgreich angefordert"); - createOperationController.updateList(); + operation.vehicles().add(vehicle); + updateFlowPane(); } public void closeWindow() { diff --git a/src/main/resources/fxml/OperationDetails.fxml b/src/main/resources/fxml/OperationDetails.fxml index e1a4daa..9d2fb5b 100644 --- a/src/main/resources/fxml/OperationDetails.fxml +++ b/src/main/resources/fxml/OperationDetails.fxml @@ -9,6 +9,7 @@ + @@ -94,7 +95,15 @@ - + + + + + -- cgit v1.2.3-70-g09d2 From 410eadc051a76cc7bae782efd15fe708439c2132 Mon Sep 17 00:00:00 2001 From: Felix Kehrer Date: Mon, 18 Jun 2018 23:21:25 +0200 Subject: Only call reset when needed, and then only once instead of twice #28864 --- .../missioncontrol/controller/RegistrationWindowController.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java index e540b9f..3bde468 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java @@ -202,7 +202,6 @@ public class RegistrationWindowController { public void cancel() { LOG.debug("Hyperlink \"schließen\" clicked"); - reset(); this.setVisible(false); createOperationController.setVisible(true); } @@ -265,8 +264,8 @@ public class RegistrationWindowController { } public void setVisible(boolean b) { + if (b) reset(); root.setVisible(b); - reset(); } public void tfVehicleSearch_TextChanged(KeyEvent keyEvent) { -- cgit v1.2.3-70-g09d2 From 2ed8028db3944677e67e57d99a7032efef0581e5 Mon Sep 17 00:00:00 2001 From: Felix Kehrer Date: Mon, 18 Jun 2018 23:37:43 +0200 Subject: Comment out unnecessary reset #28864 --- .../missioncontrol/controller/RegistrationWindowController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java index 3bde468..c89860f 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java @@ -248,7 +248,7 @@ public class RegistrationWindowController { // ((Stage) lVehicles.getScene().getWindow()).close(); this.setVisible(false); createOperationController.setVisible(true); - reset(); + // reset(); } catch (InvalidVehicleException e) { LOG.debug("Validation of Vehicle in Registration failed."); showValidationErrorAlertAndWait("Das spezifizierte Fahrzeug ist nicht gültig."); -- cgit v1.2.3-70-g09d2 From ed5ac0d568e393c9c14041b2fd6bf7b683c7540b Mon Sep 17 00:00:00 2001 From: Felix Kehrer Date: Tue, 19 Jun 2018 00:06:30 +0200 Subject: Comment out unnecessary reset #28864 --- .../missioncontrol/controller/RegistrationWindowController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java index c89860f..94210e4 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java @@ -98,7 +98,7 @@ public class RegistrationWindowController { cbEnd.setItems(hours); cbEnd.setValue(12); - reset(); + // reset(); } private void updateEmplList() { -- cgit v1.2.3-70-g09d2 From 2e316a8540f2db3b36693f6e2c2754e4d66c82ee Mon Sep 17 00:00:00 2001 From: Felix Kehrer Date: Tue, 19 Jun 2018 00:07:58 +0200 Subject: Only update when window becomes visible again, greatly speeding up opening time of all windows #28864 --- .../groupphase/missioncontrol/controller/CreateOperationController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java index 260b910..8c1df80 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java @@ -324,7 +324,7 @@ public class CreateOperationController { apInvisible.setVisible(!b); grdWindowContainer.setVisible(!b); - updateList(); + if (b) updateList(); } private void openDetailsWindow(Operation operation) { -- cgit v1.2.3-70-g09d2 From 2f6fa3024fc11b65a29624e12fb7a9a6cc851bd9 Mon Sep 17 00:00:00 2001 From: Tharre Date: Tue, 19 Jun 2018 00:06:20 +0200 Subject: Fixup OperationDao to convert version --- .../missioncontrol/dao/OperationDatabaseDAO.java | 48 +++++++++++----------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java index 1ccb4cf..10bba3d 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java @@ -37,7 +37,6 @@ public class OperationDatabaseDAO implements OperationDAO { String sql = "INSERT INTO Operation(opCode, severity, created, destination, additionalInfo," + " status) VALUES (?, ?, ?, ?, ?, ?)"; - String sql2 = "INSERT INTO VehicleOperation(vehicleId, operationId) VALUES (?, ?)"; long operationId; try { @@ -59,16 +58,7 @@ public class OperationDatabaseDAO implements OperationDAO { } } - try (PreparedStatement pstmt = con.prepareStatement(sql2)) { - pstmt.setLong(2, operationId); - - for (long id : (Iterable) o.vehicles().stream().map(Vehicle::id)::iterator) { - pstmt.setLong(1, id); - pstmt.addBatch(); - } - - pstmt.executeBatch(); - } + createVehicleOperation(con, operationId, o.vehicles()); con.commit(); return operationId; } catch (SQLException e) { @@ -84,7 +74,6 @@ public class OperationDatabaseDAO implements OperationDAO { "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(); @@ -106,16 +95,7 @@ public class OperationDatabaseDAO implements OperationDAO { pstmt.executeUpdate(); } - try (PreparedStatement pstmt = con.prepareStatement(sql3)) { - pstmt.setLong(2, o.id()); - - for (long id : (Iterable) o.vehicles().stream().map(Vehicle::id)::iterator) { - pstmt.setLong(1, id); - pstmt.addBatch(); - } - - pstmt.executeBatch(); - } + createVehicleOperation(con, o.id(), o.vehicles()); con.commit(); } catch (SQLException e) { jdbcConnectionManager.rollbackConnection(); @@ -123,6 +103,24 @@ public class OperationDatabaseDAO implements OperationDAO { } } + private void createVehicleOperation(Connection con, long operationId, Set vehicles) + throws SQLException { + String sql = + "INSERT INTO VehicleOperation(vehicleId, operationId)" + + " SELECT version, ? FROM Vehicle WHERE id = ?"; + + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setLong(1, operationId); + + for (long id : (Iterable) vehicles.stream().map(Vehicle::id)::iterator) { + pstmt.setLong(2, id); + pstmt.addBatch(); + } + + pstmt.executeBatch(); + } + } + @Override public Operation get(long operationId) throws ElementNotFoundException, PersistenceException { String sql = "Select * from operation where id = ?"; @@ -195,7 +193,9 @@ public class OperationDatabaseDAO implements OperationDAO { } private Set getVehiclesFromOperationId(long operationId) throws PersistenceException { - String sql = "SELECT vehicleId FROM VehicleOperation WHERE operationId = ?"; + String sql = + "SELECT id FROM Vehicle WHERE version IN" + + " (SELECT vehicleId FROM VehicleOperation WHERE operationId = ?)"; Set vehicles = new HashSet<>(); try { @@ -206,7 +206,7 @@ public class OperationDatabaseDAO implements OperationDAO { try (ResultSet rs = pstmt.getResultSet()) { while (rs.next()) { - vehicles.add(vehicleDAO.get(rs.getLong("vehicleId"))); + vehicles.add(vehicleDAO.get(rs.getLong("Vehicle.id"))); } } } -- cgit v1.2.3-70-g09d2 From ede9e933d7e966ee4122b7b57242c88efc868faa Mon Sep 17 00:00:00 2001 From: Dominic Rogetzer Date: Tue, 19 Jun 2018 00:31:05 +0200 Subject: Change versioning in RegistrationDatabaseDAO [#25963] --- .../dao/RegistrationDatabaseDAO.java | 112 ++++++++++++++------- .../missioncontrol/dao/VehicleDatabaseDAO.java | 2 +- 2 files changed, 79 insertions(+), 35 deletions(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java index 1f11024..2f52349 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java @@ -3,6 +3,7 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; 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.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; import java.sql.Connection; @@ -10,6 +11,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.time.LocalDate; import java.time.OffsetDateTime; import java.time.ZoneId; import java.util.ArrayList; @@ -32,6 +34,38 @@ public class RegistrationDatabaseDAO implements RegistrationDAO { this.employeePersistence = employeePersistence; } + private long getVehicleVersionId(long vehicleId) throws PersistenceException { + String sqlGetVehicleVersionId = "SELECT * FROM vehicle WHERE id = ?"; + try (PreparedStatement stmt = + jdbcConnectionManager.getConnection().prepareStatement(sqlGetVehicleVersionId)) { + stmt.setLong(1, vehicleId); + ResultSet rs = stmt.executeQuery(); + if (rs.next()) { + return rs.getLong("version"); + } else { + throw new PersistenceException("vehicle id not found"); + } + } catch (SQLException e) { + throw new PersistenceException(e); + } + } + + private long getEmployeeVersionId(long employeeId) throws PersistenceException { + String sqlGetEmployeeVersionId = "SELECT * FROM employee WHERE id = ?"; + try (PreparedStatement stmt = + jdbcConnectionManager.getConnection().prepareStatement(sqlGetEmployeeVersionId)) { + stmt.setLong(1, employeeId); + ResultSet rs = stmt.executeQuery(); + if (rs.next()) { + return rs.getLong("version"); + } else { + throw new PersistenceException("employee id not found"); + } + } catch (SQLException e) { + throw new PersistenceException(e); + } + } + @Override public Set add(long vehicleId, Set registrations) throws PersistenceException { @@ -47,10 +81,12 @@ public class RegistrationDatabaseDAO implements RegistrationDAO { try (PreparedStatement pstmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { - pstmt.setLong(1, vehicleId); + + // vehicleId is a Vehicle.id as it comes from GUI => fetch VehicleVersion.id + pstmt.setLong(1, getVehicleVersionId(vehicleId)); for (Registration r : registrations) { - pstmt.setLong(2, r.employee().id()); + pstmt.setLong(2, getEmployeeVersionId(r.employee().id())); pstmt.setObject(3, OffsetDateTime.ofInstant(r.start(), ZoneId.systemDefault())); pstmt.setObject(4, OffsetDateTime.ofInstant(r.end(), ZoneId.systemDefault())); pstmt.setBoolean(5, true); @@ -86,40 +122,48 @@ public class RegistrationDatabaseDAO implements RegistrationDAO { } protected List list(long vehicleId) throws PersistenceException { - String sql = "SELECT * FROM Registration WHERE vehicleId = ?"; - - List registrationList = new ArrayList<>(); - try { - Connection con = jdbcConnectionManager.getConnection(); - try (PreparedStatement pstmt = con.prepareStatement(sql)) { - pstmt.setLong(1, vehicleId); + // vehicleId is a Vehicle.id as it comes from GUI => fetch VehicleVersion.id + long vehicleVersionId = getVehicleVersionId(vehicleId); - try (ResultSet rs = pstmt.executeQuery()) { - while (rs.next()) { - long employeeId = rs.getLong("employeeId"); - // TODO: replace the following with employeePersistence.get once implemented - Employee emp = - employeePersistence - .list() - .stream() - .filter(employee -> employee.id() == employeeId) - .findAny() - .orElse(null); - Registration registration = - Registration.builder() - .id(rs.getLong("id")) - .start( - (rs.getObject("start", OffsetDateTime.class)) - .toInstant()) - .end( - (rs.getObject("end", OffsetDateTime.class)) - .toInstant()) - .employee(emp) - .build(); - registrationList.add(registration); - } - } + String sql = + "SELECT * FROM Registration r " + + "JOIN EmployeeVersion ev ON ev.id = r.employeeId " + + "JOIN VehicleVersion vv ON vv.id = r.vehicleId " + + "WHERE r.vehicleId = ?"; + + try (PreparedStatement stmt = jdbcConnectionManager.getConnection().prepareStatement(sql)) { + + List registrationList = new ArrayList<>(); + stmt.setLong(1, vehicleVersionId); + ResultSet rs = stmt.executeQuery(); + while (rs.next()) { + + Employee employee = + Employee.builder() + .id(rs.getLong("EmployeeVersion.id")) + .name(rs.getString("EmployeeVersion.name")) + .birthday(rs.getObject("EmployeeVersion.birthday", LocalDate.class)) + .educationLevel( + EducationLevel.valueOf( + rs.getString("EmployeeVersion.educationLevel"))) + .isDriver(rs.getBoolean("EmployeeVersion.isDriver")) + .isPilot(rs.getBoolean("EmployeeVersion.isPilot")) + .build(); + + Registration registration = + Registration.builder() + .id(rs.getLong("Registration.id")) + .start( + (rs.getObject("Registration.start", OffsetDateTime.class)) + .toInstant()) + .end( + (rs.getObject("Registration.end", OffsetDateTime.class)) + .toInstant()) + .employee(employee) + .build(); + + registrationList.add(registration); } return registrationList; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java index 9bd7ec7..eb3cc61 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java @@ -205,7 +205,7 @@ public class VehicleDatabaseDAO implements VehicleDAO { .type(VehicleType.valueOf(rs.getString("type"))) .status(Status.values()[rs.getInt("status")]) .hasNef(rs.getBoolean("hasNef")) - .registrations(registrationDatabaseDao.list(rs.getLong("id"))) + .registrations(registrationDatabaseDao.list(rs.getLong("Vehicle.id"))) .build(); } } -- cgit v1.2.3-70-g09d2 From ba18fafe3daca828719b95f0b0efeae6683afd3d Mon Sep 17 00:00:00 2001 From: Dominic Rogetzer Date: Tue, 19 Jun 2018 12:56:16 +0200 Subject: Change versioning in Operation and Registration [#25963] --- .../controller/CreateCarController.java | 2 +- .../controller/CreateOperationController.java | 1 + .../missioncontrol/dao/OperationDatabaseDAO.java | 36 +++++++++++++++++----- .../dao/RegistrationDatabaseDAO.java | 7 ++--- 4 files changed, 33 insertions(+), 13 deletions(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java index 1dd41c7..4da46a2 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java @@ -189,7 +189,7 @@ public class CreateCarController { createOperationController.setVisible(true); } - private void updateVehiclePane() { + void updateVehiclePane() { try { fpVehicleList.getChildren().clear(); diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java index 8c1df80..e5d7b72 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java @@ -340,6 +340,7 @@ public class CreateOperationController { private void openCreateCarWindow() { this.setVisible(false); createCarController.setVisible(true); + createCarController.updateVehiclePane(); } private void openRegistrationWindow() { diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java index 10bba3d..d06e13f 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java @@ -6,6 +6,8 @@ import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Severity; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType; import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; import java.sql.Connection; import java.sql.PreparedStatement; @@ -25,11 +27,15 @@ public class OperationDatabaseDAO implements OperationDAO { private JDBCConnectionManager jdbcConnectionManager; private VehicleDAO vehicleDAO; + private RegistrationDatabaseDAO registrationDAO; public OperationDatabaseDAO( - JDBCConnectionManager jdbcConnectionManager, VehicleDAO vehicleDAO) { + JDBCConnectionManager jdbcConnectionManager, + VehicleDAO vehicleDAO, + RegistrationDatabaseDAO registrationDAO) { this.jdbcConnectionManager = jdbcConnectionManager; this.vehicleDAO = vehicleDAO; + this.registrationDAO = registrationDAO; } @Override @@ -193,9 +199,12 @@ public class OperationDatabaseDAO implements OperationDAO { } private Set getVehiclesFromOperationId(long operationId) throws PersistenceException { + /*String sql = + "SELECT id FROM Vehicle WHERE version IN" + + " (SELECT vehicleId FROM VehicleOperation WHERE operationId = ?)";*/ String sql = - "SELECT id FROM Vehicle WHERE version IN" - + " (SELECT vehicleId FROM VehicleOperation WHERE operationId = ?)"; + "SELECT vv.* FROM VehicleOperation vo JOIN VehicleVersion vv ON vv.id = vo.vehicleId WHERE operationId = ?"; + Set vehicles = new HashSet<>(); try { @@ -206,16 +215,29 @@ public class OperationDatabaseDAO implements OperationDAO { try (ResultSet rs = pstmt.getResultSet()) { while (rs.next()) { - vehicles.add(vehicleDAO.get(rs.getLong("Vehicle.id"))); + vehicles.add(vehicleFromRS(rs)); } } } } catch (SQLException e) { throw new PersistenceException(e); - } catch (ElementNotFoundException e) { - throw new PersistenceException("VehicleOperation contained nonexistent vehicle", e); - } + } /*catch (ElementNotFoundException e) { + throw new PersistenceException("VehicleOperation contained nonexistent vehicle", e); + }*/ return vehicles; } + + private Vehicle vehicleFromRS(ResultSet rs) throws SQLException, PersistenceException { + return Vehicle.builder() + .id(rs.getLong("VehicleVersion.id")) + .name(rs.getString("VehicleVersion.name")) + .constructionType( + ConstructionType.values()[rs.getInt("VehicleVersion.constructionType")]) + .type(VehicleType.valueOf(rs.getString("VehicleVersion.type"))) + .status(Vehicle.Status.ABGEMELDET) + .hasNef(rs.getBoolean("VehicleVersion.hasNef")) + .registrations(registrationDAO.list(rs.getLong("VehicleVersion.id"))) + .build(); + } } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java index 2f52349..b08ee68 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java @@ -83,7 +83,7 @@ public class RegistrationDatabaseDAO implements RegistrationDAO { con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { // vehicleId is a Vehicle.id as it comes from GUI => fetch VehicleVersion.id - pstmt.setLong(1, getVehicleVersionId(vehicleId)); + pstmt.setLong(1, getVehicleVersionId(vehicleId) /*vehicleId*/); for (Registration r : registrations) { pstmt.setLong(2, getEmployeeVersionId(r.employee().id())); @@ -123,9 +123,6 @@ public class RegistrationDatabaseDAO implements RegistrationDAO { protected List list(long vehicleId) throws PersistenceException { - // vehicleId is a Vehicle.id as it comes from GUI => fetch VehicleVersion.id - long vehicleVersionId = getVehicleVersionId(vehicleId); - String sql = "SELECT * FROM Registration r " + "JOIN EmployeeVersion ev ON ev.id = r.employeeId " @@ -135,7 +132,7 @@ public class RegistrationDatabaseDAO implements RegistrationDAO { try (PreparedStatement stmt = jdbcConnectionManager.getConnection().prepareStatement(sql)) { List registrationList = new ArrayList<>(); - stmt.setLong(1, vehicleVersionId); + stmt.setLong(1, vehicleId); // is vehicle version id! ResultSet rs = stmt.executeQuery(); while (rs.next()) { -- cgit v1.2.3-70-g09d2 From 2244bd4a51eedda216d6bc822f4e07008239944b Mon Sep 17 00:00:00 2001 From: Dominic Rogetzer Date: Tue, 19 Jun 2018 16:51:54 +0200 Subject: Fix versioning problem where wrong cars showed up in op-detail [#25963] --- .../missioncontrol/dao/OperationDatabaseDAO.java | 15 +++++++++------ .../missioncontrol/dao/RegistrationDatabaseDAO.java | 2 +- .../groupphase/missioncontrol/dao/VehicleDatabaseDAO.java | 4 ++-- 3 files changed, 12 insertions(+), 9 deletions(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java index d06e13f..53682f9 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java @@ -221,21 +221,24 @@ public class OperationDatabaseDAO implements OperationDAO { } } catch (SQLException e) { throw new PersistenceException(e); - } /*catch (ElementNotFoundException e) { - throw new PersistenceException("VehicleOperation contained nonexistent vehicle", e); - }*/ + } catch (ElementNotFoundException e) { + throw new PersistenceException("VehicleOperation contained nonexistent vehicle", e); + } return vehicles; } - private Vehicle vehicleFromRS(ResultSet rs) throws SQLException, PersistenceException { + private Vehicle vehicleFromRS(ResultSet rs) + throws SQLException, PersistenceException, ElementNotFoundException { + String name = rs.getString("VehicleVersion.name"); + long vehicleId = Long.parseLong(name.split("-")[1]); return Vehicle.builder() - .id(rs.getLong("VehicleVersion.id")) + .id(vehicleId) .name(rs.getString("VehicleVersion.name")) .constructionType( ConstructionType.values()[rs.getInt("VehicleVersion.constructionType")]) .type(VehicleType.valueOf(rs.getString("VehicleVersion.type"))) - .status(Vehicle.Status.ABGEMELDET) + .status(vehicleDAO.get(vehicleId).status()) .hasNef(rs.getBoolean("VehicleVersion.hasNef")) .registrations(registrationDAO.list(rs.getLong("VehicleVersion.id"))) .build(); diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java index b08ee68..90fbc2c 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java @@ -83,7 +83,7 @@ public class RegistrationDatabaseDAO implements RegistrationDAO { con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { // vehicleId is a Vehicle.id as it comes from GUI => fetch VehicleVersion.id - pstmt.setLong(1, getVehicleVersionId(vehicleId) /*vehicleId*/); + pstmt.setLong(1, getVehicleVersionId(vehicleId)); for (Registration r : registrations) { pstmt.setLong(2, getEmployeeVersionId(r.employee().id())); diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java index eb3cc61..8cef65e 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java @@ -170,7 +170,7 @@ public class VehicleDatabaseDAO implements VehicleDAO { @Override public Vehicle get(long id) throws ElementNotFoundException, PersistenceException { String sql = - "SELECT a.id, b.name, b.constructionType, b.type, a.status, b.hasNef" + "SELECT *" + " FROM Vehicle a" + " INNER JOIN VehicleVersion b" + " ON version = b.id" @@ -205,7 +205,7 @@ public class VehicleDatabaseDAO implements VehicleDAO { .type(VehicleType.valueOf(rs.getString("type"))) .status(Status.values()[rs.getInt("status")]) .hasNef(rs.getBoolean("hasNef")) - .registrations(registrationDatabaseDao.list(rs.getLong("Vehicle.id"))) + .registrations(registrationDatabaseDao.list(rs.getLong("Vehicle.version"))) .build(); } } -- cgit v1.2.3-70-g09d2 From 824e8cb818820b313b7dd08d8f72932b8ca7d41d Mon Sep 17 00:00:00 2001 From: Dominic Rogetzer Date: Tue, 19 Jun 2018 18:29:39 +0200 Subject: Set status of vehicles to 'ZUM_BERUFUNGSORT' when creating op [#25963] --- .../groupphase/missioncontrol/dao/OperationDatabaseDAO.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java index 53682f9..238a2a8 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java @@ -114,16 +114,23 @@ public class OperationDatabaseDAO implements OperationDAO { String sql = "INSERT INTO VehicleOperation(vehicleId, operationId)" + " SELECT version, ? FROM Vehicle WHERE id = ?"; + String sqlUpdateVehicleStatus = + "UPDATE Vehicle SET status = 'ZUM_BERUFUNGSORT' WHERE id = ?"; - try (PreparedStatement pstmt = con.prepareStatement(sql)) { + try (PreparedStatement pstmt = con.prepareStatement(sql); + PreparedStatement stmtUpdateVehicleStatus = + con.prepareStatement(sqlUpdateVehicleStatus)) { pstmt.setLong(1, operationId); for (long id : (Iterable) vehicles.stream().map(Vehicle::id)::iterator) { pstmt.setLong(2, id); + stmtUpdateVehicleStatus.setLong(1, id); pstmt.addBatch(); + stmtUpdateVehicleStatus.addBatch(); } pstmt.executeBatch(); + stmtUpdateVehicleStatus.executeBatch(); } } -- cgit v1.2.3-70-g09d2 From fffb6c7bbc2a68fb824309616d3d278b39f4e824 Mon Sep 17 00:00:00 2001 From: Dominic Rogetzer Date: Tue, 19 Jun 2018 21:06:12 +0200 Subject: Display registrations in archive which are in timeframe only [#25963] E.g. one group of people registers to from 10-12. If the group of people is registered on a car which is sent to the operation within the time it is listed in archive. Otherwise, they are not shown. This restriction is necessary as otherwise, all employees that have been registered to this vehicle would be listed, regardless of the time of their registration --- .../controller/ArchiveOperationController.java | 2 +- .../DetailArchiveOperationController.java | 27 ++++++++++++++++++---- .../dao/RegistrationDatabaseDAO.java | 22 ++++++++++-------- 3 files changed, 36 insertions(+), 15 deletions(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java index 5b1f975..3c3a005 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java @@ -177,7 +177,7 @@ public class ArchiveOperationController { controller = DetailArchiveOperationController.create(fxmlLoader); - controller.set(vehicle); + controller.set(vehicle, detailOperation); fpVehicles.getChildren().add(controller.getRoot()); } } catch (IOException e) { diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/DetailArchiveOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/DetailArchiveOperationController.java index 32630a5..a866653 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/DetailArchiveOperationController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/DetailArchiveOperationController.java @@ -3,11 +3,15 @@ package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; import java.io.IOException; +import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; import javafx.fxml.FXML; import javafx.scene.Node; import javafx.scene.layout.VBox; @@ -47,7 +51,7 @@ public class DetailArchiveOperationController { private Node rootElement; - public void set(Vehicle vehicle) { + public void set(Vehicle vehicle, Operation operation) { VehiclePaneController controller; try { controller = VehiclePaneController.createVehiclePane(); @@ -59,10 +63,25 @@ public class DetailArchiveOperationController { "Ein interner Fehler ist aufgetreten. Bitte wenden Sie sich an den/die SystemadministratorIn."); } try { - for (int i = 0; i < Objects.requireNonNull(vehicle.registrations()).size(); i++) { - Employee employee = - Objects.requireNonNull(vehicle.registrations()).get(i).employee(); + List registrations = + Objects.requireNonNull(vehicle.registrations()) + .stream() + .filter( + registration -> + registration + .start() + .isBefore( + Objects.requireNonNull( + operation.created())) + && registration + .end() + .isAfter( + Objects.requireNonNull( + operation.created()))) + .collect(Collectors.toList()); + for (Registration registration : registrations) { + Employee employee = registration.employee(); EmployeeListItemController employeeListItemController = EmployeeListItemController.createEmployeeListItemController( fxmlLoader, employee); diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java index 90fbc2c..9f182c2 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java @@ -39,11 +39,12 @@ public class RegistrationDatabaseDAO implements RegistrationDAO { try (PreparedStatement stmt = jdbcConnectionManager.getConnection().prepareStatement(sqlGetVehicleVersionId)) { stmt.setLong(1, vehicleId); - ResultSet rs = stmt.executeQuery(); - if (rs.next()) { - return rs.getLong("version"); - } else { - throw new PersistenceException("vehicle id not found"); + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + return rs.getLong("version"); + } else { + throw new PersistenceException("vehicle id not found"); + } } } catch (SQLException e) { throw new PersistenceException(e); @@ -55,11 +56,12 @@ public class RegistrationDatabaseDAO implements RegistrationDAO { try (PreparedStatement stmt = jdbcConnectionManager.getConnection().prepareStatement(sqlGetEmployeeVersionId)) { stmt.setLong(1, employeeId); - ResultSet rs = stmt.executeQuery(); - if (rs.next()) { - return rs.getLong("version"); - } else { - throw new PersistenceException("employee id not found"); + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + return rs.getLong("version"); + } else { + throw new PersistenceException("employee id not found"); + } } } catch (SQLException e) { throw new PersistenceException(e); -- cgit v1.2.3-70-g09d2 From 280196ec77ffb1ff722b947afa6b2e2439a663ec Mon Sep 17 00:00:00 2001 From: Tharre Date: Tue, 19 Jun 2018 21:09:14 +0200 Subject: Implement and remove registrations #25963 --- .../controller/CreateOperationController.java | 26 +++++++++++++++------- .../dao/RegistrationDatabaseDAO.java | 18 +++++++++++++++ .../service/RegistrationServiceImpl.java | 10 ++++++++- 3 files changed, 45 insertions(+), 9 deletions(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java index e5d7b72..cc09127 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java @@ -5,6 +5,7 @@ import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller. import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; +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.ServiceException; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; @@ -12,6 +13,7 @@ import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Stat import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.OperationService; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.RegistrationService; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; import java.io.IOException; import java.time.Instant; @@ -66,11 +68,15 @@ public class CreateOperationController { private final OperationService operationService; private final VehicleService vehicleService; + private final RegistrationService registrationService; public CreateOperationController( - OperationService operationService, VehicleService vehicleService) { + OperationService operationService, + VehicleService vehicleService, + RegistrationService registrationService) { this.operationService = operationService; this.vehicleService = vehicleService; + this.registrationService = registrationService; } @FXML @@ -117,7 +123,10 @@ public class CreateOperationController { .setOnMouseClicked( event -> { if (event.getButton().equals(MouseButton.SECONDARY)) { - createContextMenu(vehicle, vehicleService) + createContextMenu( + vehicle, + vehicleService, + registrationService) .show( controller.getRootElement(), event.getScreenX(), @@ -172,14 +181,11 @@ public class CreateOperationController { } } - private ContextMenu createContextMenu(Vehicle data, VehicleService vehicleService) { + private ContextMenu createContextMenu( + Vehicle data, VehicleService vehicleService, RegistrationService registrationService) { ContextMenu menu = new ContextMenu(); for (Vehicle.Status status : Vehicle.Status.values()) { - if (status == Vehicle.Status.ABGEMELDET) { - continue; - } - MenuItem mi = new MenuItem(status.name()); if (status == Vehicle.Status.FREI_FUNK || status == Vehicle.Status.FREI_WACHE) { @@ -191,9 +197,13 @@ public class CreateOperationController { mi.setOnAction( event -> { try { + if (status == Vehicle.Status.ABGEMELDET) + for (Registration registration : data.registrations()) + registrationService.remove(registration.id()); + vehicleService.update(data.toBuilder().status(status).build()); this.updateList(); - } catch (InvalidVehicleException e) { + } catch (InvalidVehicleException | InvalidRegistrationException e) { LOG.debug( "Validation error in createContextMenu(). (mi.setOnAction) ", e); diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java index 9f182c2..8ae319c 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java @@ -11,6 +11,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.time.Instant; import java.time.LocalDate; import java.time.OffsetDateTime; import java.time.ZoneId; @@ -120,6 +121,23 @@ public class RegistrationDatabaseDAO implements RegistrationDAO { @Override public void remove(long id) throws ElementNotFoundException, PersistenceException { + String sql = "UPDATE Registration SET active = 0, end = ? WHERE id = ?"; + + try { + Connection con = jdbcConnectionManager.getConnection(); + + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setObject(1, OffsetDateTime.ofInstant(Instant.now(), ZoneId.systemDefault())); + pstmt.setLong(2, id); + + if (pstmt.executeUpdate() != 1) + throw new ElementNotFoundException("No such registrationId exists"); + } + + } catch (SQLException e) { + throw new PersistenceException(e); + } + throw new UnsupportedOperationException(); } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java index eb2cd1d..a6a1dfe 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java @@ -47,6 +47,14 @@ public class RegistrationServiceImpl implements RegistrationService { @Override public void remove(long registrationId) throws InvalidRegistrationException, ServiceException { - throw new UnsupportedOperationException(); + if (registrationId <= 0) throw new InvalidRegistrationException("RegistrationId invalid"); + + try { + registrationDAO.remove(registrationId); + } catch (PersistenceException e) { + throw new ServiceException(e); + } catch (ElementNotFoundException e) { + throw new InvalidRegistrationException(e); + } } } -- cgit v1.2.3-70-g09d2 From 7e2671d0d30bf217a40fd76c5676025218091a62 Mon Sep 17 00:00:00 2001 From: Viktoria Pundy Date: Tue, 19 Jun 2018 15:26:33 +0200 Subject: Added search to archive window [#25963] With search, the user can look for a specific archived operation. The search considers operation-code, location, date and name of the cars --- .../controller/ArchiveOperationController.java | 74 +++++++++++++++++++++- src/main/resources/fxml/ArchiveOperation.fxml | 10 ++- 2 files changed, 80 insertions(+), 4 deletions(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java index 3c3a005..212dba6 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java @@ -9,6 +9,7 @@ import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.OperationService; import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; import java.io.IOException; +import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.Arrays; @@ -21,6 +22,7 @@ import java.util.Set; import java.util.stream.Collectors; import javafx.fxml.FXML; import javafx.scene.control.Label; +import javafx.scene.control.TextField; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; @@ -33,6 +35,7 @@ import org.springframework.stereotype.Controller; public class ArchiveOperationController { private static final Logger LOG = LoggerFactory.getLogger(ArchiveOperationController.class); + @FXML private TextField txtSearch; @FXML private ImageView imvVehicleDetail; @FXML private Label lblStatus; @@ -89,13 +92,26 @@ public class ArchiveOperationController { showServiceExceptionAlertAndWait("Die Einsätze konnten nicht geladen werden!"); ; } - setFlowPane(); + setFlowPane(list); } - private void setFlowPane() { + public void update(Set operations) { + long cancelledAmount = 0; + long completedAmount = 0; + for (Operation operation : operations) { + if (operation.status() == Status.CANCELLED) cancelledAmount++; + else completedAmount++; + } + lblCancelled.setText("storniert: " + cancelledAmount); + lblCompleted.setText("abgeschlossen: " + completedAmount); + lblOperations.setText("Einsätze: " + operations.size()); + setFlowPane(operations); + } + + private void setFlowPane(Set operations) { try { archiveOperationFlowPane.getChildren().clear(); - for (Operation operation : sortSet(list)) { + for (Operation operation : sortSet(operations)) { OperationInArchiveController opInAController = OperationInArchiveController.create(); opInAController.set(operation); @@ -210,4 +226,56 @@ public class ArchiveOperationController { backApMain.setVisible(b); apMainDetails.setVisible(b); } + + @FXML + public void searchInput() { + LOG.debug("Search for operations in archive detail view started."); + String text = txtSearch.getText(); + Set chosenOperations = new HashSet<>(); + if (emptyText(text)) update(); + else { + for (Operation operation : list) { + if (checkEquality(operation, text)) chosenOperations.add(operation); + } + update(chosenOperations); + } + } + + private boolean emptyText(String text) { + if (text == null) return true; + text = text.replaceAll("\\s+", ""); + return text.isEmpty(); + } + + private boolean checkEquality(Operation operation, String text) { + if (isEqual(text, operation.opCode()) + || isEqual(text, operation.destination()) + || isEqual(text, reformDateToString(operation.created()))) return true; + for (Vehicle vehicle : operation.vehicles()) { + if (isEqual(text, vehicle.name())) return true; + } + return false; + } + + private String reformDateToString(Instant time) { + LocalDateTime dateTime = + LocalDateTime.ofInstant(Objects.requireNonNull(time), ZoneOffset.UTC); + return "am " + + dateTime.getDayOfMonth() + + "." + + dateTime.getMonth().getValue() + + "." + + dateTime.getYear(); + } + + private boolean isEqual(String text, String realText) { + for (int i = 0; (i + text.length()) < realText.length(); i++) { + StringBuilder result = new StringBuilder(); + for (int j = i; j < i + text.length(); j++) { + result.append(realText.charAt(j)); + } + if ((text.toLowerCase()).equals(result.toString().toLowerCase())) return true; + } + return false; + } } diff --git a/src/main/resources/fxml/ArchiveOperation.fxml b/src/main/resources/fxml/ArchiveOperation.fxml index e9549ae..9c22803 100644 --- a/src/main/resources/fxml/ArchiveOperation.fxml +++ b/src/main/resources/fxml/ArchiveOperation.fxml @@ -4,6 +4,7 @@ + @@ -99,9 +100,10 @@ - + + @@ -124,6 +126,12 @@ + + -- cgit v1.2.3-70-g09d2 From c0137272697475c522afa6ce1126187e68818be5 Mon Sep 17 00:00:00 2001 From: Tharre Date: Tue, 19 Jun 2018 21:55:11 +0200 Subject: Fixup the contextmenu handling for remove #25963 --- .../controller/CreateOperationController.java | 41 +++++----------------- .../dao/RegistrationDatabaseDAO.java | 2 -- 2 files changed, 9 insertions(+), 34 deletions(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java index cc09127..2334803 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java @@ -16,12 +16,8 @@ import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.OperationS import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.RegistrationService; import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; import java.io.IOException; -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.ArrayList; import java.util.EnumSet; import java.util.LinkedList; -import java.util.List; import java.util.Set; import javafx.collections.FXCollections; import javafx.fxml.FXML; @@ -186,6 +182,8 @@ public class CreateOperationController { ContextMenu menu = new ContextMenu(); for (Vehicle.Status status : Vehicle.Status.values()) { + if (status == Vehicle.Status.ABGEMELDET) continue; + MenuItem mi = new MenuItem(status.name()); if (status == Vehicle.Status.FREI_FUNK || status == Vehicle.Status.FREI_WACHE) { @@ -197,13 +195,9 @@ public class CreateOperationController { mi.setOnAction( event -> { try { - if (status == Vehicle.Status.ABGEMELDET) - for (Registration registration : data.registrations()) - registrationService.remove(registration.id()); - vehicleService.update(data.toBuilder().status(status).build()); this.updateList(); - } catch (InvalidVehicleException | InvalidRegistrationException e) { + } catch (InvalidVehicleException e) { LOG.debug( "Validation error in createContextMenu(). (mi.setOnAction) ", e); @@ -223,32 +217,15 @@ public class CreateOperationController { abmelden.setOnAction( event -> { try { - List registrations = data.registrations(); - assert registrations - != null; // Otherwise the element shouldn't be in the list. - - List newRegistrations = new ArrayList<>(); - Instant now = Instant.now(); - - for (Registration registration : registrations) { - if (registration.start().isBefore(now) - && registration.end().isAfter(now)) { - newRegistrations.add( - registration - .toBuilder() - .end(Instant.now().minus(1, ChronoUnit.SECONDS)) - .build()); - } else newRegistrations.add(registration); - } + if (data.registrations() == null) return; - vehicleService.update( - data.toBuilder() - .registrations(newRegistrations) - .status(Vehicle.Status.ABGEMELDET) - .build()); + for (Registration registration : data.registrations()) + registrationService.remove(registration.id()); + vehicleService.update( + data.toBuilder().status(Vehicle.Status.ABGEMELDET).build()); this.updateList(); - } catch (InvalidVehicleException e) { + } catch (InvalidVehicleException | InvalidRegistrationException e) { LOG.debug( "Validation error in createContextMenu(). (abmelden.setOnAction) ", e); diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java index 8ae319c..b624056 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java @@ -137,8 +137,6 @@ public class RegistrationDatabaseDAO implements RegistrationDAO { } catch (SQLException e) { throw new PersistenceException(e); } - - throw new UnsupportedOperationException(); } protected List list(long vehicleId) throws PersistenceException { -- cgit v1.2.3-70-g09d2 From 9b760d769a6cf3def05ced52c835c596df79faf0 Mon Sep 17 00:00:00 2001 From: Dominic Rogetzer Date: Tue, 19 Jun 2018 22:06:25 +0200 Subject: Set default registration start- & end time [#25963] --- .../controller/RegistrationWindowController.java | 37 ++++++++++++++-------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java index 94210e4..be0bfff 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java @@ -94,13 +94,16 @@ public class RegistrationWindowController { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23); cbStart.setItems(hours); - cbStart.setValue(0); cbEnd.setItems(hours); - cbEnd.setValue(12); - + setDefaultTime(); // reset(); } + private void setDefaultTime() { + cbStart.setValue(LocalDateTime.now().getHour()); + cbEnd.setValue((LocalDateTime.now().getHour() + 4) % 24); + } + private void updateEmplList() { employeeListController.deselectAllEmployees(); @@ -215,6 +218,7 @@ public class RegistrationWindowController { lVehicles.setText("-"); updateVehList(); updateEmplList(); + setDefaultTime(); } public void create() { @@ -225,21 +229,28 @@ public class RegistrationWindowController { if (chosenVehicle == null) { throw new InvalidVehicleException("no Vehicle"); } + + LocalDateTime startDate = + LocalDateTime.of( + LocalDate.now(), + LocalTime.of( + cbStart.getValue(), + LocalDateTime.now().getMinute(), + LocalDateTime.now().getSecond())); + + LocalDateTime endDate = + LocalDateTime.of( + LocalDate.now() + .plusDays(cbStart.getValue() >= cbEnd.getValue() ? 1 : 0), + LocalTime.of(cbEnd.getValue(), 0)); + for (Employee employee : chosenEmployees) { registrations.add( Registration.builder() .id(chosenVehicle.id()) .employee(employee) - .start( - LocalDateTime.of( - LocalDate.now(), - LocalTime.of(cbStart.getValue(), 0)) - .toInstant(OffsetDateTime.now().getOffset())) - .end( - LocalDateTime.of( - LocalDate.now(), - LocalTime.of(cbEnd.getValue(), 0)) - .toInstant(OffsetDateTime.now().getOffset())) + .start(startDate.toInstant(OffsetDateTime.now().getOffset())) + .end(endDate.toInstant(OffsetDateTime.now().getOffset())) .build()); } -- cgit v1.2.3-70-g09d2 From e70bb2b2771239dcda52f4ad1532ae56c96a3293 Mon Sep 17 00:00:00 2001 From: Felix Kehrer Date: Wed, 20 Jun 2018 16:56:08 +0200 Subject: Show validation error message (as changed during Jour Fixe) --- .../missioncontrol/controller/RegistrationWindowController.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java index be0bfff..4a8bc06 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java @@ -262,15 +262,14 @@ public class RegistrationWindowController { // reset(); } catch (InvalidVehicleException e) { LOG.debug("Validation of Vehicle in Registration failed."); - showValidationErrorAlertAndWait("Das spezifizierte Fahrzeug ist nicht gültig."); + showValidationErrorAlertAndWait(e.getMessage()); } catch (ServiceException e) { LOG.error("ServiceException in create(). ", e); showServiceExceptionAlertAndWait( "Beim Erstellen der Anmeldung ist ein Fehler aufgetreten."); } catch (InvalidRegistrationException e) { LOG.debug("Validation of Registration failed."); - showValidationErrorAlertAndWait( - "Die gewählte Kombination von Fahrzeug und Personal ist nicht gültig!"); + showValidationErrorAlertAndWait(e.getMessage()); } } -- cgit v1.2.3-70-g09d2 From 91e1248d777635a34e7d62c288c0aa38eba74205 Mon Sep 17 00:00:00 2001 From: Felix Kehrer Date: Wed, 20 Jun 2018 19:27:18 +0200 Subject: Speed up user interface by only updating operation list when changes could happen #28864 --- .../missioncontrol/controller/CreateOperationController.java | 4 +++- .../missioncontrol/controller/RegistrationWindowController.java | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java index 2334803..f06b43f 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java @@ -94,6 +94,8 @@ public class CreateOperationController { setVisible(true); createCarController.setVisible(false); registrationWindowController.setVisible(false); + + updateList(); } public void updateList() { @@ -311,7 +313,7 @@ public class CreateOperationController { apInvisible.setVisible(!b); grdWindowContainer.setVisible(!b); - if (b) updateList(); + // if (b) updateList(); } private void openDetailsWindow(Operation operation) { diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java index 4a8bc06..c445a12 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java @@ -259,6 +259,7 @@ public class RegistrationWindowController { // ((Stage) lVehicles.getScene().getWindow()).close(); this.setVisible(false); createOperationController.setVisible(true); + createOperationController.updateList(); // reset(); } catch (InvalidVehicleException e) { LOG.debug("Validation of Vehicle in Registration failed."); -- cgit v1.2.3-70-g09d2 From 7884e7dfb93b6555f9470734209b4f188ee7a937 Mon Sep 17 00:00:00 2001 From: Felix Kehrer Date: Wed, 20 Jun 2018 20:33:52 +0200 Subject: Handle validation errors differently from other Exceptions #28864 --- .../controller/OperationDetailsController.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol') diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java index 937a86a..daeaedd 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java @@ -89,9 +89,12 @@ public class OperationDetailsController { controller.getBtnRequest().setOnAction(e -> requestVehicleClicked(controller)); fpAdditional.getChildren().add(controller.getRootElement()); } - } catch (IOException | ServiceException | InvalidOperationException e) { + } catch (IOException | ServiceException e) { LOG.error("Error while updating list.", e); showServiceExceptionAlertAndWait("Error while updating list."); + } catch (InvalidOperationException e) { + LOG.debug("Validation for Operation failed"); + showValidationErrorAlertAndWait(e.getMessage()); } } @@ -160,17 +163,23 @@ public class OperationDetailsController { private void requestVehicleClicked(VehiclePaneController v) { LOG.debug("Button \"Nachfordern\" clicked."); - Vehicle vehicle; + Vehicle vehicle = null; try { vehicle = v.getData(); if (vehicle == null) return; operationService.requestVehicles(operation.id(), Set.of(vehicle.id())); - } catch (ServiceException | InvalidOperationException | InvalidVehicleException e) { - LOG.error("Exception in requestVehicleClicked()", e); + } catch (ServiceException e) { + LOG.error("ServiceException in requestVehicleClicked()", e); showServiceExceptionAlertAndWait(e.getMessage()); return; + } catch (InvalidVehicleException e) { + LOG.debug("Validation of Vehicle failed"); + showValidationErrorAlertAndWait(e.getMessage()); + } catch (InvalidOperationException e) { + LOG.debug("Validation of Operation failed"); + showValidationErrorAlertAndWait(e.getMessage()); } showSuccessAlertAndWait("Das Fahrzeug wurde erfolgreich angefordert"); operation.vehicles().add(vehicle); -- cgit v1.2.3-70-g09d2