diff options
84 files changed, 3958 insertions, 2001 deletions
| diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml index f8c1056..9b90d71 100644 --- a/.idea/dataSources.xml +++ b/.idea/dataSources.xml @@ -1,11 +1,11 @@  <?xml version="1.0" encoding="UTF-8"?>  <project version="4">    <component name="DataSourceManagerImpl" format="xml" multifile-model="true"> -    <data-source source="LOCAL" name="bev" uuid="61a88d33-7bb2-4a8d-b38f-9a1d90f0fe06"> +    <data-source source="LOCAL" name="sepm" uuid="61a88d33-7bb2-4a8d-b38f-9a1d90f0fe06">        <driver-ref>h2.unified</driver-ref>        <synchronize>true</synchronize>        <jdbc-driver>org.h2.Driver</jdbc-driver> -      <jdbc-url>jdbc:h2:~/bev</jdbc-url> +      <jdbc-url>jdbc:h2:$PROJECT_DIR$/sepm</jdbc-url>      </data-source>    </component>  </project>
\ No newline at end of file diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml index 7562c0f..1605aa7 100644 --- a/.idea/sqldialects.xml +++ b/.idea/sqldialects.xml @@ -1,6 +1,6 @@  <?xml version="1.0" encoding="UTF-8"?>  <project version="4">    <component name="SqlDialectMappings"> -    <file url="file://$PROJECT_DIR$/src/main/resources/sql/database.sql" dialect="H2" /> +    <file url="PROJECT" dialect="H2" />    </component>  </project>
\ No newline at end of file @@ -1,12 +1,19 @@  # SEPM Gruppenphase -## Projektname +## Bezirksstellen-Einsatzverwaltung -Projektname +Bezirksstellen-Einsatzverwaltung  ## Projektbeschreibung -Projektbeschreibung +Die Bezirksstellen-Einsatzverwaltung (kurz BEV) ist ein neues Programm, um die Verwaltung und +Disposition von Personal und Fahrzeugen zu vereinfachen. + +Im Gegenzug zu früheren Systemen bringt es die Verwaltung von Personal, Fahrzeugen und Einsätzen in +ein und dasselbe System, was es den DesponentInnen ermöglicht, schnell qualifizierte Entscheidungen +anhand aller relevanten Informationen zu treffen. Dabei wird der/die DisponentIn von einem +automatisierten Ranking-System unterstützt, das noch während der Eingabe der Einsatzdaten geeignete +Fahrzeuge vorschlägt.  ## Projektteam @@ -6,7 +6,7 @@      <groupId>at.ac.tuwien.sepm.assignment.groupphase</groupId>      <artifactId>ss18_sepm_qse_13<!-- add your semester and group number here --></artifactId> -    <version>1.0-SNAPSHOT</version> +    <version>2.0-SNAPSHOT</version>      <properties>          <!-- build properties --> @@ -19,7 +19,7 @@          <slf4j.version>1.8.0-beta2</slf4j.version>          <auto-value.version>1.6</auto-value.version>          <!-- runtime dependencies --> -        <h2.version>1.4.197</h2.version> +        <h2.version>1.4.196</h2.version>          <logback.version>1.3.0-alpha4</logback.version>          <!-- test dependencies -->          <junit.version>4.12</junit.version> diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/application/MainApplication.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/application/MainApplication.java index 01c04d3..d8365a7 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/application/MainApplication.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/application/MainApplication.java @@ -1,6 +1,6 @@  package at.ac.tuwien.sepm.assignment.groupphase.application; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.userInterface.CreateOperationController; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.CreateOperationController;  import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader;  import javafx.application.Application;  import javafx.application.Platform; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ArchiveOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ArchiveOperationController.java new file mode 100644 index 0000000..80d9fc4 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ArchiveOperationController.java @@ -0,0 +1,127 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.OperationService; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.Collection; +import java.util.EnumSet; +import java.util.LinkedList; +import java.util.Objects; +import java.util.stream.Collectors; +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; +import javafx.scene.control.Hyperlink; +import javafx.scene.control.Label; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.FlowPane; +import org.springframework.stereotype.Controller; + +@Controller +public class ArchiveOperationController { +    @FXML private AnchorPane apDetails; +    @FXML private Label lblCodeHeader; +    @FXML private Hyperlink hypBack; +    @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 LinkedList<Operation> list = new LinkedList<>(); + +    public ArchiveOperationController(OperationService operationService) { +        this.operationService = operationService; +    } + +    @FXML +    private void initialize() { +        try { +            list.addAll(operationService.list(EnumSet.of(Status.CANCELLED, Status.COMPLETED))); +        } catch (ServiceException e) { +            Alert alert = new Alert(AlertType.ERROR); +            alert.setTitle("Fehler"); +            alert.setHeaderText("Fehler!"); +            alert.setContentText("Die Einsätze konnten nicht geladen werden!"); +            alert.showAndWait(); +        } +        for (Operation operation : list) { +            Button b = new Button(); +            b.setPrefHeight(200); +            b.setPrefWidth(750 / 2); +            b.setText(operation.opCode()); +            b.setOnAction(event -> buttonClicked(b)); +            archiveOperationFlowPane.getChildren().add(b); +        } +    } + +    private Operation detailOperation; + +    private void buttonClicked(Button button) { +        int size = archiveOperationFlowPane.getChildren().size(); +        int index = 0; +        for (int i = 0; i < size; i++) { +            if (archiveOperationFlowPane.getChildren().get(i) == button) { +                index = i; +                break; +            } +        } +        detailOperation = list.get(index); +        setOperation(); +        setDetailsVisible(true); +    } + +    private void setOperation() { +        lblCodeHeader.setText(detailOperation.opCode()); +        String date = "am "; +        if (detailOperation.created() != null) { +            LocalDateTime myDateTime = +                    LocalDateTime.ofInstant( +                            Objects.requireNonNull(detailOperation.created()), ZoneOffset.UTC); +            date += +                    myDateTime.getDayOfMonth() +                            + "." +                            + myDateTime.getMonth().getValue() +                            + "." +                            + myDateTime.getYear(); +            lblDate.setText(date); +        } else { +            lblDate.setText("---"); +        } + +        lblOpCode.setText(detailOperation.opCode()); +        Collection<String> elements = +                detailOperation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList()); +        String result = String.join(", ", elements); + +        lblVehicles.setText(result); +        lblAddress.setText(detailOperation.destination()); + +        for (Vehicle vehicle : detailOperation.vehicles()) { +            Button b = new Button(); +            b.setPrefHeight(200); +            b.setPrefWidth(600 / 2); +            b.setText(vehicle.name()); +            fpVehicles.getChildren().add(b); +        } +    } + +    public void setListVisible(boolean b) { +        archiveOperationFlowPane.setVisible(b); +    } + +    private void setDetailsVisible(boolean b) { +        apDetails.setVisible(b); +    } + +    public void backClicked() { +        fpVehicles.getChildren().clear(); +        setDetailsVisible(false); +    } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateCarController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateCarController.java index b6693d0..ce795da 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateCarController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateCarController.java @@ -8,17 +8,22 @@ import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.Vehicle  import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException;  import java.lang.invoke.MethodHandles; +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.geometry.HPos; +import javafx.geometry.Orientation;  import javafx.scene.control.Alert;  import javafx.scene.control.Alert.AlertType;  import javafx.scene.control.Button;  import javafx.scene.control.ButtonType;  import javafx.scene.control.CheckBox;  import javafx.scene.control.ChoiceBox; +import javafx.scene.layout.FlowPane;  import javafx.stage.Stage;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory; @@ -30,17 +35,21 @@ public class CreateCarController {      @FXML private ChoiceBox<String> cmb_Ctyp;      @FXML private ChoiceBox<String> cmb_typ;      @FXML private Button btn_cancel; +    @FXML private Button btn_create;      @FXML private CheckBox cbx_NEF; +    @FXML private FlowPane fp_vehicleList;      private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());      private final VehicleService vehicleService; +    private boolean update = false; +    private long vid = -1;      public CreateCarController(VehicleService vehicleService) {          this.vehicleService = vehicleService;      }      @FXML -    public void initialize() { +    private void initialize() {          cmb_Ctyp.setItems(                  FXCollections.observableArrayList(                          Stream.of( @@ -62,36 +71,74 @@ public class CreateCarController {                                  .map(Enum::toString)                                  .collect(Collectors.toList())));          cmb_typ.setValue(VehicleType.BKTW.toString()); +        vehicleListFP();      }      @FXML -    public void onCancelClicked() { +    private void onCancelClicked() {          ((Stage) btn_cancel.getScene().getWindow()).close();      }      @FXML -    public void createCar(ActionEvent actionEvent) { -        Vehicle vehicle = -                Vehicle.builder() -                        .constructionType(parseConstructionType()) -                        .type(parseType()) -                        .name("") -                        .status(Status.ABGEMELDET) -                        .hasNef(cbx_NEF.isSelected()) -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (InvalidVehicleException e) { -            LOG.error("Invalid Vehicle: {}", e); -            createComplete(AlertType.ERROR, "Ungültige Eingabe", e.getMessage()); -            return; -        } catch (ServiceException e) { -            LOG.error("Exception: {}", e); -            createComplete(AlertType.ERROR, "Fehler", e.getMessage()); -            return; +    private void createCar(ActionEvent actionEvent) { + +        if (!update) { +            Vehicle vehicle = +                    Vehicle.builder() +                            .constructionType(parseConstructionType()) +                            .type(parseType()) +                            .name("") +                            .status(Status.ABGEMELDET) +                            .hasNef(cbx_NEF.isSelected()) +                            .build(); +            try { +                vehicleService.add(vehicle); +                setToStart(); +            } catch (InvalidVehicleException e) { +                LOG.error("Invalid Vehicle: {}", e); +                createComplete(AlertType.ERROR, "Ungültige Eingabe", e.getMessage()); +                setToStart(); +                return; +            } catch (ServiceException e) { +                LOG.error("Exception: {}", e); +                createComplete(AlertType.ERROR, "Fehler", e.getMessage()); +                setToStart(); +                return; +            } +            createComplete( +                    AlertType.CONFIRMATION, +                    "Speichern Erfolgreich", +                    "Auto wurde erfolgreich angelegt"); +        } else { +            try { +                Vehicle vehicle = +                        Vehicle.builder() +                                .id(vid) +                                .constructionType(parseConstructionType()) +                                .type(parseType()) +                                .name("") +                                .status(Status.ABGEMELDET) +                                .hasNef(cbx_NEF.isSelected()) +                                .build(); +                vehicleService.update(vehicle); +                setToStart(); +            } catch (InvalidVehicleException e) { +                LOG.error("Invalid Vehicle: {}", e); +                createComplete(AlertType.ERROR, "Ungültige Eingabe", e.getMessage()); +                setToStart(); +                return; +            } catch (ServiceException e) { +                LOG.error("Exception: {}", e); +                createComplete(AlertType.ERROR, "Fehler", e.getMessage()); +                setToStart(); +                return; +            } +            createComplete( +                    AlertType.CONFIRMATION, +                    "Bearbiten Erfolgreich", +                    "Auto wurde erfolgreich bearbeitet");          } -        createComplete( -                AlertType.CONFIRMATION, "Speichern Erfolgreich", "Auto wurde erfolgreich angelegt"); +        vehicleListFP();      }      private ConstructionType parseConstructionType() { @@ -113,4 +160,47 @@ public class CreateCarController {          alert.setHeaderText(headerText);          alert.showAndWait();      } + +    private void vehicleListFP() { +        Set<Vehicle> vehicleList = null; +        fp_vehicleList.getChildren().clear(); +        try { +            vehicleList = vehicleService.list(EnumSet.range(Status.ABGEMELDET, Status.FREI_FUNK)); +        } catch (ServiceException e) { +            e.printStackTrace(); +        } + +        fp_vehicleList.setOrientation(Orientation.HORIZONTAL); +        fp_vehicleList.setColumnHalignment(HPos.LEFT); // align labels on left +        fp_vehicleList.setPrefWrapLength(200); // preferred height = 200 + +        for (Vehicle v : vehicleList) { +            Button b = new Button(v.name()); +            b.setOnAction(event -> updateVehicle(v)); +            fp_vehicleList.getChildren().add(b); +        } +        fp_vehicleList.setVisible(true); +    } + +    private void setToStart() { +        btn_create.setText("Erstellen"); +        cbx_NEF.setSelected(false); +        cmb_typ.setValue(VehicleType.BKTW.name()); +        cmb_Ctyp.setValue(ConstructionType.NORMAL.name()); +        update = false; +    } + +    private void updateVehicle(Vehicle vehicle) { +        cmb_Ctyp.setValue(vehicle.constructionType().name()); +        cmb_typ.setValue(vehicle.type().name()); +        cbx_NEF.setSelected(vehicle.hasNef()); +        btn_create.setText("Speichern"); +        vid = vehicle.id(); +        update = true; +    } + +    @FXML +    public void cancelAction(ActionEvent actionEvent) { +        setToStart(); +    }  } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewEmployeeController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewEmployeeController.java index d81f6d7..15282cc 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewEmployeeController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewEmployeeController.java @@ -5,44 +5,56 @@ import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.Ed  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.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.lang.invoke.MethodHandles;  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.Alert;  import javafx.scene.control.Alert.AlertType;  import javafx.scene.control.Button;  import javafx.scene.control.ButtonType;  import javafx.scene.control.CheckBox;  import javafx.scene.control.ChoiceBox; -import javafx.scene.control.Hyperlink; +import javafx.scene.control.Label;  import javafx.scene.control.TextField; -import javafx.stage.Stage;  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(MethodHandles.lookup().lookupClass());      private final EmployeeService employeeService; +    @FXML private Label lblHeader;      @FXML private CheckBox inputIsDriver;      @FXML private CheckBox inputIsPilot; -    @FXML private Hyperlink btnCancel; -    @FXML private Button btnCreate;      @FXML private TextField inputName;      @FXML private ChoiceBox<String> 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 -    public void initialize() { +    private void initialize() {          inputQualification.setItems(                  FXCollections.observableArrayList(                          Stream.of( @@ -56,18 +68,28 @@ public class CreateNewEmployeeController {                                  .collect(Collectors.toList())));          inputQualification.setValue(EducationLevel.RS.toString()); +        employee = +                Employee.builder() +                        .name("") +                        .educationLevel(EducationLevel.RS) +                        .isDriver(false) +                        .isPilot(false) +                        .birthday(LocalDate.MIN) +                        .build();      }      @FXML -    public void onCancelClicked() { -        ((Stage) inputQualification.getScene().getWindow()).close(); +    private void onCancelClicked() { +        if (consumerCancelClicked != null) { +            consumerCancelClicked.run(); +        }      }      @FXML -    public void onCreateClicked() { +    private void onCreateClicked() { -        Employee employee = -                Employee.builder() +        employee = +                employee.toBuilder()                          .name(inputName.getText())                          .educationLevel(parseEducationLevel())                          .birthday(LocalDate.MIN) // TODO: change UI to include birthday field @@ -76,7 +98,11 @@ public class CreateNewEmployeeController {                          .build();          try { -            employeeService.add(employee); +            if (isEdit) { +                employeeService.update(employee); +            } else { +                employeeService.add(employee); +            }          } catch (InvalidEmployeeException e) {              LOG.error("Invalid Employee: {}", e); @@ -99,6 +125,10 @@ public class CreateNewEmployeeController {                  AlertType.INFORMATION,                  "Erfolgreich angelegt",                  "Mitarbeiter wurde erfolgreich angelegt und gespeichert!"); + +        if (consumerCreateClicked != null) { +            consumerCreateClicked.run(); +        }      }      private void showModalDialogWithOkButton( @@ -114,4 +144,46 @@ public class CreateNewEmployeeController {          }          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<Object, CreateNewEmployeeController> 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/einsatzverwaltung/controller/CreateOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateOperationController.java new file mode 100644 index 0000000..57759e3 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateOperationController.java @@ -0,0 +1,365 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.OperationService; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.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 at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import java.io.IOException; +import java.lang.invoke.MethodHandles; +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.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +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.stage.Stage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class CreateOperationController { + +    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + +    public AnchorPane apCreateOperation; +    @FXML private TextField txtCode; +    @FXML private TextField txtAddress; +    @FXML private TextField txtNote; +    @FXML private Button btnCreateOperation; +    @FXML private ListView<Vehicle> lvVehicles; +    @FXML private ListView<Operation> lvActiveOperations; +    @FXML private Label lblChosenVehicles; +    @FXML private AnchorPane apInvisible; +    @FXML private OperationDetailsController operationDetailsController; +    @FXML private FlowPane fpVehicles; + +    private LinkedList<Vehicle> chosenVehicles = new LinkedList<>(); + +    private final OperationService operationService; +    private final VehicleService vehicleService; +    private final SpringFXMLLoader fxmlLoader; + +    public CreateOperationController( +            OperationService operationService, +            VehicleService vehicleService, +            SpringFXMLLoader fxmlLoader) { +        this.operationService = operationService; +        this.vehicleService = vehicleService; +        this.fxmlLoader = fxmlLoader; +    } + +    @FXML +    private void initialize() { +        lblChosenVehicles.setText("keine ausgewählt"); +        lvActiveOperations.setCellFactory( +                param -> +                        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()); +                                } +                            } +                        }); +        lvActiveOperations.setOnMouseClicked( +                event -> { +                    if (event.getClickCount() == 2) { +                        if (lvActiveOperations.getSelectionModel().getSelectedItem() == null) { +                            return; +                        } +                        openDetailsWindow(lvActiveOperations.getSelectionModel().getSelectedItem()); +                    } +                }); +    } + +    public void updateList() { +        try { +            fpVehicles.getChildren().clear(); + +            // TODO: this should probably be handled differently +            Set<Vehicle> 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); +                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()); +                                        } +                                    } +                                }); + +                fpVehicles.getChildren().add(controller.getRootElement()); +            } +        } catch (ServiceException | IOException | InvalidOperationException e) { +            LOG.error("Error while updating list.", e); + +            Alert alert = new Alert(Alert.AlertType.ERROR); +            alert.setTitle("Fehler"); +            alert.setHeaderText("Fehler!"); +            alert.setContentText(e.getMessage()); +            alert.showAndWait(); +        } +        try { +            lvActiveOperations.setItems( +                    FXCollections.observableArrayList( +                            operationService.list(EnumSet.of(Status.ACTIVE)))); +        } catch (ServiceException e) { +            Alert alert = new Alert(Alert.AlertType.ERROR); +            alert.setTitle("Fehler - Einsätze"); +            alert.setHeaderText("Beim Holen der aktiven Einsätze ist ein Fehler aufgetreten."); +            alert.setContentText(e.getMessage()); +            alert.showAndWait(); +        } +    } + +    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 | ServiceException e) { +                            LOG.error("Error while setting status.", e); +                            Alert a = new Alert(AlertType.ERROR, e.getMessage()); +                            a.show(); +                        } +                    }); + +            menu.getItems().add(mi); +        } + +        MenuItem abmelden = new MenuItem("abmelden"); + +        abmelden.setOnAction( +                event -> { +                    try { +                        List<Registration> registrations = data.registrations(); +                        assert registrations +                                != null; // Otherwise the element shouldn't be in the list. + +                        List<Registration> 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 | ServiceException e) { +                        LOG.error("Error while unregistering.", e); +                        Alert a = new Alert(AlertType.ERROR, e.getMessage()); +                        a.show(); +                    } +                }); + +        menu.getItems().add(abmelden); +        return menu; +    } + +    @FXML +    protected void createOperationClicked() { +        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 | InvalidOperationException e) { +            Alert alert = new Alert(Alert.AlertType.ERROR); +            alert.setTitle("Fehler"); +            alert.setHeaderText("Fehler!"); +            alert.setContentText(e.getMessage()); +            alert.showAndWait(); +            return; +        } +        Alert alert = new Alert(AlertType.CONFIRMATION); +        alert.setTitle("Erfolg"); +        alert.setHeaderText("Erfolgreich gespeichert"); +        alert.setContentText("Der Einsatz wurde erfolgreich gespeichert."); +        alert.showAndWait(); +        updateList(); +        lblChosenVehicles.setText("keine ausgewählt"); +        txtAddress.setText(""); +        txtCode.setText(""); +        txtNote.setText(""); +        chosenVehicles = new LinkedList<>(); +    } + +    public void onRegistrationLinkClicked(ActionEvent actionEvent) { +        openNewWindow("RegistrationWindow.fxml"); +    } + +    public void onEmployeeLinkClicked(ActionEvent actionEvent) { +        openNewWindow("listEmployees.fxml"); +    } + +    public void onVehicleLinkClicked(ActionEvent actionEvent) { +        openNewWindow("createCar.fxml"); +    } + +    public void onArchivLinkClicked() { +        openNewArchivWindow(); +    } + +    private void openNewArchivWindow() { +        Stage stage = new Stage(); +        try { +            stage.setScene( +                    new Scene( +                            (Parent) +                                    fxmlLoader.load( +                                            getClass() +                                                    .getResourceAsStream( +                                                            "/fxml/ArchiveOperation.fxml")))); +        } catch (IOException e) { +            LOG.error("Could not open new window: {}", e); +        } +        stage.setTitle("Einsatz erstellen"); +        stage.centerOnScreen(); +        stage.show(); +        updateList(); +    } + +    private void openNewWindow(String fxmlFileName) { + +        Stage stage = new Stage(); +        try { +            stage.setScene( +                    new Scene( +                            (Parent) +                                    fxmlLoader.load( +                                            getClass() +                                                    .getResourceAsStream( +                                                            "/fxml/" + fxmlFileName)))); +        } catch (IOException e) { +            LOG.error("Could not open new window: {}", e); +        } + +        stage.setTitle("Ressourcenverwaltung"); +        stage.centerOnScreen(); +        stage.showAndWait(); // important to call wait so that updateList is executed afterwards + +        updateList(); +    } + +    void setVisible(boolean b) { +        apInvisible.setVisible(!b); +    } + +    private void openDetailsWindow(Operation operation) { +        operationDetailsController.initOperation(operation); +        this.setVisible(false); +    } + +    @FXML +    public void onOperationCodeChanged(KeyEvent keyEvent) { +        if (keyEvent.getCode() == KeyCode.ENTER) { +            updateList(); +        } +    } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/EmployeeListItemController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/EmployeeListItemController.java new file mode 100644 index 0000000..11b5626 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/EmployeeListItemController.java @@ -0,0 +1,83 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.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 { + +    @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 Node rootElement; +    private Employee employee; + +    private Consumer<Employee> consumerEditEmployeeClicked; + +    @FXML +    public void onEditEmployeeClicked() { +        if (consumerEditEmployeeClicked != null) { +            consumerEditEmployeeClicked.accept(employee); +        } +    } + +    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<Object, EmployeeListItemController> wrapper = +                loader.loadAndWrap("/fxml/employeeListItem.fxml", EmployeeListItemController.class); +        Node root = (Node) wrapper.getLoadedObject(); +        EmployeeListItemController controller = wrapper.getController(); +        controller.rootElement = root; +        return controller; +    } + +    public Node getRootElement() { +        return rootElement; +    } + +    public Employee getEmployee() { +        return employee; +    } + +    public void setConsumerEditEmployeeClicked(Consumer<Employee> consumerEditEmployeeClicked) { +        this.consumerEditEmployeeClicked = consumerEditEmployeeClicked; +    } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/FilterEmployeesController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/FilterEmployeesController.java new file mode 100644 index 0000000..6d6214d --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/FilterEmployeesController.java @@ -0,0 +1,60 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.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.springframework.context.annotation.Scope; +import org.springframework.stereotype.Controller; + +@Controller +@Scope("prototype") +public class FilterEmployeesController { + +    @FXML private TextField inputFilterString; + +    private Consumer<String> consumerFilterTextChanged; +    private Runnable consumerAddEmployeeClicked; + +    private Node rootElement; + +    @FXML +    private void onAddEmployeeClicked() { +        if (consumerAddEmployeeClicked != null) { +            consumerAddEmployeeClicked.run(); +        } +    } + +    @FXML +    private void onFilterTextChanged() { +        if (consumerFilterTextChanged != null) { +            consumerFilterTextChanged.accept(inputFilterString.getText()); +        } +    } + +    public void setOnFilterTextChangedListener(Consumer<String> callback) { +        this.consumerFilterTextChanged = callback; +    } + +    public void setOnAddEmployeeClickedListener(Runnable callback) { +        this.consumerAddEmployeeClicked = callback; +    } + +    public static FilterEmployeesController createFilterEmployeesController( +            SpringFXMLLoader fxmlLoader) throws IOException { +        FXMLWrapper<Object, FilterEmployeesController> 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/einsatzverwaltung/controller/ListEmployeesController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ListEmployeesController.java new file mode 100644 index 0000000..25f1263 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ListEmployeesController.java @@ -0,0 +1,117 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.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.lang.invoke.MethodHandles; +import javafx.fxml.FXML; +import javafx.geometry.Insets; +import javafx.scene.Node; +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 ListEmployeesController { + +    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + +    @FXML private AnchorPane containerHeader; +    @FXML private FlowPane flowPaneEmployeeList; + +    private final EmployeeService employeeService; +    private final SpringFXMLLoader fxmlLoader; + +    public ListEmployeesController(EmployeeService employeeService, SpringFXMLLoader fxmlLoader) { +        this.employeeService = employeeService; +        this.fxmlLoader = fxmlLoader; +    } + +    @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("Could not initialize controller: {}", e); +        } +    } + +    private void openAddEmployee() { +        openEmployee(null); +    } + +    private void openEditEmployee(Employee 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("Could not prepare UI for adding employee: {}", e); +        } +    } + +    private void updateEmployeeList() { +        updateEmployeeList(""); +    } + +    private void updateEmployeeList(String searchString) { +        try { +            flowPaneEmployeeList.getChildren().clear(); +            employeeService +                    .list() +                    .stream() +                    .filter( +                            employee -> +                                    searchString.trim().isEmpty() +                                            || employee.name() +                                                    .toLowerCase() +                                                    .contains(searchString.toLowerCase())) +                    .forEach(this::addEmployeeToFlowPane); +        } catch (ServiceException e) { +            LOG.error("Could not fetch employee list: {}", e); +        } +    } + +    private void addEmployeeToFlowPane(Employee employee) { +        Insets listItemMargins = new Insets(0, 5, 10, 5); + +        try { +            EmployeeListItemController controller = +                    EmployeeListItemController.createEmployeeListItemController( +                            fxmlLoader, employee); +            Node rootElement = controller.getRootElement(); +            flowPaneEmployeeList.getChildren().add(rootElement); +            FlowPane.setMargin(rootElement, listItemMargins); +            controller.setConsumerEditEmployeeClicked(this::openEditEmployee); +        } catch (IOException e) { +            LOG.error("Could not create a new EmployeeListItem: {}", e); +        } +    } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/OperationDetailsController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/OperationDetailsController.java new file mode 100644 index 0000000..dc7e969 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/OperationDetailsController.java @@ -0,0 +1,162 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.OperationService; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.VehicleService; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.util.Collection; +import java.util.EnumSet; +import java.util.stream.Collectors; +import javafx.collections.FXCollections; +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.layout.AnchorPane; +import org.springframework.stereotype.Controller; + +@Controller +public class OperationDetailsController { + +    public Operation operation; +    private final OperationService operationService; +    private final VehicleService vehicleService; +    private final CreateOperationController createOperationController; +    @FXML private ListView<Vehicle> lvVehicles; +    @FXML private ListView<Operation> 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() { +        lvVehicles.setCellFactory( +                param -> +                        new ListCell<>() { +                            @Override +                            protected void updateItem(Vehicle item, boolean empty) { +                                super.updateItem(item, empty); + +                                if (empty || item == null || item.name() == null) { +                                    setText(null); +                                } else { +                                    setText(item.name()); +                                } +                            } +                        }); +        lvActiveOperations.setCellFactory( +                param -> +                        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()); +                                } +                            } +                        }); +        lvActiveOperations.setOnMouseClicked( +                event -> { +                    if (event.getClickCount() == 2) { +                        if (lvActiveOperations.getSelectionModel().getSelectedItem() == null) { +                            return; +                        } +                        initOperation(lvActiveOperations.getSelectionModel().getSelectedItem()); +                    } +                }); +    } + +    void initOperation(Operation operation) { +        fillActiveList(); +        this.operation = operation; +        lblCode.setText(operation.opCode()); +        Collection<String> 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()); +        lvVehicles.setItems(FXCollections.observableArrayList(operation.vehicles())); +        operationDetailsAP.setVisible(true); +    } + +    private void fillActiveList() { +        try { +            lvActiveOperations.setItems( +                    FXCollections.observableArrayList( +                            operationService.list(EnumSet.of(Status.ACTIVE)))); +        } catch (ServiceException e) { +            Alert alert = new Alert(AlertType.ERROR); +            alert.setTitle("Fehler"); +            alert.setHeaderText("Fehler!"); +            alert.setContentText(e.getMessage()); +            alert.showAndWait(); +        } +    } + +    @FXML +    public void closeOperationClicked() { +        try { +            operationService.complete(operation.id(), Status.COMPLETED); +        } catch (InvalidOperationException | ServiceException e) { +            Alert alert = new Alert(AlertType.ERROR); +            alert.setTitle("Fehler"); +            alert.setHeaderText("Fehler!"); +            alert.setContentText(e.getMessage()); +            alert.showAndWait(); +            return; +        } +        Alert alert = new Alert(AlertType.CONFIRMATION); +        alert.setTitle("Erfolg"); +        alert.setHeaderText("Erfolgreich aktualisiert"); +        alert.setContentText("Der Einsatz wurde erfolgreich aktualisiert."); +        alert.showAndWait(); +        closeWindow(); +        createOperationController.updateList(); +    } + +    public void cancelOperationClicked() { +        try { +            operationService.complete(operation.id(), Status.CANCELLED); +        } catch (InvalidOperationException | ServiceException e) { +            Alert alert = new Alert(AlertType.ERROR); +            alert.setTitle("Fehler"); +            alert.setHeaderText("Fehler!"); +            alert.setContentText(e.getMessage()); +            alert.showAndWait(); +            return; +        } +        Alert alert = new Alert(AlertType.CONFIRMATION); +        alert.setTitle("Erfolg"); +        alert.setHeaderText("Erfolgreich aktualisiert"); +        alert.setContentText("Der Einsatz wurde erfolgreich aktualisiert."); +        alert.showAndWait(); +        closeWindow(); +        createOperationController.updateList(); +    } + +    public void closeWindow() { +        operationDetailsAP.setVisible(false); +        this.createOperationController.setVisible(true); +    } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/RegistrationWindowController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/RegistrationWindowController.java index bf413bb..4653663 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/RegistrationWindowController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/RegistrationWindowController.java @@ -15,8 +15,10 @@ 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 javafx.beans.property.SimpleStringProperty;  import javafx.collections.FXCollections;  import javafx.collections.ObservableList; @@ -31,7 +33,6 @@ import javafx.scene.control.TextField;  import javafx.stage.Stage;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.stereotype.Controller;  @Controller @@ -39,46 +40,40 @@ public class RegistrationWindowController {      private static final Logger LOG = LoggerFactory.getLogger(RegistrationWindowController.class); -    private EmployeeService employeeService; +    private final EmployeeService employeeService; -    private VehicleService vehicleService; +    private final VehicleService vehicleService; -    private RegistrationService registrationService; +    private final RegistrationService registrationService; -    @Autowired -    public void setEmployeeService(EmployeeService employeeService) { +    public RegistrationWindowController( +            EmployeeService employeeService, +            VehicleService vehicleService, +            RegistrationService registrationService) {          this.employeeService = employeeService; -    } - -    @Autowired -    public void setVehicleService(VehicleService vehicleService) {          this.vehicleService = vehicleService; -    } - -    @Autowired -    public void setRegistrationService(RegistrationService registrationService) {          this.registrationService = registrationService;      } -    @FXML public ChoiceBox<Integer> cbStart; -    @FXML public ChoiceBox<Integer> cbEnd; -    @FXML public Label lVehicles; -    @FXML public Label lEmployees; -    @FXML public TextField tfVehicleSearch; -    @FXML public TextField tfEmployeeSearch; -    @FXML public TableView<Vehicle> tvVehicles; -    @FXML public TableView<Employee> tvEmployees; -    @FXML public TableColumn<Vehicle, String> tcVehicles; -    @FXML public TableColumn<Employee, String> tcEmployees; +    @FXML private ChoiceBox<Integer> cbStart; +    @FXML private ChoiceBox<Integer> cbEnd; +    @FXML private Label lVehicles; +    @FXML private Label lEmployees; +    @FXML private TextField tfVehicleSearch; +    @FXML private TextField tfEmployeeSearch; +    @FXML private TableView<Vehicle> tvVehicles; +    @FXML private TableView<Employee> tvEmployees; +    @FXML private TableColumn<Vehicle, String> tcVehicles; +    @FXML private TableColumn<Employee, String> tcEmployees;      private Vehicle chosenVehicle;      private List<Employee> chosenEmployees = new LinkedList<>();      @FXML -    public void initialize() { +    private void initialize() {          // will have to be replaced for FlowPane          try { -            List<Vehicle> vehicles = vehicleService.list(EnumSet.of(Status.ABGEMELDET)); +            Set<Vehicle> vehicles = vehicleService.list(EnumSet.of(Status.ABGEMELDET));              tcVehicles.setCellValueFactory(x -> new SimpleStringProperty(x.getValue().name()));              tvVehicles.setItems(FXCollections.observableArrayList(vehicles));          } catch (ServiceException e) { @@ -92,7 +87,7 @@ public class RegistrationWindowController {              alert.show();          }          try { -            List<Employee> employees = employeeService.list(); +            Set<Employee> employees = employeeService.list();              tcEmployees.setCellValueFactory(x -> new SimpleStringProperty(x.getValue().name()));              tvEmployees.setItems(FXCollections.observableArrayList(employees));          } catch (ServiceException e) { @@ -118,10 +113,15 @@ public class RegistrationWindowController {          tvEmployees.setOnMousePressed(                  mouseEvent -> {                      if (mouseEvent.isPrimaryButtonDown() && mouseEvent.getClickCount() == 2) { -                        chosenEmployees.add(tvEmployees.getSelectionModel().getSelectedItem()); -                        if (chosenEmployees == null) { +                        Employee selection = tvEmployees.getSelectionModel().getSelectedItem(); +                        if (selection == null) {                              return; +                        } else if (chosenEmployees.contains(selection)) { +                            chosenEmployees.remove(selection); +                        } else { +                            chosenEmployees.add(selection);                          } +                          StringBuilder text = new StringBuilder();                          for (Employee employee : chosenEmployees) {                              text.append(employee.name()).append("\n"); @@ -141,34 +141,40 @@ public class RegistrationWindowController {      public void cancel() {          LOG.debug("Cancel Button clicked"); +        chosenEmployees.clear();          ((Stage) lVehicles.getScene().getWindow()).close();      }      public void create() {          LOG.debug("Create Button clicked"); -        List<Registration> registrations = new LinkedList<>(); - -        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()); -        } +        Set<Registration> 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(); +          } catch (InvalidVehicleException e) {              // NOT THROWN ANYWHERE RIGHT NOW              LOG.info( @@ -180,6 +186,7 @@ public class RegistrationWindowController {              alert.setHeaderText("Das spezifizierte Fahrzeug ist nicht gültig.");              alert.setContentText(e.getMessage());              alert.show(); +            chosenEmployees.clear();          } catch (ServiceException e) {              LOG.warn(                      "Caught ServiceException while getting vehicles. Showing it to user. Error message: {}", @@ -189,6 +196,7 @@ public class RegistrationWindowController {              alert.setHeaderText("Beim Erstellen der Anmeldung ist ein Fehler aufgetreten.");              alert.setContentText(e.getMessage());              alert.show(); +            chosenEmployees.clear();          } catch (InvalidRegistrationException e) {              LOG.info(                      "Caught InvalidRegistrationException. Showing it to user. Error message: {}", @@ -199,6 +207,7 @@ public class RegistrationWindowController {                      "Die gewählte Kombination von Fahrzeug und Personal ist nicht gültig!");              alert.setContentText(e.getMessage());              alert.show(); +            chosenEmployees.clear();          }      }  } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/ui/vehiclepane/VehiclePaneController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/VehiclePaneController.java index 2db6f37..6c0932b 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/ui/vehiclepane/VehiclePaneController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/VehiclePaneController.java @@ -1,11 +1,10 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.ui.vehiclepane; +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle;  import java.io.IOException;  import java.time.Instant; -import java.util.Date;  import java.util.List;  import java.util.Optional;  import javafx.fxml.FXML; @@ -14,15 +13,12 @@ import javafx.scene.Node;  import javafx.scene.image.Image;  import javafx.scene.image.ImageView;  import javafx.scene.text.Text; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory;  public class VehiclePaneController { -    @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; + +    private static Logger LOG = LoggerFactory.getLogger(VehiclePaneController.class);      public static VehiclePaneController createVehiclePane() throws IOException {          FXMLLoader fxmlLoader = @@ -34,12 +30,25 @@ public class VehiclePaneController {          return result;      } +    @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; +      private Node rootElement; +    private Vehicle data;      public Node getRootElement() {          return rootElement;      } +    public Vehicle getData() { +        return data; +    } +      /**       * * Set the displayed data of this VehiclePane.       * @@ -52,27 +61,33 @@ public class VehiclePaneController {          String constrType = vehicle.constructionType().name();          txtRooftype.setText(                  constrType.substring(0, 1).toUpperCase() + constrType.substring(1).toLowerCase()); -        txtNumber.setText("" + vehicle.id()); +        txtNumber.setText("-" + vehicle.id());          if (vehicle.hasNef()) { -            ivNEF.setImage(new Image("../images/NEF.png")); +            ivNEF.setImage(new Image("images/NEF.png"));              txtNEF.setText("hat NEF-Halterung");          } else { -            ivNEF.setImage(new Image("../images/NotNEF.png")); +            ivNEF.setImage(new Image("images/NotNEF.png"));              txtNEF.setText("keine NEF-Halterung");          }          if (showQualification) { -            Instant now = (new Date()).toInstant(); +            Instant now = Instant.now();              List<Registration> regs = vehicle.registrations(); -            assert regs != null; +            if (regs == null) { +                return; +            } +              Optional<EducationLevel> edu =                      regs.stream()                              .filter(reg -> reg.start().isBefore(now) && reg.end().isAfter(now))                              .map(reg -> reg.employee().educationLevel())                              .max(EducationLevel::compareTo); -            assert edu.isPresent(); +            if (!edu.isPresent()) { +                return; +            } +              txtQualification.setText(edu.get().name());          } else {              txtQualification.setVisible(false); @@ -80,5 +95,19 @@ public class VehiclePaneController {              ivQualification.setVisible(false);              ivQualification.setManaged(false);          } + +        this.data = vehicle; +    } + +    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/einsatzverwaltung/dao/DBOperationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java deleted file mode 100644 index 672424a..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java +++ /dev/null @@ -1,161 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.util.EnumSet; -import java.util.List; - -public class DBOperationDAO implements OperationDAO { - -    private JDBCConnectionManager jdbcConnectionManager; - -    public DBOperationDAO(JDBCConnectionManager j) { -        jdbcConnectionManager = j; -    } - -    @Override -    public long add(Operation operation) throws PersistenceException { -        if (operation == null) { -            throw new PersistenceException("Das der Datenbank übergebene Objekt ist fehlerhaft!"); -        } -        PreparedStatement pstmt = null; -        try { -            pstmt = -                    jdbcConnectionManager -                            .getConnection() -                            .prepareStatement( -                                    "INSERT INTO operation(opCode, severity, " -                                            + "created, destination, additionalInfo, status) values (?,?,?,?,?,?)", -                                    java.sql.Statement.RETURN_GENERATED_KEYS); - -            if (operation.opCode() == null) { -                throw new PersistenceException("Code darf nicht null sein!"); -            } else if (operation.opCode().length() > 20) -                throw new PersistenceException( -                        "Länge des OP-Codes überschreitet erlaubte Länge von 100 Zeichen!"); -            else pstmt.setString(1, operation.opCode()); -            /*switch (operation.severity()) { -                case A: -                    pstmt.setInt(2, 0); -                    break; -                case B: -                    pstmt.setInt(2, 1); -                    break; -                case C: -                    pstmt.setInt(2, 2); -                    break; -                case D: -                    pstmt.setInt(2, 3); -                    break; -                case E: -                    pstmt.setInt(2, 4); -                    break; -                case O: -                    pstmt.setInt(2, 5); -                    break; -                default: -                    throw new PersistenceException( -                            "Schwere des Einsatzes konnte nicht validiert werden!"); -            }*/ -            pstmt.setString(2, operation.severity().name()); -            if (operation.created() != null) { -                pstmt.setTimestamp(3, Timestamp.from(operation.created())); -            } else { -                throw new PersistenceException("Zeitpunkt der Erstellung darf nicht null sein!"); -            } - -            if (operation.destination() == null) { -                throw new PersistenceException("Einsatzort darf nicht null sein!"); -            } else if (operation.destination().length() > 100) { -                throw new PersistenceException( -                        "Länge der Adresse überschreitet erlaubte Länge von 100 Zeichen!"); -            } else { -                pstmt.setString(4, operation.destination()); -            } -            if (operation.additionalInfo().length() > 100) -                throw new PersistenceException( -                        "Länge der zusätzlichen Information überschreitet erlaubte Länge von 100 Zeichen!"); -            else pstmt.setString(5, operation.additionalInfo()); -            if (operation.status() == null) { -                throw new PersistenceException("Status darf nicht null sein!"); -            } else if (operation.status().toString().length() > 100) { -                throw new PersistenceException( -                        "Länge des Status überschreitet erlaubte Länge von 100 Zeichen!"); -            } else { -                pstmt.setString(6, operation.status().toString()); -            } -            pstmt.executeUpdate(); -            ResultSet rs = pstmt.getGeneratedKeys(); -            if (rs.next()) return rs.getInt(1); -            else throw new PersistenceException("Einsatz konnte nicht gespeichert werden"); -        } catch (SQLException e) { -            throw new PersistenceException(e); -        } finally { -            if (pstmt != null) { -                try { -                    pstmt.close(); -                } catch (SQLException e) { -                    throw new PersistenceException( -                            "Verbindung zur Datenbank konnte nicht geschlossen werden!", e); -                } -            } -        } -    } - -    @Override -    public void update(Operation operation) throws ElementNotFoundException, PersistenceException {} - -    @Override -    public Operation get(long operationId) throws ElementNotFoundException, PersistenceException { -        return null; -    } - -    @Override -    public List<Operation> list(EnumSet<Status> statuses) throws PersistenceException { -        return null; -    } - -    @Override -    public int connectVehicleToOperation(long vehicleID, long operationID) -            throws PersistenceException { -        PreparedStatement pstmt = null; -        try { -            pstmt = -                    jdbcConnectionManager -                            .getConnection() -                            .prepareStatement( -                                    "insert into VehicleOperation(vehicleId, operationId)" -                                            + "values (?,?)"); -            pstmt.setLong(1, vehicleID); -            pstmt.setLong(2, operationID); -            pstmt.executeUpdate(); - -            /* -            ResultSet rs = pstmt.getGeneratedKeys(); -            if (rs.next()) return rs.getInt(1); -            else -                throw new PersistenceException( -                        "Fahrzeug für die Operation konnte nicht abgespeichert werden!");*/ -        } catch (SQLException e) { -            throw new PersistenceException("Die Werte konnten nicht gespeichert werden!"); -        } finally { -            if (pstmt != null) { -                try { -                    pstmt.close(); -                } catch (SQLException e) { -                    throw new PersistenceException( -                            "Verbindung zur Datenbank konnte nicht geschlossen werden!", e); -                } -            } -        } - -        return 1; -    } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDAO.java index 564ce7c..539a8e5 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDAO.java @@ -3,7 +3,7 @@ package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import java.util.List; +import java.util.Set;  public interface EmployeeDAO { @@ -31,7 +31,7 @@ public interface EmployeeDAO {       * @return list containing all stored employees       * @throws PersistenceException if loading the stored employees failed       */ -    List<Employee> list() throws PersistenceException; +    Set<Employee> list() throws PersistenceException;      /**       * Remove employee with the given id from the store. diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDatabaseDAO.java new file mode 100644 index 0000000..43a5c9d --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDatabaseDAO.java @@ -0,0 +1,201 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; +import java.lang.invoke.MethodHandles; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Savepoint; +import java.sql.Statement; +import java.sql.Timestamp; +import java.util.HashSet; +import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Repository; + +@Repository +public class EmployeeDatabaseDAO implements EmployeeDAO { + +    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); +    private static final String INSERT_EMPLOYEE_VERSION = +            "INSERT INTO EmployeeVersion(name, birthday, educationLevel, isDriver, isPilot) " +                    + "VALUES(?, ?, ?, ?, ?)"; +    private static final String INSERT_EMPLOYEE = "INSERT INTO Employee(version) VALUES(?)"; +    private static final String LIST_EMPLOYEE = +            "SELECT emp.id, v.name, v.birthday, v.educationLevel, v.isDriver, v.isPilot " +                    + "FROM employee emp " +                    + "JOIN EmployeeVersion v ON v.id = emp.version"; +    private static final String UPDATE_EMPLOYEE = "UPDATE Employee SET version = ? WHERE id = ?"; + +    private final PreparedStatement insertEmployeeVersion, +            insertEmployee, +            listEmployee, +            updateEmployee; + +    private final Connection connection; + +    public EmployeeDatabaseDAO(JDBCConnectionManager connectionManager) +            throws PersistenceException { + +        try { + +            connection = connectionManager.getConnection(); +            insertEmployeeVersion = +                    connection.prepareStatement( +                            INSERT_EMPLOYEE_VERSION, Statement.RETURN_GENERATED_KEYS); +            insertEmployee = +                    connection.prepareStatement(INSERT_EMPLOYEE, Statement.RETURN_GENERATED_KEYS); + +            listEmployee = connection.prepareStatement(LIST_EMPLOYEE); + +            updateEmployee = connection.prepareStatement(UPDATE_EMPLOYEE); + +        } catch (SQLException e) { +            throw new PersistenceException(e); +        } +    } + +    @Override +    public long add(Employee employee) throws PersistenceException { + +        // Assumption: the given employee is already validated (from service) +        Savepoint savepoint = null; +        try { +            savepoint = connection.setSavepoint(); +            connection.setAutoCommit(false); +            insertEmployeeVersion.setString(1, employee.name()); +            insertEmployeeVersion.setTimestamp( +                    2, Timestamp.valueOf(employee.birthday().atStartOfDay())); +            insertEmployeeVersion.setString(3, employee.educationLevel().toString()); +            insertEmployeeVersion.setBoolean(4, employee.isDriver()); +            insertEmployeeVersion.setBoolean(5, employee.isPilot()); +            insertEmployeeVersion.executeUpdate(); +            try (ResultSet resultSetEmployeeVersion = insertEmployeeVersion.getGeneratedKeys()) { +                if (resultSetEmployeeVersion.next()) { +                    long versionId = resultSetEmployeeVersion.getLong(1); + +                    insertEmployee.setLong(1, versionId); +                    insertEmployee.executeUpdate(); + +                    try (ResultSet resultSetEmployee = insertEmployee.getGeneratedKeys()) { +                        if (resultSetEmployee.next()) { +                            connection.commit(); +                            return resultSetEmployee.getLong(1); +                        } +                    } +                } +            } + +            throw new PersistenceException("Employee was not updated"); + +        } catch (SQLException e) { +            try { +                if (savepoint != null) { +                    connection.rollback(savepoint); +                } +            } catch (SQLException e1) { +                throw new PersistenceException(e); +            } +            throw new PersistenceException(e); +        } finally { +            try { +                connection.setAutoCommit(true); +            } catch (SQLException e) { +                throw new PersistenceException(e); +            } +        } +    } + +    @Override +    public void update(Employee employee) throws ElementNotFoundException, PersistenceException { + +        Savepoint savepoint = null; +        try { +            savepoint = connection.setSavepoint(); +            connection.setAutoCommit(false); + +            insertEmployeeVersion.setString(1, employee.name()); +            insertEmployeeVersion.setTimestamp( +                    2, Timestamp.valueOf(employee.birthday().atStartOfDay())); +            insertEmployeeVersion.setString(3, employee.educationLevel().toString()); +            insertEmployeeVersion.setBoolean(4, employee.isDriver()); +            insertEmployeeVersion.setBoolean(5, employee.isPilot()); +            insertEmployeeVersion.executeUpdate(); +            try (ResultSet resultSetEmployeeVersion = insertEmployeeVersion.getGeneratedKeys()) { + +                if (resultSetEmployeeVersion.next()) { +                    long versionId = resultSetEmployeeVersion.getLong(1); + +                    updateEmployee.setLong(1, versionId); +                    updateEmployee.setLong(2, employee.id()); +                    int affectedRows = updateEmployee.executeUpdate(); + +                    if (affectedRows == 1) { +                        connection.commit(); +                    } else { +                        throw new ElementNotFoundException( +                                "element not found with id: " + employee.id()); +                    } +                } +            } + +        } catch (SQLException e) { +            try { +                if (savepoint != null) { +                    connection.rollback(savepoint); +                } +            } catch (SQLException e1) { +                throw new PersistenceException(e); +            } +            throw new PersistenceException(e); +        } finally { +            try { +                connection.setAutoCommit(true); +            } catch (SQLException e) { +                throw new PersistenceException(e); +            } +        } +    } + +    @Override +    public Set<Employee> list() throws PersistenceException { + +        try { +            Set<Employee> employees; +            try (ResultSet rs = listEmployee.executeQuery()) { + +                employees = new HashSet<>(); +                while (rs.next()) { + +                    Employee employee = +                            Employee.builder() +                                    .id(rs.getLong(1)) +                                    .name(rs.getString(2)) +                                    .birthday(rs.getTimestamp(3).toLocalDateTime().toLocalDate()) +                                    .educationLevel(EducationLevel.valueOf(rs.getString(4))) +                                    .isDriver(rs.getBoolean(5)) +                                    .isPilot(rs.getBoolean(6)) +                                    .build(); + +                    employees.add(employee); +                } +            } + +            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/einsatzverwaltung/dao/EmployeeDatabaseDao.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDatabaseDao.java deleted file mode 100644 index 3e4ba12..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDatabaseDao.java +++ /dev/null @@ -1,124 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; -import java.lang.invoke.MethodHandles; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Repository; - -@Repository -public class EmployeeDatabaseDao implements EmployeeDAO { - -    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); -    private static final String INSERT_EMPLOYEE_VERSION = -            "INSERT INTO EmployeeVersion(name, birthday, educationLevel, isDriver, isPilot) " -                    + "VALUES(?, ?, ?, ?, ?)"; -    private static final String INSERT_EMPLOYEE = "INSERT INTO Employee(version) VALUES(?)"; -    private static final String LIST_EMPLOYEE = -            "SELECT emp.id, v.name, v.birthday, v.educationLevel, v.isDriver, v.isPilot " -                    + "FROM employee emp " -                    + "JOIN EmployeeVersion v ON v.id = emp.version"; - -    private final PreparedStatement insertEmployeeVersion, insertEmployee, listEmployee; - -    public EmployeeDatabaseDao(JDBCConnectionManager connectionManager) -            throws PersistenceException { - -        try { - -            final var connection = connectionManager.getConnection(); -            insertEmployeeVersion = -                    connection.prepareStatement( -                            INSERT_EMPLOYEE_VERSION, Statement.RETURN_GENERATED_KEYS); -            insertEmployee = -                    connection.prepareStatement(INSERT_EMPLOYEE, Statement.RETURN_GENERATED_KEYS); - -            listEmployee = connection.prepareStatement(LIST_EMPLOYEE); - -        } catch (SQLException e) { -            throw new PersistenceException(e); -        } -    } - -    @Override -    public long add(Employee employee) throws PersistenceException { - -        // Assumption: the given employee is already validated (from service) -        try { -            insertEmployeeVersion.setString(1, employee.name()); -            insertEmployeeVersion.setTimestamp( -                    2, Timestamp.valueOf(employee.birthday().atStartOfDay())); -            insertEmployeeVersion.setString(3, employee.educationLevel().toString()); -            insertEmployeeVersion.setBoolean(4, employee.isDriver()); -            insertEmployeeVersion.setBoolean(5, employee.isPilot()); -            insertEmployeeVersion.executeUpdate(); -            ResultSet resultSetEmployeeVersion = insertEmployeeVersion.getGeneratedKeys(); -            if (resultSetEmployeeVersion.next()) { -                long versionId = resultSetEmployeeVersion.getLong(1); - -                insertEmployee.setLong(1, versionId); -                insertEmployee.executeUpdate(); - -                ResultSet resultSetEmployee = insertEmployee.getGeneratedKeys(); -                if (resultSetEmployee.next()) { -                    return resultSetEmployee.getLong(1); -                } -            } - -            throw new PersistenceException("Employee was not created"); - -        } catch (SQLException e) { -            throw new PersistenceException(e); -        } -    } - -    @Override -    public void update(Employee employee) throws ElementNotFoundException, PersistenceException { -        throw new UnsupportedOperationException(); -    } - -    @Override -    public List<Employee> list() throws PersistenceException { - -        try { -            ResultSet rs = listEmployee.executeQuery(); - -            List<Employee> employees = new ArrayList<>(); -            while (rs.next()) { - -                Employee employee = -                        Employee.builder() -                                .id(rs.getLong(1)) -                                .name(rs.getString(2)) -                                .birthday(rs.getTimestamp(3).toLocalDateTime().toLocalDate()) -                                .educationLevel(EducationLevel.valueOf(rs.getString(4))) -                                .isDriver(rs.getBoolean(5)) -                                .isPilot(rs.getBoolean(6)) -                                .build(); - -                employees.add(employee); -            } - -            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/einsatzverwaltung/dao/OperationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAO.java index dd1a189..d82f768 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAO.java @@ -5,7 +5,7 @@ import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.S  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.List; +import java.util.Set;  public interface OperationDAO { @@ -44,7 +44,5 @@ public interface OperationDAO {       * @return list containing all matched operations       * @throws PersistenceException if loading the stored operations failed       */ -    List<Operation> list(EnumSet<Status> statuses) throws PersistenceException; - -    int connectVehicleToOperation(long vehicleID, long operationID) throws PersistenceException; +    Set<Operation> list(EnumSet<Status> statuses) throws PersistenceException;  } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDatabaseDAO.java new file mode 100644 index 0000000..0a465f2 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDatabaseDAO.java @@ -0,0 +1,218 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.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.Timestamp; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Objects; +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.setTimestamp(3, Timestamp.from(Objects.requireNonNull(o.created()))); +                pstmt.setString(4, o.destination()); +                pstmt.setString(5, o.additionalInfo()); +                pstmt.setInt(6, o.status().ordinal()); +                pstmt.executeUpdate(); + +                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<Long>) o.vehicles().stream().map(Vehicle::id)::iterator) { +                    pstmt.setLong(1, id); +                    pstmt.addBatch(); +                } + +                pstmt.executeBatch(); +            } +            con.commit(); +            con.setAutoCommit(true); +            return operationId; +        } catch (SQLException e) { +            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<Long>) o.vehicles().stream().map(Vehicle::id)::iterator) { +                    pstmt.setLong(1, id); +                    pstmt.addBatch(); +                } + +                pstmt.executeBatch(); +            } +            con.commit(); +            con.setAutoCommit(true); +        } catch (SQLException e) { +            throw new PersistenceException(e); +        } +    } + +    @Override +    public Operation get(long operationId) throws ElementNotFoundException, PersistenceException { +        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<Operation> list(EnumSet<Status> 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. +        String str = +                statuses.stream() +                        .map(Enum::name) +                        .map(s -> "'" + s + "'") +                        .collect(Collectors.joining(",")); +        String sql = "SELECT * FROM Operation WHERE status IN (" + str + ")"; +        Set<Operation> 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.getTimestamp("created").toInstant()) +                .destination(rs.getString("destination")) +                .additionalInfo(rs.getString("additionalInfo")) +                .build(); +    } + +    private Set<Vehicle> getVehiclesFromOperationId(long operationId) throws PersistenceException { +        String sql = "SELECT vehicleId FROM VehicleOperation WHERE operationId = ?"; +        Set<Vehicle> 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/einsatzverwaltung/dao/RegistrationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDAO.java index ba8f909..36b6f1b 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDAO.java @@ -3,7 +3,7 @@ package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import java.util.List; +import java.util.Set;  public interface RegistrationDAO { @@ -15,7 +15,7 @@ public interface RegistrationDAO {       * @return a list of the ids that were assigned       * @throws PersistenceException if the registration could not be persisted       */ -    List<Long> add(long vehicleId, List<Registration> registrations) throws PersistenceException; +    Set<Long> add(long vehicleId, Set<Registration> registrations) throws PersistenceException;      /**       * Make registration with the given id inactive. diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDatabaseDAO.java index 8fbcd18..13f2c0f 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDatabaseDAO.java @@ -1,5 +1,6 @@  package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; @@ -10,8 +11,10 @@ import java.sql.ResultSet;  import java.sql.SQLException;  import java.sql.Statement;  import java.sql.Timestamp; -import java.util.LinkedList; +import java.util.ArrayList; +import java.util.HashSet;  import java.util.List; +import java.util.Set;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory;  import org.springframework.beans.factory.annotation.Autowired; @@ -26,20 +29,27 @@ public class RegistrationDatabaseDAO implements RegistrationDAO {              "INSERT INTO Registration (vehicleId, employeeId, start, end, active) VALUES (?,?,?,?,?);";      private static final String UPDATE_VEHICLE =              "UPDATE Vehicle SET status = 'FREI_WACHE' WHERE id = ?;"; +    private static final String FETCH_REGISTRATIONS = +            "SELECT * FROM Registration WHERE vehicleId = ?";      private PreparedStatement addRegistration;      private PreparedStatement updateVehicle; +    private PreparedStatement fetchRegistrations;      private Connection connection; +    private EmployeeDAO employeePersistence;      @Autowired -    public RegistrationDatabaseDAO(JDBCConnectionManager connectionManager) +    public RegistrationDatabaseDAO( +            JDBCConnectionManager connectionManager, EmployeeDAO employeePersistence)              throws PersistenceException { +        this.employeePersistence = employeePersistence;          try {              connection = connectionManager.getConnection();              addRegistration =                      connection.prepareStatement(ADD_REGISTRATION, Statement.RETURN_GENERATED_KEYS);              updateVehicle = connection.prepareStatement(UPDATE_VEHICLE); +            fetchRegistrations = connection.prepareStatement(FETCH_REGISTRATIONS);          } catch (SQLException e) {              LOG.error("Could not get connection or preparation of statement failed");              throw new PersistenceException(e); @@ -47,16 +57,16 @@ public class RegistrationDatabaseDAO implements RegistrationDAO {      }      @Override -    public List<Long> add(long vehicleId, List<Registration> registrations) +    public Set<Long> add(long vehicleId, Set<Registration> registrations)              throws PersistenceException { -        List<Long> returnValues = new LinkedList<>(); +        Set<Long> returnValues = new HashSet<>();          try {              connection.setAutoCommit(false);              for (Registration registration : registrations) {                  addRegistration.setLong(1, vehicleId);                  addRegistration.setLong(2, registration.employee().id());                  addRegistration.setTimestamp(3, Timestamp.from(registration.start())); -                addRegistration.setObject(4, registration.end()); +                addRegistration.setTimestamp(4, Timestamp.from(registration.end()));                  addRegistration.setBoolean(                          5, true); // ASSUMPTION: Registration gets created as active                  addRegistration.executeUpdate(); @@ -103,4 +113,35 @@ public class RegistrationDatabaseDAO implements RegistrationDAO {      public void remove(long id) throws ElementNotFoundException, PersistenceException {          throw new UnsupportedOperationException();      } + +    public List<Registration> list(long vehicleId) throws PersistenceException { +        List<Registration> registrationList = new ArrayList<>(); +        try { +            fetchRegistrations.setLong(1, vehicleId); +            ResultSet rs = fetchRegistrations.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.getTimestamp("start").toInstant()) +                                .end(rs.getTimestamp("end").toInstant()) +                                .employee(emp) +                                .build(); +                registrationList.add(registration); +            } +        } catch (SQLException e) { +            throw new PersistenceException(e); +        } + +        return registrationList; +    }  } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDAO.java index fe12952..5782fd9 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDAO.java @@ -3,7 +3,7 @@ package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import java.util.List; +import java.util.Set;  public interface VehicleDAO { @@ -31,7 +31,17 @@ public interface VehicleDAO {       * @return list containing all stored vehicles       * @throws PersistenceException if loading the stored vehicles failed       */ -    List<Vehicle> list() throws PersistenceException; +    Set<Vehicle> 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. diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDatabaseDAO.java new file mode 100644 index 0000000..6d50588 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDatabaseDAO.java @@ -0,0 +1,220 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.Status; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; +import java.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; +    } + +    public long add(Vehicle vehicle) throws PersistenceException { +        String query1 = +                "INSERT INTO VehicleVersion (name,hasNef,constructionType,type) VALUES (?,?,?,?)"; +        String query2 = "INSERT INTO Vehicle (version,status) VALUES (?,?)"; + +        String status = "ABGEMELDET"; +        String name = ""; +        int id = -1; +        int version = -1; +        try { +            Connection connection = jdbcConnectionManager.getConnection(); +            connection.setAutoCommit(false); +            try (PreparedStatement p1 = +                    connection.prepareStatement(query1, PreparedStatement.RETURN_GENERATED_KEYS)) { + +                p1.setString(1, name); +                p1.setBoolean(2, vehicle.hasNef()); +                p1.setString(3, vehicle.constructionType().name()); + +                p1.setString(4, vehicle.type().name()); + +                p1.executeUpdate(); +                try (ResultSet keyResultSet = p1.getGeneratedKeys()) { + +                    if (keyResultSet.next()) { +                        version = keyResultSet.getInt(1); +                    } +                } +            } +            try (PreparedStatement p2 = +                    connection.prepareStatement(query2, Statement.RETURN_GENERATED_KEYS)) { + +                p2.setInt(1, version); +                p2.setString(2, status); +                p2.executeUpdate(); +                try (ResultSet keyResultSet = p2.getGeneratedKeys()) { + +                    if (keyResultSet.next()) { +                        id = keyResultSet.getInt(1); +                    } +                } + +                name = vehicle.type().name() + "-" + id; +            } +            query1 = "UPDATE VehicleVersion SET name=? WHERE id=?"; +            try (PreparedStatement p3 = connection.prepareStatement(query1)) { +                p3.setString(1, name); +                p3.setInt(2, version); +                p3.executeUpdate(); +            } + +            connection.commit(); +            connection.setAutoCommit(true); +        } catch (SQLException e) { +            throw new PersistenceException(e); +        } +        return id; +    } + +    @Override +    public void update(Vehicle vehicle) throws ElementNotFoundException, PersistenceException { +        String query = "SELECT * FROM vehicle WHERE id=?"; + +        long vehicleID = -1; +        long vehicleVersion = -1; +        try { +            Connection connection = jdbcConnectionManager.getConnection(); +            connection.setAutoCommit(false); +            try (PreparedStatement p = +                    connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) { + +                p.setLong(1, vehicle.id()); +                p.executeQuery(); +                try (ResultSet rs = p.getResultSet()) { +                    while (rs.next()) { +                        vehicleID = rs.getLong("id"); +                    } +                } +            } +            if (vehicleID == -1) { +                throw new ElementNotFoundException("Vehicle don´t found"); +            } + +            query = +                    "INSERT INTO VehicleVersion (name,hasNef,constructionType,type) VALUES (?,?,?,?)"; +            String name = ""; +            try (PreparedStatement p = +                    connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) { +                p.setString(1, name); +                p.setBoolean(2, vehicle.hasNef()); +                p.setString(3, vehicle.constructionType().name()); + +                p.setString(4, vehicle.type().name()); + +                p.executeUpdate(); + +                try (ResultSet keyResultSet = p.getGeneratedKeys()) { + +                    if (keyResultSet.next()) { +                        vehicleVersion = keyResultSet.getInt(1); +                    } +                } +                if (vehicleVersion == -1) { +                    throw new ElementNotFoundException("Vehicle don´t found"); +                } +            } +            name = vehicle.type().name() + "-" + vehicleID; + +            query = "UPDATE VehicleVersion SET name=? WHERE id=?"; +            try (PreparedStatement p = connection.prepareStatement(query)) { + +                p.setString(1, name); +                p.setLong(2, vehicleVersion); +                p.executeUpdate(); +            } +            query = "UPDATE Vehicle SET version=? WHERE id=?"; +            try (PreparedStatement p = connection.prepareStatement(query)) { + +                p.setLong(1, vehicleVersion); +                p.setLong(2, vehicleID); +                p.executeUpdate(); +            } +            connection.commit(); +            connection.setAutoCommit(true); +        } catch (SQLException e) { +            throw new PersistenceException(e); +        } +    } + +    @Override +    public Set<Vehicle> list() throws PersistenceException { +        Set<Vehicle> 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("Die Werte konnten nicht geladen werden.", 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 {} + +    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/einsatzverwaltung/dao/VehicleDatabaseDao.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDatabaseDao.java deleted file mode 100644 index ca1d45c..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDatabaseDao.java +++ /dev/null @@ -1,147 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.LinkedList; -import java.util.List; -import org.springframework.stereotype.Repository; - -@Repository -public class VehicleDatabaseDao implements VehicleDAO { - -    private final JDBCConnectionManager jdbcConnectionManager; - -    public VehicleDatabaseDao(JDBCConnectionManager j) { -        jdbcConnectionManager = j; -    } - -    public long add(Vehicle vehicle) throws PersistenceException { -        String query1 = -                "INSERT INTO VehicleVersion (name,hasNef,constructionType,type) VALUES (?,?,?,?)"; -        String query2 = "INSERT INTO Vehicle (version,status) VALUES (?,?)"; -        PreparedStatement p1 = null; -        PreparedStatement p2 = null; -        PreparedStatement p3 = null; -        String status = "ABGEMELDET"; -        String name = ""; -        int id = -1; -        try { -            p1 = -                    jdbcConnectionManager -                            .getConnection() -                            .prepareStatement(query1, PreparedStatement.RETURN_GENERATED_KEYS); -            p1.setString(1, name); -            p1.setBoolean(2, vehicle.hasNef()); -            p1.setString(3, vehicle.constructionType().name()); -            if (vehicle.type() == VehicleType.KTW_B) { -                p1.setString(4, "KTW-B"); -            } else { -                p1.setString(4, vehicle.type().name()); -            } -            p1.executeUpdate(); - -            ResultSet keyResultSet = p1.getGeneratedKeys(); - -            if (keyResultSet.next()) { -                id = keyResultSet.getInt(1); -            } - -            name = vehicle.type().name() + "-" + id; - -        } catch (SQLException e) { -            throw new PersistenceException("SQL Excpetion : " + e.toString()); -        } finally { -            try { -                p1.close(); - -            } catch (SQLException e) { -                throw new PersistenceException("SQL Excpetion : " + e.toString()); -            } -        } -        try { -            query1 = "UPDATE VehicleVersion SET name=? WHERE id=?"; -            p3 = jdbcConnectionManager.getConnection().prepareStatement(query1); -            p3.setString(1, name); -            p3.setInt(2, id); -            p3.executeUpdate(); -        } catch (SQLException e) { -            throw new PersistenceException("SQL Excpetion : " + e.toString()); -        } finally { -            try { -                p3.close(); -            } catch (SQLException e) { -                throw new PersistenceException("SQL Excpetion : " + e.toString()); -            } -        } -        try { -            p2 = jdbcConnectionManager.getConnection().prepareStatement(query2); -            p2.setInt(1, id); -            p2.setString(2, status); -            p2.executeUpdate(); -        } catch (SQLException e) { -            throw new PersistenceException("SQL Excpetion : " + e.toString()); -        } finally { -            try { -                p2.close(); -            } catch (SQLException e) { -                throw new PersistenceException("SQL Excpetion : " + e.toString()); -            } -        } -        return id; -    } - -    @Override -    public void update(Vehicle vehicle) throws ElementNotFoundException, PersistenceException {} - -    @Override -    public List<Vehicle> list() throws PersistenceException { -        PreparedStatement pstmt = null; -        List<Vehicle> result = new LinkedList<>(); -        try { -            pstmt = -                    jdbcConnectionManager -                            .getConnection() -                            .prepareStatement( -                                    "Select * from VehicleVersion, " -                                            + "Vehicle where VehicleVersion.id=Vehicle.version"); -            pstmt.executeQuery(); -            ResultSet rs = pstmt.getResultSet(); -            while (rs.next()) { -                Vehicle vehicle = -                        Vehicle.builder() -                                .name(rs.getString("name")) -                                .constructionType( -                                        ConstructionType.valueOf(rs.getString("constructionType"))) -                                .status(Status.valueOf(rs.getString("status"))) -                                .id(rs.getInt("id")) -                                .hasNef(rs.getBoolean("hasNef")) -                                .type(VehicleType.valueOf(rs.getString("type").replace("-", "_"))) -                                .build(); -                result.add(vehicle); -            } -        } catch (SQLException e) { -            throw new PersistenceException("Die Werte konnten nicht geladen werden.", e); -        } finally { -            if (pstmt != null) { -                try { -                    pstmt.close(); -                } catch (SQLException e) { -                    throw new PersistenceException( -                            "Verbindung zur Datenbank konnte nicht geschlossen werden!", e); -                } -            } -        } -        return result; -    } - -    @Override -    public void remove(long id) throws ElementNotFoundException, PersistenceException {} -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Operation.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Operation.java index 6641437..3a97dc7 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Operation.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Operation.java @@ -2,7 +2,7 @@ package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto;  import com.google.auto.value.AutoValue;  import java.time.Instant; -import java.util.List; +import java.util.Set;  import javax.annotation.Nullable;  @AutoValue @@ -26,17 +26,19 @@ public abstract class Operation {      public abstract String opCode(); +    @Nullable      public abstract Severity severity();      public abstract Status status(); -    public abstract List<Vehicle> vehicles(); +    public abstract Set<Vehicle> vehicles();      @Nullable      public abstract Instant created();      public abstract String destination(); +    @Nullable      public abstract String additionalInfo();      public static Builder builder() { @@ -53,7 +55,7 @@ public abstract class Operation {          public abstract Builder status(Status status); -        public abstract Builder vehicles(List<Vehicle> vehicles); +        public abstract Builder vehicles(Set<Vehicle> vehicles);          public abstract Builder created(Instant created); diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/RegistrationValidator.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/RegistrationValidator.java index 295b615..610426c 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/RegistrationValidator.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/RegistrationValidator.java @@ -7,6 +7,7 @@ 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;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory; @@ -16,7 +17,7 @@ public class RegistrationValidator {      private RegistrationValidator() {} -    public static void validate(Vehicle vehicle, List<Registration> registrations) +    public static void validate(Vehicle vehicle, Set<Registration> registrations)              throws InvalidVehicleException, InvalidRegistrationException {          /*          Vehicles and Employees are assumed to be valid. diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Vehicle.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Vehicle.java index 84d9c92..e81db0b 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Vehicle.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Vehicle.java @@ -24,11 +24,11 @@ public abstract class Vehicle {      public enum Status {          ABGEMELDET,          FREI_WACHE, +        FREI_FUNK,          ZUM_BERUFUNGSORT,          AM_BERUFUNGSORT,          ZUM_ZIELORT,          AM_ZIELORT, -        FREI_FUNK,      }      public abstract long id(); diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeService.java index 8753504..f7f8e71 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeService.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeService.java @@ -3,7 +3,7 @@ package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee;  import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.util.List; +import java.util.Set;  public interface EmployeeService { @@ -33,7 +33,7 @@ public interface EmployeeService {       * @return list containing all stored employees       * @throws ServiceException if loading the stored employees failed       */ -    List<Employee> list() throws ServiceException; +    Set<Employee> list() throws ServiceException;      /**       * Remove employee with the given id from the store. diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeServiceImpl.java index ed0fb1c..31b5acd 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeServiceImpl.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeServiceImpl.java @@ -3,10 +3,11 @@ package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.EmployeeDAO;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.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.List; +import java.util.Set;  import org.springframework.stereotype.Service;  @Service @@ -31,11 +32,18 @@ public class EmployeeServiceImpl implements EmployeeService {      @Override      public Employee update(Employee employee) throws InvalidEmployeeException, ServiceException { -        return null; + +        EmployeeValidator.validate(employee); +        try { +            employeePersistence.update(employee); +            return employee; +        } catch (ElementNotFoundException | PersistenceException e) { +            throw new ServiceException(e); +        }      }      @Override -    public List<Employee> list() throws ServiceException { +    public Set<Employee> list() throws ServiceException {          try {              return employeePersistence.list(); diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationService.java index e21c10b..4b7e630 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationService.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationService.java @@ -7,8 +7,8 @@ import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationExcepti  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.List; -import javafx.collections.transformation.SortedList; +import java.util.Set; +import java.util.SortedSet;  public interface OperationService { @@ -32,7 +32,7 @@ public interface OperationService {       * @throws ServiceException if the vehicles could not be loaded or the operation could not be       *     persisted       */ -    void requestVehicles(long operationId, List<Long> vehicleIds) +    void requestVehicles(long operationId, Set<Long> vehicleIds)              throws InvalidOperationException, InvalidVehicleException, ServiceException;      /** @@ -48,15 +48,15 @@ public interface OperationService {              throws InvalidOperationException, ServiceException;      /** -     * Get all available vehicles, sorted by how well they fit to the given operation, starting with +     * Get all available vehicles, sorted by how well they fit to the given opCode, starting with       * the best fitting.       * -     * @param operationId id of the operation that is used to determine the ranking +     * @param opCode the operation code that is used to determine the ranking       * @return a sorted list containing all available vehicles -     * @throws InvalidOperationException if the operationId is invalid or does not exist +     * @throws InvalidOperationException if the opCode is invalid       * @throws ServiceException if loading the stored vehicles failed       */ -    SortedList<Vehicle> rankVehicles(long operationId) +    SortedSet<Vehicle> rankVehicles(String opCode)              throws InvalidOperationException, ServiceException;      /** @@ -66,5 +66,5 @@ public interface OperationService {       * @return list containing all matched operations       * @throws ServiceException if loading the stored operations failed       */ -    List<Operation> list(EnumSet<Status> statuses) throws ServiceException; +    Set<Operation> list(EnumSet<Status> statuses) throws ServiceException;  } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java index 05a548c..d07f46f 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java @@ -1,131 +1,264 @@  package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.OperationDAO; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.VehicleDAO;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.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.lang.invoke.MethodHandles; +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 javafx.collections.transformation.SortedList; +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 { -    // TODO: anders? -    private OperationDAO operationDAO; +    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); -    public OperationServiceImpl(OperationDAO dao) { -        this.operationDAO = dao; +    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 operation) throws InvalidOperationException, ServiceException { -        List<Vehicle> vehicles = operation.vehicles(); -        boolean rtw = false; -        if (faultyInput(operation.opCode())) { -            throw new InvalidOperationException("Code ist ungültig!"); -        } -        if (faultyInput(operation.destination())) { -            throw new InvalidOperationException("Adresse ist ungültig!"); -        } -        if (operation.vehicles().size() == 0) { -            throw new InvalidOperationException( -                    "Es muss mindestens ein Fahrzeug ausgewählt werden!"); +    public long add(Operation o) throws InvalidOperationException, ServiceException { +        if (o.created() != null) throw new InvalidOperationException("Created must not be set"); + +        if (o.severity() != null) throw new InvalidOperationException("Severity must not be set"); + +        if (o.id() != 0) throw new InvalidOperationException("Id must be 0"); + +        if (o.status() != Status.ACTIVE) +            LOG.warn("Status was set but will be overridden"); // TODO: nullable instead?? + +        try { +            for (long id : (Iterable<Long>) o.vehicles().stream().map(Vehicle::id)::iterator) { +                Vehicle v = vehicleDAO.get(id); +                VehicleServiceImpl.validateVehicle(v); +            } + +            validateOperation(o); + +            return operationDAO.add( +                    o.toBuilder() +                            .created(Instant.now()) +                            .severity(extractSeverityFromOpCode(o.opCode())) +                            .status(Status.ACTIVE) +                            .build()); +        } catch (PersistenceException e) { +            LOG.error("PersistenceException while adding operation: {}", e); +            throw new ServiceException(e); +        } catch (InvalidVehicleException e) { +            throw new InvalidOperationException("Enthaltenes Fahrzeug ist invalid", e); +        } catch (ElementNotFoundException e) { +            throw new InvalidOperationException("Enthaltenes Fahrzeug existiert nicht", e);          } -        for (Vehicle vehicle : vehicles) { -            if (vehicle.status() == Vehicle.Status.ABGEMELDET -                    || (vehicle.status() != Vehicle.Status.FREI_FUNK -                            && vehicle.status() != Vehicle.Status.FREI_WACHE)) -                throw new InvalidOperationException( -                        "Abgemeldete Fahrzeuge dürfen nicht zu einem Einsatz geschickt werden!"); -            /*if (vehicle.type() == VehicleType.NEF && !rtw) { -                for (Vehicle vehicleA : vehicles) { -                    if (vehicleA.type() == VehicleType.RTW && vehicleA.hasNef()) { -                        rtw = true; -                        break; -                    } -                } -                if (!rtw) -                    throw new InvalidOperationException( -                            "Zu einem Fahrzeug des Typs NEF muss auch ein Fahrzeug des Typs RTW mit NEF-Halterung geschickt werden!"); -            }*/ -            /* if (vehicle.type() == VehicleType.NAH && !rtw) { -                for (Vehicle vehicleA : vehicles) { -                    if (vehicleA.type() == VehicleType.RTW) { -                        rtw = true; -                        break; -                    } +    } + +    @Override +    public void requestVehicles(long operationId, Set<Long> vehicleIds) +            throws InvalidOperationException, InvalidVehicleException, ServiceException { +        Set<Vehicle> vs = new HashSet<>(); + +        try { +            if (operationId <= 0) throw new InvalidOperationException("OperationId ist invalid"); +            Operation o = operationDAO.get(operationId); +            validateOperation(o); + +            if (o.opCode().trim().isEmpty() +                    || extractSeverityFromOpCode(o.opCode()) != o.severity()) +                throw new InvalidOperationException("Einsatzcode ist invalid"); + +            if (o.status() != Status.ACTIVE) +                throw new InvalidOperationException("Einsatz ist inaktiv"); + +            if (o.created() == null) +                throw new InvalidOperationException("Created darf nicht leer sein"); + +            for (Long id : vehicleIds) { +                if (id <= 0) throw new InvalidVehicleException("VehicleId ist invalid"); + +                try { +                    Vehicle v = vehicleDAO.get(id); +                    VehicleServiceImpl.validateVehicle(v); +                    if (v.status() == Vehicle.Status.ABGEMELDET) +                        throw new InvalidVehicleException( +                                "Kann keine inaktiven Fahrzeuge anfordern"); + +                    vs.add(v); +                } catch (ElementNotFoundException e) { +                    throw new InvalidVehicleException("VehicleId ist invalid");                  } -                if (!rtw) -                    throw new InvalidOperationException( -                            "Zu einem Fahrzeug des Typs NAH muss auch ein Fahrzeug des Typs RTW geschickt werden!"); -            }*/ -        } -        String[] codeParts = operation.opCode().split("-"); -        String severity = ""; -        for (int i = 0; i < codeParts[1].length(); i++) { -            if (((int) (codeParts[1].charAt(i)) >= 65 && (int) (codeParts[1].charAt(i)) <= 79) -                    || ((int) (codeParts[1].charAt(i)) >= 97 -                            && (int) (codeParts[1].charAt(i)) <= 111)) { -                severity = "" + codeParts[1].charAt(i); -                break;              } + +            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) { +            LOG.error("PersistenceException while requesting vehicles: {}", e); +            throw new ServiceException(e);          } +    } + +    @Override +    public void complete(long operationId, Status status) +            throws InvalidOperationException, ServiceException {          try { -            operation = operation.toBuilder().severity(Severity.valueOf(severity)).build(); -        } catch (IllegalArgumentException e) { -            throw new InvalidOperationException( -                    "Der Schweregrad des Einsatzes konnte nicht ausgelesen werden!"); +            Operation o = operationDAO.get(operationId); +            operationDAO.update(o.toBuilder().status(status).build()); +        } catch (ElementNotFoundException e) { +            throw new InvalidOperationException(e); +        } catch (PersistenceException e) { +            LOG.error("PersistenceException while completing operation: {}", e); +            throw new ServiceException(e); +        } +    } + +    @Override +    public SortedSet<Vehicle> rankVehicles(String opCode) +            throws InvalidOperationException, ServiceException { +        Set<Vehicle> vehicles = +                vehicleService.list(EnumSet.complementOf(EnumSet.of(Vehicle.Status.ABGEMELDET))); + +        List<Predicate<Vehicle>> priorities = new ArrayList<>(); +        Predicate<Vehicle> ktw = v -> v.type() == VehicleType.KTW; +        Predicate<Vehicle> rtwNoNEF = v -> v.type() == VehicleType.RTW && !v.hasNef(); +        Predicate<Vehicle> rtwNEF = v -> v.type() == VehicleType.RTW && v.hasNef(); +        Predicate<Vehicle> nef = v -> v.type() == VehicleType.NEF; +        Predicate<Vehicle> 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;          } -        operation = operation.toBuilder().status(Status.ACTIVE).build(); -        long operationId = -1; +        Comparator<Vehicle> vehicleComparator = +                (v1, v2) -> { +                    for (Predicate<Vehicle> priority : priorities) { +                        if (priority.test(v1)) { +                            return -1; +                        } +                        if (priority.test(v2)) { +                            return +1; +                        } +                    } +                    return 0; +                }; + +        Supplier<TreeSet<Vehicle>> supplier = () -> new TreeSet<>(vehicleComparator); + +        return vehicles.stream().collect(Collectors.toCollection(supplier)); +    } + +    @Override +    public Set<Operation> list(EnumSet<Status> statuses) throws ServiceException {          try { -            operationId = operationDAO.add(operation); +            Set<Operation> operations = operationDAO.list(statuses); +            for (Operation o : operations) validateOperation(o); + +            return operations;          } catch (PersistenceException e) { +            LOG.error("PersistenceException while listing operations", e);              throw new ServiceException(e); +        } catch (InvalidOperationException e) { +            // database returned invalid values +            LOG.error("DB returned invalid operation: {}", e); +            throw new ServiceException("DB returned invalid operation", e);          } +    } + +    private static void validateOperation(Operation o) throws InvalidOperationException { +        if (o.vehicles().isEmpty()) +            throw new InvalidOperationException( +                    "Es muss mindestens ein Fahrzeug ausgewählt werden!"); -        for (Vehicle vehicle : vehicles) { +        for (Vehicle v : o.vehicles()) {              try { -                operationDAO.connectVehicleToOperation(vehicle.id(), operationId); -            } catch (PersistenceException e) { -                throw new ServiceException(e); +                VehicleServiceImpl.validateVehicle(v); +            } catch (InvalidVehicleException e) { +                throw new InvalidOperationException("Fahrzeug " + v.name() + " ist invalid" + e);              } -        } -        return operationId; -    } +            if (v.status() != Vehicle.Status.FREI_FUNK && v.status() != Vehicle.Status.FREI_WACHE) +                throw new InvalidOperationException( +                        "Fahrzeug nicht verfügbar (" + v.status() + ")"); -    private boolean faultyInput(String name) { -        if (name == null) return true; -        else if (name.isEmpty()) return true; -        for (int i = 0; i < name.length(); i++) { -            if (name.charAt(i) != ' ') return false; +            // TODO: validate if NEF/RTW/NAH conditions?          } -        return true; + +        Instant created = o.created(); +        if (created != null && created.isAfter(Instant.now())) +            throw new InvalidOperationException("Fahrzeug wurde in der Zukunft erstellt"); + +        if (o.destination().trim().isEmpty()) +            throw new InvalidOperationException("Adresse darf nicht leer sein");      } -    @Override -    public void requestVehicles(long operationId, List<Long> vehicleIds) -            throws InvalidOperationException, InvalidVehicleException, ServiceException {} +    private static final Pattern opCodePattern = +            Pattern.compile("(?:\\w{1,3}-\\d{0,2})([ABCDEO])(?:.*)"); -    @Override -    public void complete(long operationId, Status status) -            throws InvalidOperationException, ServiceException {} +    private static Severity extractSeverityFromOpCode(String opCode) +            throws InvalidOperationException { +        Matcher m = opCodePattern.matcher(opCode); -    @Override -    public SortedList<Vehicle> rankVehicles(long operationId) -            throws InvalidOperationException, ServiceException { -        return null; -    } +        if (!m.matches()) throw new InvalidOperationException("Einsatzcode ist invalid"); -    @Override -    public List<Operation> list(EnumSet<Status> statuses) throws ServiceException { -        return null; +        return Severity.valueOf(m.group(1));      }  } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationService.java index c345a2b..b7d8eef 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationService.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationService.java @@ -4,7 +4,7 @@ import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registratio  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.List; +import java.util.Set;  public interface RegistrationService { @@ -18,7 +18,7 @@ public interface RegistrationService {       * @throws InvalidRegistrationException if the registration is invalid       * @throws ServiceException if the registration could not be persisted       */ -    List<Long> add(long vehicleId, List<Registration> registrations) +    Set<Long> add(long vehicleId, Set<Registration> registrations)              throws InvalidVehicleException, InvalidRegistrationException, ServiceException;      /** diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationServiceImpl.java index a267b6f..54d46e7 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationServiceImpl.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationServiceImpl.java @@ -1,16 +1,16 @@  package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.RegistrationDAO; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.VehicleDAO;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.RegistrationValidator;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.Status; +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.EnumSet; -import java.util.List; +import java.util.Set;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory;  import org.springframework.beans.factory.annotation.Autowired; @@ -22,36 +22,31 @@ public class RegistrationServiceImpl implements RegistrationService {      private static final Logger LOG = LoggerFactory.getLogger(RegistrationServiceImpl.class);      private final RegistrationDAO registrationDAO; -    private final VehicleService vehicleService; +    private final VehicleDAO vehicleDAO;      @Autowired -    public RegistrationServiceImpl(RegistrationDAO registrationDAO, VehicleService vehicleService) { +    public RegistrationServiceImpl(RegistrationDAO registrationDAO, VehicleDAO vehicleDAO) {          this.registrationDAO = registrationDAO; -        this.vehicleService = vehicleService; +        this.vehicleDAO = vehicleDAO;      }      @Override -    public List<Long> add(long vehicleId, List<Registration> registrations) +    public Set<Long> add(long vehicleId, Set<Registration> registrations)              throws InvalidVehicleException, InvalidRegistrationException, ServiceException { -        Vehicle vehicle = -                vehicleService -                        .list(EnumSet.of(Status.ABGEMELDET)) -                        .stream() -                        .filter(v -> v.id() == vehicleId) -                        .findFirst() -                        .orElse(null); +        if (vehicleId <= 0) throw new InvalidVehicleException("VehicleId invalid"); -        if (vehicle == null) { -            throw new ServiceException("no vehicle with this id"); -        } - -        RegistrationValidator.validate(vehicle, registrations);          try { +            Vehicle vehicle = vehicleDAO.get(vehicleId); + +            RegistrationValidator.validate(vehicle, registrations); +              return registrationDAO.add(vehicle.id(), registrations);          } catch (PersistenceException e) {              LOG.warn("PersistenceException caught, throwing matching ServiceException");              throw new ServiceException(e); +        } catch (ElementNotFoundException e) { +            throw new InvalidVehicleException(e);          }      } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleService.java index 6a96bc5..fe09ca1 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleService.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleService.java @@ -5,7 +5,7 @@ import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.Sta  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.List; +import java.util.Set;  public interface VehicleService { @@ -36,7 +36,7 @@ public interface VehicleService {       * @return list containing all stored vehicles       * @throws ServiceException if loading the stored vehicles failed       */ -    List<Vehicle> list(EnumSet<Status> statuses) throws ServiceException; +    Set<Vehicle> list(EnumSet<Status> statuses) throws ServiceException;      /**       * Remove vehicle with the given id from the store. diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java index bbe668b..61a24e5 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java @@ -4,13 +4,15 @@ import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.VehicleDAO;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.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.List; +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 { @@ -22,7 +24,31 @@ public class VehicleServiceImpl implements VehicleService {      }      public long add(Vehicle vehicle) throws InvalidVehicleException, ServiceException { +        if (!CollectionUtils.isEmpty(vehicle.registrations())) +            throw new InvalidVehicleException("Vehicle can't be created with registrations"); +        validateVehicle(vehicle); +        try { +            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"); +        } 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) { @@ -58,28 +84,17 @@ public class VehicleServiceImpl implements VehicleService {              case BKTW:                  break;              default: -                throw new ServiceException("not a Valid type"); -        } -        try { -            vehiclePersistence.add(vehicle); -        } catch (PersistenceException e) { -            throw new ServiceException(e); +                throw new IllegalStateException("BUG: invalid vehicle type" + vehicle.type());          } -        return 0; -    } - -    public Vehicle update(Vehicle vehicle) throws InvalidVehicleException, ServiceException { -        throw new UnsupportedOperationException();      }      @Override -    public List<Vehicle> list(EnumSet<Status> statuses) throws ServiceException { - +    public Set<Vehicle> list(EnumSet<Status> statuses) throws ServiceException {          if (statuses == null) {              throw new ServiceException("statuses may not be null");          } -        List<Vehicle> vehicles; +        Set<Vehicle> vehicles;          try {              vehicles = vehiclePersistence.list(); @@ -89,7 +104,7 @@ public class VehicleServiceImpl implements VehicleService {          return vehicles.stream()                  .filter(vehicle -> statuses.contains(vehicle.status())) -                .collect(Collectors.toList()); +                .collect(Collectors.toSet());      }      @Override diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/CreateOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/CreateOperationController.java deleted file mode 100644 index 5b645f3..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/CreateOperationController.java +++ /dev/null @@ -1,227 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.userInterface; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.DBOperationDAO; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.OperationService; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.OperationServiceImpl; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.VehicleService; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; -import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; -import java.io.IOException; -import java.lang.invoke.MethodHandles; -import java.time.Instant; -import java.util.EnumSet; -import java.util.LinkedList; -import java.util.List; -import javafx.collections.FXCollections; -import javafx.event.ActionEvent; -import javafx.fxml.FXML; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.ListCell; -import javafx.scene.control.ListView; -import javafx.scene.control.TextField; -import javafx.scene.layout.AnchorPane; -import javafx.stage.Stage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; - -@Controller -public class CreateOperationController { - -    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - -    public AnchorPane apCreateOperation; -    public TextField txtCode; -    public TextField txtAddress; -    public TextField txtNote; -    public Button btnCreateOperation; -    public ListView<Vehicle> lvVehicles; -    public ListView lvActiveOperations; -    public Label lblChosenVehicles; -    public LinkedList<Vehicle> chosenVehicles = new LinkedList<>(); - -    // TODO: Anders? -    OperationService operationService = -            new OperationServiceImpl(new DBOperationDAO(new JDBCConnectionManager())); -    private final VehicleService vehicleService; -    private final SpringFXMLLoader fxmlLoader; - -    public CreateOperationController(VehicleService vehicleService, SpringFXMLLoader fxmlLoader) { -        this.vehicleService = vehicleService; -        this.fxmlLoader = fxmlLoader; -    } - -    @FXML -    public void initialize() { -        lblChosenVehicles.setText("keine ausgewählt"); -        lvVehicles.setCellFactory( -                param -> -                        new ListCell<Vehicle>() { -                            @Override -                            protected void updateItem(Vehicle item, boolean empty) { -                                super.updateItem(item, empty); - -                                if (empty || item == null || item.name() == null) { -                                    setText(null); -                                } else { -                                    setText(item.name()); -                                } -                            } -                        }); - -        lvVehicles.setOnMouseClicked( -                event -> { -                    if (event.getClickCount() == 2) { -                        boolean remove = false; -                        if (lvVehicles.getSelectionModel().getSelectedItem() == null) { -                            return; -                        } -                        for (Vehicle vehicle : chosenVehicles) { -                            if (lvVehicles.getSelectionModel().getSelectedItem().equals(vehicle)) { -                                remove = true; -                                break; -                            } -                        } -                        if (!remove) { -                            chosenVehicles.add(lvVehicles.getSelectionModel().getSelectedItem()); - -                        } else { -                            chosenVehicles.remove(lvVehicles.getSelectionModel().getSelectedItem()); -                        } -                        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()); -                        } -                    } -                }); -    } - -    public void updateList() { -        try { -            this.lvVehicles.setItems( -                    FXCollections.observableArrayList( -                            vehicleService.list( -                                    EnumSet.of( -                                            Vehicle.Status.FREI_FUNK, Vehicle.Status.FREI_WACHE)))); -        } catch (ServiceException e) { -            Alert alert = new Alert(Alert.AlertType.ERROR); -            alert.setTitle("Fehler"); -            alert.setHeaderText("Fehler!"); -            alert.setContentText(e.getMessage()); -            alert.showAndWait(); -        } -    } - -    /*private LinkedList<Vehicle> mylist() { -        Vehicle vehicle = -                Vehicle.builder() -                        .name("Test-KTW") -                        .constructionType(ConstructionType.HOCHDACH) -                        .type(VehicleType.KTW) -                        .status(Vehicle.Status.FREI_WACHE) -                        .hasNef(true) -                        .build(); - -        Vehicle vehicle1 = -                Vehicle.builder() -                        .name("Test-NEF") -                        .constructionType(ConstructionType.NORMAL) -                        .type(VehicleType.NEF) -                        .status(Vehicle.Status.FREI_FUNK) -                        .hasNef(true) -                        .build(); -        LinkedList<Vehicle> list = new LinkedList<>(); -        list.add(vehicle); -        list.add(vehicle1); -        // this.lvVehicles.setItems(FXCollections.observableArrayList(list)); -        return list; -    }*/ - -    @FXML -    protected void createOperationClicked() { -        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()) -                        .created(Instant.now()) -                        .opCode(txtCode.getText()) -                        .status(Status.ACTIVE) -                        .vehicles(List.of(vehicles)) -                        .severity(Severity.A) -                        .build(); -        try { -            operationService.add(operation); -        } catch (ServiceException | InvalidOperationException e) { -            Alert alert = new Alert(Alert.AlertType.ERROR); -            alert.setTitle("Fehler"); -            alert.setHeaderText("Fehler!"); -            alert.setContentText(e.getMessage()); -            alert.showAndWait(); -            return; -        } -        Alert alert = new Alert(AlertType.CONFIRMATION); -        alert.setTitle("Erfolg"); -        alert.setHeaderText("Erfolgreich gespeichert"); -        alert.setContentText("Der Einsatz wurde erfolgreich gespeichert."); -        alert.showAndWait(); -        updateList(); -    } - -    public void onRegistrationLinkClicked(ActionEvent actionEvent) { -        openNewWindow("RegistrationWindow.fxml"); -    } - -    public void onEmployeeLinkClicked(ActionEvent actionEvent) { -        openNewWindow("createNewEmployee.fxml"); -    } - -    public void onVehicleLinkClicked(ActionEvent actionEvent) { -        openNewWindow("createCar.fxml"); -    } - -    private void openNewWindow(String fxmlFileName) { - -        Stage stage = new Stage(); -        try { -            stage.setScene( -                    new Scene( -                            (Parent) -                                    fxmlLoader.load( -                                            getClass() -                                                    .getResourceAsStream( -                                                            "/fxml/" + fxmlFileName)))); -        } catch (IOException e) { -            LOG.error("Could not open new window: {}", e); -        } - -        stage.setTitle("Einsatz erstellen"); -        stage.centerOnScreen(); -        stage.showAndWait(); // important to call wait so that updateList is executed afterwards - -        updateList(); -    } -} diff --git a/src/main/resources/fxml/ArchiveOperation.fxml b/src/main/resources/fxml/ArchiveOperation.fxml new file mode 100644 index 0000000..88b5b39 --- /dev/null +++ b/src/main/resources/fxml/ArchiveOperation.fxml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.Hyperlink?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.ScrollPane?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.layout.FlowPane?> +<?import javafx.scene.text.Font?> + +<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="650.0" prefWidth="1200.0" style="-fx-background-color: BLACK;" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.ArchiveOperationController"> +  <children> +    <AnchorPane prefHeight="650.0" prefWidth="800.0" style="-fx-background-color: rgba(239,235,232,1);" AnchorPane.leftAnchor="200.0" /> +      <ScrollPane prefHeight="650.0" prefWidth="800.0" AnchorPane.leftAnchor="200.0"> +         <content> +          <FlowPane fx:id="archiveOperationFlowPane" prefHeight="650.0" prefWidth="800.0" /> +         </content> +      </ScrollPane> +      <AnchorPane fx:id="apDetails" layoutX="201.0" prefHeight="650.0" prefWidth="800.0" style="-fx-background-color: rgba(239,235,232,1);" visible="false" AnchorPane.leftAnchor="201.0" AnchorPane.topAnchor="0.0"> +         <children> +            <AnchorPane prefHeight="170.0" prefWidth="800.0" style="-fx-background-color: rgba(191,144,0,1);"> +               <children> +                  <Label layoutX="81.0" layoutY="20.0" prefHeight="34.0" prefWidth="116.0" text="Archiv-Eintrag:" textFill="WHITE"> +                     <font> +                        <Font name="System Bold" size="16.0" /> +                     </font> +                  </Label> +                  <Label fx:id="lblCodeHeader" layoutX="203.0" layoutY="20.0" prefHeight="34.0" prefWidth="116.0" textFill="WHITE"> +                     <font> +                        <Font name="System Bold" size="16.0" /> +                     </font> +                  </Label> +                  <Hyperlink fx:id="hypBack" layoutX="656.0" layoutY="20.0" onAction="#backClicked" text="Zurück" textFill="WHITE"> +                     <font> +                        <Font name="System Bold" size="16.0" /> +                     </font> +                  </Hyperlink> +               </children></AnchorPane> +            <AnchorPane layoutX="82.0" layoutY="60.0" prefHeight="150.0" prefWidth="636.0" style="-fx-background-color: white; -fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.8), 5, 0, 0, 5);"> +               <children> +                  <Label fx:id="lblOpCode" layoutX="25.0" layoutY="22.0" prefHeight="26.0" prefWidth="116.0" text="Label"> +                     <font> +                        <Font name="System Bold" size="18.0" /> +                     </font> +                  </Label> +                  <Label fx:id="lblAddress" layoutX="26.0" layoutY="53.0" prefHeight="22.0" prefWidth="540.0" text="Label"> +                     <font> +                        <Font size="15.0" /> +                     </font> +                  </Label> +                  <Label fx:id="lblVehicles" layoutX="58.0" layoutY="91.0" prefHeight="46.0" prefWidth="554.0" text="Label"> +                     <font> +                        <Font size="15.0" /> +                     </font> +                  </Label> +                  <Label fx:id="lblDate" alignment="CENTER_RIGHT" layoutX="482.0" layoutY="22.0" prefHeight="27.0" prefWidth="140.0" text="Label"> +                     <font> +                        <Font name="System Bold" size="18.0" /> +                     </font> +                  </Label> +               </children> +            </AnchorPane> +            <ScrollPane fitToWidth="true" prefHeight="410.0" prefWidth="640.0" AnchorPane.leftAnchor="82.0" AnchorPane.topAnchor="225.0"> +               <content> +                  <FlowPane fx:id="fpVehicles" prefHeight="410.0" prefWidth="640.0" /> +               </content> +            </ScrollPane> +         </children> +      </AnchorPane> +  </children> +</AnchorPane> diff --git a/src/main/resources/fxml/CreateOperationController.fxml b/src/main/resources/fxml/CreateOperationController.fxml index 086a5d1..0a09611 100644 --- a/src/main/resources/fxml/CreateOperationController.fxml +++ b/src/main/resources/fxml/CreateOperationController.fxml @@ -6,90 +6,83 @@  <?import javafx.scene.control.ListView?>  <?import javafx.scene.control.TextField?>  <?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.layout.FlowPane?>  <?import javafx.scene.text.Font?> - -<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="650.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.userInterface.CreateOperationController"> -   <children> -      <AnchorPane layoutX="964.0" layoutY="-66.0" prefHeight="182.0" prefWidth="1200.0" style="-fx-background-color: #2D75B6;" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0" /> -      <AnchorPane fx:id="apCreateOperation" layoutX="40.0" layoutY="71.0" prefHeight="151.0" prefWidth="920.0" style="-fx-background-color: white; -fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.8), 5, 0, 0, 5);"> -         <children> -            <Label layoutX="14.0" layoutY="14.0" prefHeight="30.0" prefWidth="62.0" text="Code"> -               <font> -                  <Font size="19.0" /> -               </font> -            </Label> -            <Label layoutX="185.0" layoutY="14.0" prefHeight="30.0" prefWidth="94.0" text="Adresse"> -               <font> -                  <Font size="19.0" /> -               </font> -            </Label> -            <Label layoutX="587.0" layoutY="14.0" prefHeight="30.0" prefWidth="121.0" text="Anmerkung"> -               <font> -                  <Font size="19.0" /> -               </font> -            </Label> -            <TextField fx:id="txtCode" layoutX="14.0" layoutY="48.0" prefHeight="39.0" prefWidth="163.0"> -               <font> -                  <Font name="System Bold" size="20.0" /> -               </font> -            </TextField> -            <TextField fx:id="txtAddress" layoutX="185.0" layoutY="48.0" prefHeight="39.0" prefWidth="396.0"> -               <font> -                  <Font name="System Bold" size="20.0" /> -               </font> -            </TextField> -            <TextField fx:id="txtNote" layoutX="587.0" layoutY="48.0" prefHeight="39.0" prefWidth="319.0"> -               <font> -                  <Font name="System Bold" size="20.0" /> -               </font> -            </TextField> -            <Label layoutX="14.0" layoutY="101.0" prefHeight="30.0" prefWidth="102.0" text="Fahrzeuge:"> -               <font> -                  <Font size="19.0" /> -               </font> -            </Label> -            <Label fx:id="lblChosenVehicles" layoutX="116.0" layoutY="102.0" prefHeight="30.0" prefWidth="610.0" text="keine ausgewählt"> -               <font> -                  <Font size="19.0" /> -               </font> -            </Label> -            <Button fx:id="btnCreateOperation" layoutX="747.0" layoutY="95.0" mnemonicParsing="false" onAction="#createOperationClicked" prefHeight="0.0" prefWidth="158.0" text="Erstellen"> -               <font> -                  <Font name="System Bold" size="21.0" /> -               </font> -            </Button> -         </children> -      </AnchorPane> -      <Hyperlink layoutX="44.0" layoutY="38.0" onAction="#onRegistrationLinkClicked" text="Anmeldungen" textFill="WHITE"> -         <font> -            <Font size="15.0" /> -         </font> -      </Hyperlink> -      <Hyperlink layoutX="802.0" layoutY="38.0" onAction="#onEmployeeLinkClicked" text="Personen" textFill="WHITE"> -         <font> -            <Font size="15.0" /> -         </font> -      </Hyperlink> -      <Hyperlink layoutX="877.0" layoutY="38.0" onAction="#onVehicleLinkClicked" text="Fahrzeuge" textFill="WHITE"> -         <font> -            <Font size="15.0" /> -         </font> -      </Hyperlink> -      <AnchorPane fx:id="apActiveOperations" layoutX="968.0" layoutY="71.0" prefHeight="315.0" prefWidth="207.0" style="-fx-background-color: white; -fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.8), 10, 0, 0, 5);"> -         <children> -            <ListView fx:id="lvActiveOperations" layoutX="4.0" layoutY="74.0" prefHeight="242.0" prefWidth="200.0" style="-fx-background-color: white;" /> -            <Label layoutX="10.0" layoutY="14.0" prefHeight="46.0" prefWidth="103.0" text="Aktive Einsätze"> -               <font> -                  <Font name="System Bold" size="14.0" /> -               </font> -            </Label> -            <Label layoutX="148.0" layoutY="28.0" text="Archiv"> -               <font> -                  <Font size="13.0" /> -               </font> -            </Label> -         </children> -      </AnchorPane> -      <ListView fx:id="lvVehicles" layoutX="40.0" layoutY="228.0" prefHeight="388.0" prefWidth="920.0" style="-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.8), 10, 0, 0, 5);" /> -   </children> +<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" +  prefHeight="650.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/9.0.1" +  xmlns:fx="http://javafx.com/fxml/1" +  fx:controller="at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.CreateOperationController" +  stylesheets="@/styles/main.css"> +  <AnchorPane prefHeight="182.0" style="-fx-background-color: #2D75B6;" AnchorPane.leftAnchor="0.0" +    AnchorPane.topAnchor="0.0" AnchorPane.rightAnchor="0.0"/> +  <AnchorPane fx:id="apCreateOperation" layoutX="40.0" layoutY="71.0" prefHeight="151.0" +    prefWidth="920.0" +    styleClass="bg-white, shadowed"> +    <Label layoutX="14.0" layoutY="14.0" prefHeight="30.0" prefWidth="62.0" text="Code" +      styleClass="text-medium"/> +    <Label layoutX="185.0" layoutY="14.0" prefHeight="30.0" prefWidth="94.0" text="Adresse" +      styleClass="text-medium"/> +    <Label layoutX="587.0" layoutY="14.0" prefHeight="30.0" prefWidth="121.0" text="Anmerkung" +      styleClass="text-medium"/> +    <TextField fx:id="txtCode" layoutX="14.0" layoutY="48.0" prefHeight="39.0" +      onKeyReleased="#onOperationCodeChanged" +      prefWidth="163.0" styleClass="text-big"> +      <font> +        <Font name="System Bold"/> +      </font> +    </TextField> +    <TextField fx:id="txtAddress" layoutX="185.0" layoutY="48.0" prefHeight="39.0" +      prefWidth="396.0" styleClass="text-big"> +      <font> +        <Font name="System Bold"/> +      </font> +    </TextField> +    <TextField fx:id="txtNote" layoutX="587.0" layoutY="48.0" prefHeight="39.0" +      prefWidth="319.0" styleClass="text-big"> +      <font> +        <Font name="System Bold"/> +      </font> +    </TextField> +    <Label layoutX="14.0" layoutY="101.0" prefHeight="30.0" prefWidth="102.0" +      text="Fahrzeuge:" styleClass="text-medium"/> +    <Label fx:id="lblChosenVehicles" layoutX="116.0" layoutY="102.0" prefHeight="30.0" +      prefWidth="610.0" text="keine ausgewählt" styleClass="text-big"/> +    <Button fx:id="btnCreateOperation" layoutX="747.0" styleClass="text-big, button-main" +      layoutY="95.0" mnemonicParsing="false" +      onAction="#createOperationClicked" prefHeight="0.0" prefWidth="158.0" text="Erstellen"> +      <font> +        <Font name="System Bold"/> +      </font> +    </Button> +  </AnchorPane> +  <Hyperlink layoutX="44.0" layoutY="38.0" onAction="#onRegistrationLinkClicked" text="Anmeldungen" +    textFill="WHITE" styleClass="text-small"> +  </Hyperlink> +  <Hyperlink layoutX="802.0" layoutY="38.0" onAction="#onEmployeeLinkClicked" text="Personen" +    styleClass="text-small" +    textFill="WHITE"> +  </Hyperlink> +  <Hyperlink layoutX="877.0" layoutY="38.0" onAction="#onVehicleLinkClicked" text="Fahrzeuge" +    styleClass="text-small" +    textFill="WHITE"> +  </Hyperlink> +  <!--<AnchorPane fx:id="apActiveOperations" layoutX="968.0" layoutY="71.0" prefHeight="315.0" prefWidth="207.0" style="-fx-background-color: white; -fx-effect: dropshadow(gaussian, rgba(0.5,0.5,0.5,0.8), 5, 0, 0, 3);">--> +  <AnchorPane fx:id="apActiveOperations" layoutX="968.0" layoutY="71.0" prefHeight="315.0" +    prefWidth="207.0" +    styleClass="bg-white, shadowed"> +    <ListView fx:id="lvActiveOperations" layoutX="4.0" layoutY="74.0" prefHeight="242.0" +      prefWidth="200.0" style="-fx-background-color: white;"/> +    <Label layoutX="10.0" layoutY="6.0" +      text="Aktive Einsätze" styleClass="text-big"> +    </Label> +    <Hyperlink onAction="#onArchivLinkClicked" layoutY="7.0" text="Archiv" styleClass="text-medium" +      AnchorPane.rightAnchor="12"/> +  </AnchorPane> +  <FlowPane fx:id="fpVehicles" hgap="12" layoutX="40.0" layoutY="228.0" prefHeight="388.0" +    prefWidth="920.0" vgap="12"> +  </FlowPane> +  <AnchorPane fx:id="apInvisible" prefHeight="650.0" prefWidth="1200.0" +    style="-fx-background-color: rgba(0,0,0,0.7);" visible="false"/> +  <fx:include fx:id="operationDetails" source="/fxml/OperationDetails.fxml" +    AnchorPane.leftAnchor="54.0" AnchorPane.topAnchor="50.0"/>  </AnchorPane> diff --git a/src/main/resources/fxml/OperationDetails.fxml b/src/main/resources/fxml/OperationDetails.fxml new file mode 100644 index 0000000..3ac7d93 --- /dev/null +++ b/src/main/resources/fxml/OperationDetails.fxml @@ -0,0 +1,102 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.Hyperlink?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.ListView?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.text.Font?> + +<AnchorPane fx:id="operationDetailsAP" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="542.0" prefWidth="1100.0" visible="false" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.OperationDetailsController"> +  <children> +    <AnchorPane prefHeight="542.0" prefWidth="1100.0" style="-fx-background-color: white;" /> +    <AnchorPane layoutX="10.0" layoutY="10.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="542.0" prefWidth="1000.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0"> +      <children> +        <AnchorPane layoutX="964.0" layoutY="-66.0" prefHeight="152.0" prefWidth="1100.0" style="-fx-background-color: green;" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="0.0"> +          <children> +            <Hyperlink layoutX="1023.0" layoutY="16.0" onAction="#closeWindow" text="Zurück" textFill="WHITE"> +              <font> +                <Font size="15.0" /> +              </font> +            </Hyperlink> +            <Label layoutX="17.0" layoutY="13.0" prefHeight="34.0" prefWidth="174.0" text="Ausgewählter Einsatz:" textFill="WHITE"> +              <font> +                <Font size="17.0" /> +              </font> +            </Label> +          </children> +        </AnchorPane> +        <AnchorPane fx:id="apActiveOperations" layoutX="874.0" layoutY="50.0" prefHeight="298.0" prefWidth="200.0" style="-fx-background-color: white; -fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.8), 10, 0, 0, 5);"> +          <children> +            <ListView fx:id="lvActiveOperations" layoutX="9.0" layoutY="55.0" prefHeight="242.0" prefWidth="182.0" style="-fx-background-color: white;" /> +            <Label layoutX="9.0" layoutY="11.0" prefHeight="46.0" prefWidth="103.0" text="Aktive Einsätze"> +              <font> +                <Font name="System Bold" size="14.0" /> +              </font> +            </Label> +            <Label layoutX="150.0" layoutY="24.0" text="Archiv"> +              <font> +                <Font size="13.0" /> +              </font> +            </Label> +          </children> +        </AnchorPane> +        <ListView fx:id="lvVehicles" layoutX="16.0" layoutY="185.0" prefHeight="355.0" prefWidth="846.0" style="-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.8), 10, 0, 0, 5);" /> +        <AnchorPane fx:id="apCreateOperation" layoutX="16.0" layoutY="49.0" prefHeight="134.0" prefWidth="845.0" style="-fx-background-color: white; -fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.8), 5, 0, 0, 5);"> +          <children> +            <Label layoutX="14.0" layoutY="14.0" prefHeight="30.0" prefWidth="62.0" text="Code"> +              <font> +                <Font size="15.0" /> +              </font> +            </Label> +            <Label layoutX="185.0" layoutY="14.0" prefHeight="30.0" prefWidth="94.0" text="Adresse"> +              <font> +                <Font size="15.0" /> +              </font> +            </Label> +            <Label layoutX="563.0" layoutY="14.0" prefHeight="30.0" prefWidth="121.0" text="Anmerkung"> +              <font> +                <Font size="15.0" /> +              </font> +            </Label> +            <Label layoutX="14.0" layoutY="96.0" prefHeight="30.0" prefWidth="102.0" text="Fahrzeuge:"> +              <font> +                <Font size="17.0" /> +              </font> +            </Label> +            <Label fx:id="lblChosenVehicles" layoutX="105.0" layoutY="96.0" prefHeight="30.0" prefWidth="418.0" text="keine ausgewählt"> +              <font> +                <Font size="17.0" /> +              </font> +            </Label> +            <Button fx:id="btnCloseOperation" layoutX="709.0" layoutY="89.0" mnemonicParsing="false" onAction="#closeOperationClicked" prefHeight="39.0" prefWidth="122.0" text="Abschließen"> +              <font> +                <Font name="System Bold" size="17.0" /> +              </font> +            </Button> +            <Button fx:id="btnCancelOperation" layoutX="575.0" layoutY="90.0" mnemonicParsing="false" onAction="#cancelOperationClicked" prefHeight="38.0" prefWidth="122.0" text="Stornieren"> +              <font> +                <Font name="System Bold" size="17.0" /> +              </font> +            </Button> +            <Label fx:id="lblCode" layoutX="14.0" layoutY="39.0" prefHeight="46.0" prefWidth="154.0"> +              <font> +                <Font name="System Bold" size="19.0" /> +              </font> +            </Label> +            <Label fx:id="lblAddress" layoutX="185.0" layoutY="39.0" prefHeight="44.0" prefWidth="374.0"> +              <font> +                <Font name="System Bold" size="19.0" /> +              </font> +            </Label> +            <Label fx:id="lblAdditionalInfo" layoutX="562.0" layoutY="39.0" prefHeight="44.0" prefWidth="272.0"> +              <font> +                <Font name="System Bold" size="19.0" /> +              </font> +            </Label> +          </children> +        </AnchorPane> +      </children> +    </AnchorPane> +  </children> +</AnchorPane> diff --git a/src/main/resources/fxml/createCar.fxml b/src/main/resources/fxml/createCar.fxml index b0898da..cefac82 100644 --- a/src/main/resources/fxml/createCar.fxml +++ b/src/main/resources/fxml/createCar.fxml @@ -4,14 +4,15 @@  <?import javafx.scene.control.CheckBox?>  <?import javafx.scene.control.ChoiceBox?>  <?import javafx.scene.layout.AnchorPane?> - +<?import javafx.scene.layout.FlowPane?>  <AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.CreateCarController">     <children>        <ChoiceBox fx:id="cmb_Ctyp" layoutX="14.0" layoutY="14.0" prefWidth="150.0" />        <ChoiceBox fx:id="cmb_typ" layoutX="191.0" layoutY="14.0" prefWidth="150.0" /> -      <Button fx:id="btn_cancel" layoutX="500.0" layoutY="14.0" mnemonicParsing="false" text="abbrechen" /> +      <Button fx:id="btn_cancel" layoutX="500.0" layoutY="14.0" mnemonicParsing="false" text="abbrechen" onAction="#cancelAction"/>        <Button fx:id="btn_create" layoutX="500.0" layoutY="53.0" mnemonicParsing="false" onAction="#createCar" text="Erstellen" />        <CheckBox fx:id="cbx_NEF" layoutX="14.0" layoutY="57.0" mnemonicParsing="false" text="NEF - Halterung" /> +      <FlowPane fx:id="fp_vehicleList" layoutX="14.0" layoutY="94.0" prefHeight="298.0" prefWidth="571.0" AnchorPane.bottomAnchor="5.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" />     </children>  </AnchorPane> diff --git a/src/main/resources/fxml/createNewEmployee.fxml b/src/main/resources/fxml/createNewEmployee.fxml index 5fa1ca9..4848c09 100644 --- a/src/main/resources/fxml/createNewEmployee.fxml +++ b/src/main/resources/fxml/createNewEmployee.fxml @@ -8,10 +8,9 @@  <?import javafx.scene.control.TextField?>  <?import javafx.scene.layout.AnchorPane?> - -<AnchorPane prefHeight="114.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.CreateNewEmployeeController"> +<AnchorPane prefHeight="96.0" prefWidth="740.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.CreateNewEmployeeController">     <children> -      <Label layoutX="14.0" layoutY="14.0" text="Neue Person erstellen" /> +      <Label fx:id="lblHeader" layoutX="14.0" layoutY="14.0" text="Neue Person erstellen" />        <Label layoutX="14.0" layoutY="38.0" text="Name" />        <Label layoutX="206.0" layoutY="38.0" text="Qualifikation" />        <CheckBox fx:id="inputIsDriver" layoutX="343.0" layoutY="37.0" mnemonicParsing="false" text="Fahrer" /> diff --git a/src/main/resources/fxml/employeeListItem.fxml b/src/main/resources/fxml/employeeListItem.fxml new file mode 100644 index 0000000..05354fc --- /dev/null +++ b/src/main/resources/fxml/employeeListItem.fxml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.image.ImageView?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.layout.HBox?> +<?import javafx.scene.text.Font?> + +<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" +  prefHeight="96.0" prefWidth="360.0" style="-fx-background-color: white;" +  xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" +  fx:controller="at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.EmployeeListItemController"> +  <children> +    <Label fx:id="lblName" layoutX="8.0" layoutY="22.0" text="Peter Mustermann" +      AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="5.0"> +      <font> +        <Font name="System Bold" size="18.0"/> +      </font> +    </Label> +    <Button layoutX="298.0" layoutY="5.0" mnemonicParsing="false" onAction="#onEditEmployeeClicked" +      text="bearbeiten" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0"/> +    <HBox layoutX="10.0" layoutY="40.0" prefHeight="42.0" prefWidth="339.0" +      AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="40.0"> +      <children> +        <AnchorPane prefHeight="42.0" prefWidth="112.0" style="-fx-background-color: white;"> +          <children> +            <ImageView fx:id="imgQualification" fitHeight="25.0" fitWidth="25.0" layoutX="10.0" +              layoutY="11.0" pickOnBounds="true" preserveRatio="true" AnchorPane.leftAnchor="10.0" +              AnchorPane.topAnchor="10.0"/> +            <Label fx:id="lblQualification" layoutX="45.0" layoutY="14.0" text="Notarzt" +              AnchorPane.leftAnchor="45.0" AnchorPane.topAnchor="14.0"/> +          </children> +        </AnchorPane> +        <AnchorPane prefHeight="42.0" prefWidth="112.0" style="-fx-background-color: white;"> +          <children> +            <ImageView fx:id="imgPilot" fitHeight="25.0" fitWidth="25.0" layoutX="10.0" +              layoutY="11.0" pickOnBounds="true" preserveRatio="true" AnchorPane.leftAnchor="10.0" +              AnchorPane.topAnchor="10.0"/> +            <Label fx:id="lblPilot" layoutX="53.0" layoutY="14.0" text="nicht Pilot" +              AnchorPane.leftAnchor="45.0" AnchorPane.topAnchor="14.0"/> +          </children> +        </AnchorPane> +        <AnchorPane prefHeight="42.0" prefWidth="112.0" style="-fx-background-color: white;"> +          <children> +            <ImageView fx:id="imgDriver" fitHeight="25.0" fitWidth="25.0" layoutX="10.0" +              layoutY="11.0" pickOnBounds="true" preserveRatio="true" AnchorPane.leftAnchor="10.0" +              AnchorPane.topAnchor="10.0"/> +            <Label fx:id="lblDriver" layoutX="54.0" layoutY="14.0" text="ist Fahrer" +              AnchorPane.leftAnchor="45.0" AnchorPane.topAnchor="14.0"/> +          </children> +        </AnchorPane> +      </children> +    </HBox> +  </children> +</AnchorPane> diff --git a/src/main/resources/fxml/filterEmployeesControl.fxml b/src/main/resources/fxml/filterEmployeesControl.fxml new file mode 100644 index 0000000..68a6f3e --- /dev/null +++ b/src/main/resources/fxml/filterEmployeesControl.fxml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.TextField?> +<?import javafx.scene.layout.AnchorPane?> + +<AnchorPane prefHeight="86.0" prefWidth="740.0" style="-fx-background-color: white;" +  xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" +  fx:controller="at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.FilterEmployeesController"> +  <children> +    <Label layoutX="14.0" layoutY="14.0" text="Filtern nach Name"/> +    <TextField fx:id="inputFilterString" layoutX="22.0" layoutY="41.0" +      onKeyReleased="#onFilterTextChanged" promptText="Name eingeben"/> +    <Button layoutX="698.0" layoutY="48.0" mnemonicParsing="false" onAction="#onAddEmployeeClicked" +      onInputMethodTextChanged="#onFilterTextChanged" text="Person hinzufügen" +      AnchorPane.rightAnchor="10.0"/> +  </children> +</AnchorPane> diff --git a/src/main/resources/fxml/listEmployees.fxml b/src/main/resources/fxml/listEmployees.fxml new file mode 100644 index 0000000..ae815e1 --- /dev/null +++ b/src/main/resources/fxml/listEmployees.fxml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.ScrollPane?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.layout.FlowPane?> +<?import javafx.scene.layout.VBox?> +<?import javafx.scene.text.Font?> + +<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" +  prefHeight="536.0" prefWidth="816.0" style="-fx-background-color: #EFEBE8;" +  xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" +  fx:controller="at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.ListEmployeesController"> +  <children> +    <AnchorPane prefHeight="118.0" prefWidth="816.0" style="-fx-background-color: #C55A11;"> +      <children> +        <Label layoutX="39.0" layoutY="23.0" text="Personen" textFill="WHITE"> +          <font> +            <Font name="Calibri Bold" size="22.0"/> +          </font> +        </Label> +      </children> +    </AnchorPane> +    <VBox layoutX="37.0" layoutY="60.0" prefHeight="454.0" prefWidth="742.0"> +      <children> +        <AnchorPane fx:id="containerHeader" prefHeight="86.0" prefWidth="740.0" +          style="-fx-background-color: white; -fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.8), 10, 0, 0, 5);"/> +        <ScrollPane hbarPolicy="NEVER" style="-fx-background-color: #EFEBE8;" vbarPolicy="NEVER"> +          <VBox.margin> +            <Insets top="20.0"/> +          </VBox.margin> +          <content> +            <FlowPane fx:id="flowPaneEmployeeList" prefHeight="346.0" prefWidth="742.0" +              style="-fx-background-color: #EFEBE8;"/> +          </content> +        </ScrollPane> +      </children> +    </VBox> +  </children> +</AnchorPane> diff --git a/src/main/resources/fxml/vehiclePane.fxml b/src/main/resources/fxml/vehiclePane.fxml index 8b1d194..784febc 100644 --- a/src/main/resources/fxml/vehiclePane.fxml +++ b/src/main/resources/fxml/vehiclePane.fxml @@ -10,61 +10,56 @@  <?import javafx.scene.text.Text?>  <?import javafx.scene.text.TextFlow?> -<GridPane hgap="6.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" -  fx:controller="at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.ui.vehiclepane.VehiclePaneController"> +<GridPane hgap="6.0" stylesheets="@/styles/main.css" styleClass="bg-white, shadowed" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.VehiclePaneController">    <columnConstraints> -    <ColumnConstraints/> -    <ColumnConstraints/> -    <ColumnConstraints/> -    <ColumnConstraints/> +    <ColumnConstraints /> +    <ColumnConstraints /> +    <ColumnConstraints /> +    <ColumnConstraints />    </columnConstraints>    <rowConstraints> -    <RowConstraints/> -    <RowConstraints/> -    <RowConstraints/> -    <RowConstraints/> +    <RowConstraints /> +    <RowConstraints /> +    <RowConstraints /> +    <RowConstraints />    </rowConstraints>    <padding> -    <Insets bottom="6.0" left="6.0" right="6.0" top="6.0"/> +    <Insets bottom="6.0" left="12.0" right="12.0" top="6.0" />    </padding>    <TextFlow GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="0"> -    <Text text="RTW" fx:id="txtType"> +    <Text fx:id="txtType" text="RTW">        <font> -        <Font name="System Bold" size="18.0"/> +        <Font name="System Bold" size="18.0" />        </font>      </Text> -    <Text text="-10003" fx:id="txtNumber"> +    <Text fx:id="txtNumber" text="-10003">        <font> -        <Font size="16.0"/> +        <Font size="16.0" />        </font>      </Text>    </TextFlow> -  <ImageView fx:id="ivNEF" fitHeight="25.0" fitWidth="25.0" pickOnBounds="true" preserveRatio="true" -    GridPane.columnIndex="0" GridPane.rowIndex="1"> -    <Image url="@../images/NotNEF.png"/> +  <ImageView fx:id="ivNEF" fitHeight="25.0" fitWidth="25.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="0" GridPane.rowIndex="1"> +    <Image url="@../images/NotNEF.png" />    </ImageView>    <Text fx:id="txtNEF" text="keine NEF-Halterung" GridPane.columnIndex="1" GridPane.rowIndex="1">      <font> -      <Font size="14.0"/> +      <Font size="14.0" />      </font>    </Text> -  <ImageView fx:id="ivQualification" fitHeight="25.0" fitWidth="25.0" pickOnBounds="true" -    preserveRatio="true" -    GridPane.columnIndex="0" GridPane.rowIndex="2"> -    <Image url="@../images/Qualification.png"/> +  <ImageView fx:id="ivQualification" fitHeight="25.0" fitWidth="25.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="0" GridPane.rowIndex="2"> +    <Image url="@../images/Qualification.png" />    </ImageView> -  <Text fx:id="txtQualification" text="Notarzt" GridPane.columnIndex="1" GridPane.rowIndex="2"> +  <Text fx:id="txtQualification" text="-" GridPane.columnIndex="1" GridPane.rowIndex="2">      <font> -      <Font size="14.0"/> +      <Font size="14.0" />      </font>    </Text> -  <ImageView fitHeight="25.0" fitWidth="25.0" pickOnBounds="true" preserveRatio="true" -    GridPane.columnIndex="0" GridPane.rowIndex="3"> -    <Image url="@../images/Vehicle.png"/> +  <ImageView fitHeight="25.0" fitWidth="25.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="0" GridPane.rowIndex="3"> +    <Image url="@../images/Vehicle.png" />    </ImageView>    <Text fx:id="txtRooftype" text="Hochdach" GridPane.columnIndex="1" GridPane.rowIndex="3">      <font> -      <Font size="14.0"/> +      <Font size="14.0" />      </font>    </Text>  </GridPane> diff --git a/src/main/resources/images/Driver.png b/src/main/resources/images/Driver.pngBinary files differ new file mode 100644 index 0000000..55d4f4a --- /dev/null +++ b/src/main/resources/images/Driver.png diff --git a/src/main/resources/images/NotDriver.png b/src/main/resources/images/NotDriver.pngBinary files differ new file mode 100644 index 0000000..b8492aa --- /dev/null +++ b/src/main/resources/images/NotDriver.png diff --git a/src/main/resources/images/NotPilot.png b/src/main/resources/images/NotPilot.pngBinary files differ new file mode 100644 index 0000000..22d039f --- /dev/null +++ b/src/main/resources/images/NotPilot.png diff --git a/src/main/resources/images/Pilot.png b/src/main/resources/images/Pilot.pngBinary files differ new file mode 100644 index 0000000..18049e8 --- /dev/null +++ b/src/main/resources/images/Pilot.png diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..d2d4f23 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> +<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> +    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> +        <fileNamePattern>sepm-%d{yyyy-MM-dd}.log</fileNamePattern> +    </rollingPolicy> + +    <encoder> +        <pattern>%date{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern> +    </encoder> +</appender> + +<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> +    <encoder> +        <pattern>%date{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern> +    </encoder> +</appender> + +<root level="INFO"> +    <appender-ref ref="FILE" /> +    <appender-ref ref="STDOUT" /> +</root> +</configuration> diff --git a/src/main/resources/sql/database.sql b/src/main/resources/sql/database.sql index 4f3adf7..463e8ac 100644 --- a/src/main/resources/sql/database.sql +++ b/src/main/resources/sql/database.sql @@ -1,30 +1,26 @@  CREATE TABLE IF NOT EXISTS VehicleVersion (    id BIGINT AUTO_INCREMENT PRIMARY KEY,    name VARCHAR(100) NOT NULL, -  constructionType VARCHAR NOT NULL, -  type VARCHAR NOT NULL, +  constructionType ENUM('NORMAL', 'HOCHDACH', 'MITTELHOCHDACH') NOT NULL, +  type ENUM('BKTW', 'KTW_B', 'KTW', 'RTW', 'NEF', 'NAH') NOT NULL,    hasNef BOOLEAN NOT NULL, -  CHECK constructionType IN ('NORMAL', 'HOCHDACH', 'MITTELHOCHDACH'), -  CHECK type IN ('BKTW', 'KTW-B', 'KTW', 'RTW', 'NEF', 'NAH')  );  CREATE TABLE IF NOT EXISTS Vehicle (    id BIGINT AUTO_INCREMENT PRIMARY KEY,    version BIGINT NOT NULL, -  status VARCHAR NOT NULL, +  status ENUM('ABGEMELDET', 'FREI_WACHE', 'FREI_FUNK', 'ZUM_BERUFUNGSORT', 'AM_BERUFUNGSORT', +              'ZUM_ZIELORT', 'AM_ZIELORT', 'DELETED') NOT NULL,    FOREIGN KEY (version) REFERENCES VehicleVersion(id), -  CHECK status IN ('ABGEMELDET', 'FREI_WACHE', 'ZUM_BERUFUNGSORT', 'AM_BERUFUNGSORT', 'ZUM_ZIELORT', -              'AM_ZIELORT', 'FREI_FUNK', 'DELETED')  );  CREATE TABLE IF NOT EXISTS EmployeeVersion (    id BIGINT AUTO_INCREMENT PRIMARY KEY,    name VARCHAR(100) NOT NULL,    birthday DATE NOT NULL, -  educationLevel VARCHAR NOT NULL, +  educationLevel ENUM('RS', 'NFS', 'NKV', 'NKA', 'NKI', 'NA') NOT NULL,    isDriver BOOLEAN NOT NULL,    isPilot BOOLEAN NOT NULL, -  CHECK educationLevel IN ('RS', 'NFS', 'NKV', 'NKA', 'NKI', 'NA')  );  CREATE TABLE IF NOT EXISTS Employee ( @@ -47,13 +43,11 @@ CREATE TABLE IF NOT EXISTS Registration (  CREATE TABLE IF NOT EXISTS Operation (    id BIGINT AUTO_INCREMENT PRIMARY KEY,    opCode VARCHAR(20) NOT NULL, -  severity VARCHAR NOT NULL, +  severity ENUM('A', 'B', 'C', 'D', 'E', 'O') NOT NULL,    created TIMESTAMP NOT NULL,    destination VARCHAR(100) NOT NULL,    additionalInfo VARCHAR(100), -  status VARCHAR NOT NULL, -  CHECK severity IN ('A', 'B', 'C', 'D', 'E', 'O'), -  CHECK status IN ('ACTIVE', 'COMPLETED', 'CANCELLED') +  status ENUM('ACTIVE', 'COMPLETED', 'CANCELLED'),  );  CREATE TABLE IF NOT EXISTS VehicleOperation ( diff --git a/src/main/resources/styles/main.css b/src/main/resources/styles/main.css new file mode 100644 index 0000000..886e756 --- /dev/null +++ b/src/main/resources/styles/main.css @@ -0,0 +1,95 @@ +/* === shadow === */ +.shadowed { +  -fx-effect: dropshadow(gaussian, rgba(100,100,100,0.8), 5, 0, 0, 3); +} + +/* === background === */ +/* -- basic -- */ +.bg-white { +  -fx-background-color: white; +} +/* -- vehiclePane -- */ +.bg-yellow { +  -fx-background-color: #FFE699; +} +.bg-status-green { +  -fx-background-color: #C5E0B4; +} +.bg-status-orange { +  -fx-background-color: #F8CBAD; +} +/* -- header areas -- */ +.bg-blue { +  -fx-background-color: #2E75B6; +} +.bg-green { +  -fx-background-color: #548235; +} +.bg-light-orange { +  -fx-background-color: #BF9000; +} +.bg-dark-orange { +  -fx-background-color: #C55A11; +} +/* -- content areas -- */ +.bg-gray-blue { +  -fx-background-color: #E8EAEF; +} +.bg-gray-green { +  -fx-background-color: #EBEFE8; +} +.bg-gray-orange { +  -fx-background-color: #EFEBE8; +} +/* -- edit area -- */ +.bg-edit-area-orange { +  -fx-background-color: #FBE5D6; +} + +/* === text === */ +.text-big { +  -fx-font-size: 18px; +} + +.text-medium { +  -fx-font-size: 14px; +} + +.text-small { +  -fx-font-size: 14px; +} + +/* === button === */ +.button { +  -fx-background-radius: 0em; +  -fx-border-color: black; +} + +.button-main { +  -fx-background-color: #548235; +  -fx-text-fill: white; +  -fx-font-weight: bold; +} + +.button-free-status { +  -fx-background-color: #C5E0B4; +} + +.button-other-status { +  -fx-background-color: #F8CBAD; +} + +/* === menu item === */ +.mi-free { +  -fx-background-color: #C5E0B4; +} + +.mi-other { +  -fx-background-color: #F8CBAD; +} + +.menu-item:focused .label { +  -fx-text-fill: black; +  -fx-font-weight: bold; +} + diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/employee/CreateNewEmployeeApplication.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewEmployeeApplication.java index e9f4801..e1b3714 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/employee/CreateNewEmployeeApplication.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewEmployeeApplication.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.sepm.assignment.groupphase.employee; +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller;  import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader;  import java.lang.invoke.MethodHandles; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/employee/CreateNewEmployeeControllerTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewEmployeeControllerTest.java index eb1a728..7f95950 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/employee/CreateNewEmployeeControllerTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewEmployeeControllerTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.sepm.assignment.groupphase.employee; +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller;  import static org.mockito.ArgumentMatchers.any;  import static org.mockito.Mockito.when; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/vehicle/CreateNewVehicleApplication.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewVehicleApplication.java index dcd88ec..ff46938 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/vehicle/CreateNewVehicleApplication.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewVehicleApplication.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.sepm.assignment.groupphase.vehicle; +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller;  import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader;  import java.lang.invoke.MethodHandles; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/vehicle/CreateNewVehicleControllerTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewVehicleControllerTest.java index 866ed74..08e3fde 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/vehicle/CreateNewVehicleControllerTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewVehicleControllerTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.sepm.assignment.groupphase.vehicle; +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller;  import static org.mockito.ArgumentMatchers.any;  import static org.mockito.Mockito.when; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDAOTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDAOTest.java new file mode 100644 index 0000000..585e5ea --- /dev/null +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDAOTest.java @@ -0,0 +1,254 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.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; +import java.time.LocalDate; +import java.util.Set; +import org.dbunit.Assertion; +import org.dbunit.dataset.DataSetException; +import org.dbunit.dataset.IDataSet; +import org.dbunit.dataset.ITable; +import org.dbunit.dataset.filter.DefaultColumnFilter; +import org.dbunit.dataset.xml.FlatXmlDataSetBuilder; +import org.dbunit.util.fileloader.FlatXmlDataFileLoader; +import org.junit.Assert; +import org.junit.Test; + +public class EmployeeDAOTest extends JdbcTestCase { + +    private EmployeeDAO employeePersistence; + +    public EmployeeDAOTest() throws PersistenceException { +        employeePersistence = new EmployeeDatabaseDAO(getJdbcConnectionManager()); +    } + +    @Override +    protected IDataSet getDataSet() throws DataSetException { +        InputStream res = +                getClass() +                        .getClassLoader() +                        .getResourceAsStream("EmployeePersistenceTestBaseData.xml"); +        return new FlatXmlDataSetBuilder().build(res); +    } + +    @Test +    public void testListEmployees() throws PersistenceException { +        Set<Employee> employees = employeePersistence.list(); + +        System.out.println(LocalDate.parse("2010-10-10")); +        Employee empOne = +                Employee.builder() +                        .id(1) +                        .name("Adam") +                        .birthday(LocalDate.parse("2010-10-10")) +                        .educationLevel(EducationLevel.RS) +                        .isDriver(true) +                        .isPilot(false) +                        .build(); + +        Employee empTwo = +                Employee.builder() +                        .id(2) +                        .name("Max") +                        .birthday(LocalDate.parse("1990-11-11")) +                        .educationLevel(EducationLevel.NFS) +                        .isDriver(false) +                        .isPilot(false) +                        .build(); + +        Employee empThree = +                Employee.builder() +                        .id(3) +                        .name("Lisa") +                        .birthday(LocalDate.parse("1999-10-16")) +                        .educationLevel(EducationLevel.NKI) +                        .isDriver(true) +                        .isPilot(false) +                        .build(); + +        Assert.assertTrue(employees.contains(empOne)); +        Assert.assertTrue(employees.contains(empTwo)); +        Assert.assertTrue(employees.contains(empThree)); +        Assert.assertEquals(3, employees.size()); +    } + +    @Test +    public void testEmployeeListNoElement() throws PersistenceException { +        Set<Employee> employees = employeePersistence.list(); + +        Employee empOne = +                Employee.builder() +                        .id(10) +                        .name("Adam") +                        .birthday(LocalDate.parse("2010-10-10")) +                        .educationLevel(EducationLevel.RS) +                        .isDriver(true) +                        .isPilot(false) +                        .build(); + +        Assert.assertFalse(employees.contains(empOne)); +    } + +    Employee validEmployee = +            Employee.builder() +                    .name("Testperson") +                    .birthday(LocalDate.parse("2010-11-11")) +                    .educationLevel(EducationLevel.NA) +                    .isDriver(true) +                    .isPilot(false) +                    .build(); + +    @Test +    public void testAddValidEmployee_EmployeeVersion() throws Exception { + +        employeePersistence.add(validEmployee); + +        String[] excludedColumnsEmployeeVersion = new String[] {"ID"}; +        String tableEmployeeVersion = "EMPLOYEEVERSION"; + +        // load actual and expected data set +        IDataSet actualDataSet = getConnection().createDataSet(); +        IDataSet expectedDataSet = +                new FlatXmlDataFileLoader().load("/testAddValidEmployee_expected.xml"); + +        // extract employeeVersion table +        ITable actualEmployeeVersionTable = actualDataSet.getTable(tableEmployeeVersion); +        ITable expectedEmployeeVersionTable = expectedDataSet.getTable(tableEmployeeVersion); + +        // exclude 'id' column as it is an autogenerated value +        ITable actualFilteredTable = +                DefaultColumnFilter.excludedColumnsTable( +                        actualEmployeeVersionTable, excludedColumnsEmployeeVersion); +        ITable expectedFilteredTable = +                DefaultColumnFilter.excludedColumnsTable( +                        expectedEmployeeVersionTable, excludedColumnsEmployeeVersion); + +        Assertion.assertEquals(expectedFilteredTable, actualFilteredTable); +    } + +    @Test +    public void testAddValidEmployee_Employee() throws Exception { + +        employeePersistence.add(validEmployee); + +        String[] excludedColumnsEmployee = new String[] {"VERSION", "ID"}; +        String tableEmployee = "EMPLOYEE"; + +        // load actual and expected data set +        IDataSet actualDataSet = getConnection().createDataSet(); +        IDataSet expectedDataSet = +                new FlatXmlDataFileLoader().load("/testAddValidEmployee_expected.xml"); + +        // extract employee table +        ITable actualEmployeeTable = actualDataSet.getTable(tableEmployee); +        ITable expectedEmployeeTable = expectedDataSet.getTable(tableEmployee); + +        // exclude 'version' as it is an autogenerated value +        ITable actualFilteredEmpTable = +                DefaultColumnFilter.excludedColumnsTable( +                        actualEmployeeTable, excludedColumnsEmployee); +        ITable expectedFilteredEmpTable = +                DefaultColumnFilter.excludedColumnsTable( +                        expectedEmployeeTable, excludedColumnsEmployee); + +        Assertion.assertEquals(expectedFilteredEmpTable, actualFilteredEmpTable); +    } + +    @Test +    public void testAddValidEmployee_Join() throws Exception { + +        employeePersistence.add(validEmployee); + +        String[] excludedColumns = new String[] {"E_VERSION", "V_ID", "E_ID"}; +        String table = "EMP_JOIN"; +        String expectedXmlDataFileName = "testAddValidEmployeeJoin_expected.xml"; + +        String sqlJoinEmployeeVersion = +                "SELECT e.id AS E_ID, v.name AS V_NAME, v.birthday AS V_BIRTHDAY, " +                        + "v.educationLevel as V_EDUCATIONLEVEL, " +                        + "v.isDriver AS V_ISDRIVER, v.isPilot AS V_ISPILOT " +                        + "FROM Employee e " +                        + "JOIN EmployeeVersion v ON e.version = v.id"; + +        ITable actualFilteredJoinData = +                Helper.getActualFilteredQueryTableData( +                        getConnection(), table, sqlJoinEmployeeVersion, excludedColumns); + +        ITable expectedFilteredJoinData = +                Helper.getExpectedFilteredTableData( +                        table, excludedColumns, expectedXmlDataFileName); + +        Assertion.assertEquals(expectedFilteredJoinData, actualFilteredJoinData); +    } + +    Employee validUpdateEmployee = +            Employee.builder() +                    .id(3) +                    .name("Lisa") +                    .birthday(LocalDate.parse("1999-10-16")) +                    .educationLevel(EducationLevel.NKA) +                    .isDriver(true) +                    .isPilot(true) +                    .build(); + +    @Test +    public void testUpdateValidEmployee_EmployeeVersion() throws Exception { + +        employeePersistence.update(validUpdateEmployee); + +        String[] excludedColumnsEmployeeVersion = new String[] {"ID"}; +        String tableEmployeeVersion = "EMPLOYEEVERSION"; + +        ITable actualTableData = +                Helper.getActualFilteredTableData( +                        getConnection(), tableEmployeeVersion, excludedColumnsEmployeeVersion); +        ITable expedtedTableData = +                Helper.getExpectedFilteredTableData( +                        tableEmployeeVersion, +                        excludedColumnsEmployeeVersion, +                        "testUpdateValidEmployee_expected.xml"); + +        Assertion.assertEquals(expedtedTableData, actualTableData); +    } + +    @Test +    public void testUpdateValidEmployee_Employee() throws Exception { + +        employeePersistence.update(validUpdateEmployee); + +        String[] excludedColumns = new String[] {"VERSION"}; +        String tableName = "EMPLOYEE"; +        String expectedXmlDataFileName = "testUpdateValidEmployee_expected.xml"; + +        ITable actualTableData = +                Helper.getActualFilteredTableData(getConnection(), tableName, excludedColumns); + +        ITable expectedTableData = +                Helper.getExpectedFilteredTableData( +                        tableName, excludedColumns, expectedXmlDataFileName); + +        Assertion.assertEquals(expectedTableData, actualTableData); +    } + +    @Test(expected = ElementNotFoundException.class) +    public void testUpdateNonExistingEmployee() +            throws PersistenceException, ElementNotFoundException { + +        Employee nonExistentEmployee = +                Employee.builder() +                        .id(1000) +                        .name("Lisa") +                        .birthday(LocalDate.parse("1999-10-16")) +                        .educationLevel(EducationLevel.NKA) +                        .isDriver(true) +                        .isPilot(true) +                        .build(); + +        employeePersistence.update(nonExistentEmployee); +    } +} diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAOTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAOTest.java new file mode 100644 index 0000000..f173376 --- /dev/null +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAOTest.java @@ -0,0 +1,157 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.JdbcTestCase; +import java.time.Instant; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Set; +import org.dbunit.dataset.DataSetException; +import org.dbunit.dataset.IDataSet; +import org.junit.Test; + +public class OperationDAOTest extends JdbcTestCase { + +    private static final String[] COMPARE_TABLES = +            new String[] {"VehicleOperation", "Operation", "Vehicle", "VehicleVersion"}; + +    private final OperationDAO operationDAO; + +    private final Operation o; + +    public OperationDAOTest() throws PersistenceException { +        // TODO: fix once everything properly uses dependency injection +        EmployeeDAO employeeDAO = new EmployeeDatabaseDAO(getJdbcConnectionManager()); +        RegistrationDatabaseDAO registrationDatabaseDAO = +                new RegistrationDatabaseDAO(getJdbcConnectionManager(), employeeDAO); +        VehicleDAO vehicleDAO = +                new VehicleDatabaseDAO(getJdbcConnectionManager(), registrationDatabaseDAO); +        this.operationDAO = new OperationDatabaseDAO(getJdbcConnectionManager(), vehicleDAO); + +        Vehicle v1 = +                Vehicle.builder() +                        .id(1) +                        .name("RTW-1") +                        .constructionType(Vehicle.ConstructionType.HOCHDACH) +                        .type(Vehicle.VehicleType.RTW) +                        .status(Vehicle.Status.FREI_FUNK) +                        .hasNef(true) +                        .build(); + +        Vehicle v2 = v1.toBuilder().id(2).build(); +        Vehicle v3 = v1.toBuilder().id(3).build(); + +        o = +                Operation.builder() +                        .id(1) +                        .opCode("RD-2B0M") +                        .severity(Severity.B) +                        .status(Status.ACTIVE) +                        .vehicles(Set.of(v1, v2, v3)) +                        .created(Instant.now()) +                        .destination("New description") +                        .additionalInfo("Test") +                        .build(); +    } + +    @Override +    protected IDataSet getDataSet() throws DataSetException { +        return getDataSet("operationDAOUpdateSetup.xml"); +    } + +    @Test +    public void testUpdateNormal() throws Exception { +        operationDAO.update(o); + +        compareWith("operationDAOUpdateNormal.xml", COMPARE_TABLES); +    } + +    @Test(expected = ElementNotFoundException.class) +    public void testUpdateMissing() throws Exception { +        Operation op = o.toBuilder().id(73).build(); + +        operationDAO.update(op); +    } + +    @Test +    public void testUpdateRemoveVehicles() throws Exception { +        Operation op = o.toBuilder().vehicles(Collections.emptySet()).build(); + +        operationDAO.update(op); + +        compareWith("operationDAOUpdateRemoveVehicles.xml", COMPARE_TABLES); +    } + +    @Test +    public void testListOperations() throws Exception { +        Set<Operation> operationSet = operationDAO.list(EnumSet.allOf(Status.class)); + +        // TODO: operations.list() currently doesn't set the vehicles set +        // assertEquals(Set.of(o), operationSet); +    } + +    @Test +    public void testAddOperation() throws Exception { +        operationDAO.add(o); + +        // TODO: won't work because id won't match +        // compareWith("operationDAOUpdateNormal.xml", COMPARE_TABLES); +    } + +    @Test(expected = PersistenceException.class) +    public void testAddFaultyOperation() throws PersistenceException { +        Vehicle vehicle = +                Vehicle.builder() +                        .status(Vehicle.Status.FREI_FUNK) +                        .constructionType(ConstructionType.HOCHDACH) +                        .name("BKTW_123") +                        .hasNef(true) +                        .type(VehicleType.BKTW) +                        .build(); + +        Operation operation = +                Operation.builder() +                        .status(Status.ACTIVE) +                        .opCode(String.valueOf(Arrays.stream(new int[200]).map(i -> 'a'))) +                        .created(Instant.now()) +                        .destination("Wiedner Hauptstraße 35, Wien") +                        .additionalInfo("HTU Wien") +                        .severity(Severity.B) +                        .vehicles(Set.of(vehicle)) +                        .build(); +        operationDAO.add(operation); +    } + +    @Test(expected = PersistenceException.class) +    public void testAddFaultyOperation2() throws PersistenceException { +        Vehicle vehicle = +                Vehicle.builder() +                        .status(Vehicle.Status.FREI_FUNK) +                        .constructionType(ConstructionType.HOCHDACH) +                        .name("BKTW_123") +                        .hasNef(true) +                        .type(VehicleType.BKTW) +                        .build(); + +        Operation operation = +                Operation.builder() +                        .status(Status.ACTIVE) +                        .opCode("ALP-95E7") +                        .created(Instant.now()) +                        .destination( +                                "Wiednerstraße 888, 1010 Wien Wiednerstraße 888, 1010 Wien Wiednerstraße 888, 1010 Wien Wiednerstraße 888, 1010 Wien Wiednerstraße 888, 1010 Wien ") +                        .additionalInfo("HTU Wien") +                        .severity(Severity.B) +                        .vehicles(Set.of(vehicle)) +                        .build(); +        operationDAO.add(operation); +    } +} diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDatabaseDAOTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDAOTest.java index 03059ff..e8ea809 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDatabaseDAOTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDAOTest.java @@ -11,8 +11,8 @@ import java.nio.charset.Charset;  import java.sql.SQLException;  import java.time.Instant;  import java.time.LocalDate; -import java.util.LinkedList; -import java.util.List; +import java.util.HashSet; +import java.util.Set;  import org.h2.tools.RunScript;  import org.junit.AfterClass;  import org.junit.BeforeClass; @@ -20,9 +20,9 @@ import org.junit.Rule;  import org.junit.Test;  import org.junit.rules.ExpectedException; -public class RegistrationDatabaseDAOTest { +public class RegistrationDAOTest { -    // Base taken from EmployeePersistenceTest +    // Base taken from EmployeeDAOTest      private static final String JDBC_DRIVER = org.h2.Driver.class.getName();      private static final String JDBC_URL = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"; @@ -31,8 +31,12 @@ public class RegistrationDatabaseDAOTest {      private RegistrationDAO registrationDAO; -    public RegistrationDatabaseDAOTest() throws PersistenceException { -        this.registrationDAO = new RegistrationDatabaseDAO(new JDBCConnectionManager(JDBC_URL)); +    public RegistrationDAOTest() throws PersistenceException { +        JDBCConnectionManager jdbcConnectionManager = new JDBCConnectionManager(JDBC_URL); +        this.registrationDAO = +                new RegistrationDatabaseDAO( +                        jdbcConnectionManager, new EmployeeDatabaseDAO(jdbcConnectionManager)); +        // TODO: Use Spring Dependency Injection here!      }      @BeforeClass @@ -79,7 +83,7 @@ public class RegistrationDatabaseDAOTest {      @Test      public void addRegistrationsShouldSucceed() throws PersistenceException { -        List<Registration> registrations = new LinkedList<>(); +        Set<Registration> registrations = new HashSet<>();          /*          Vehicle vehicle = Vehicle.builder()                  .id(1) @@ -139,14 +143,14 @@ public class RegistrationDatabaseDAOTest {          registrations.add(registration2);          registrations.add(registration3); -        List<Long> returnvalues = registrationDAO.add(1, registrations); +        Set<Long> returnvalues = registrationDAO.add(1, registrations);          assertFalse(returnvalues.isEmpty()); // can be improved...      }      @Test      public void addRegistrationToInexistentVehicleShouldFail() throws PersistenceException {          thrown.expect(PersistenceException.class); -        List<Registration> registrations = new LinkedList<>(); +        Set<Registration> registrations = new HashSet<>();          Employee employee =                  Employee.builder()                          .id(1) diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDAOTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDAOTest.java new file mode 100644 index 0000000..1862214 --- /dev/null +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDAOTest.java @@ -0,0 +1,161 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.Status; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.Helper; +import at.ac.tuwien.sepm.assignment.groupphase.util.JdbcTestCase; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Set; +import org.dbunit.Assertion; +import org.dbunit.dataset.IDataSet; +import org.dbunit.dataset.ITable; +import org.dbunit.dataset.xml.FlatXmlDataSetBuilder; +import org.junit.Assert; +import org.junit.Test; + +public class VehicleDAOTest extends JdbcTestCase { + +    private VehicleDAO vehicleDAO; + +    private Vehicle validUpdateVehicle = +            Vehicle.builder() +                    .hasNef(true) +                    .constructionType(ConstructionType.HOCHDACH) +                    .type(VehicleType.RTW) +                    .id(2) +                    .name("RTW-2") +                    .status(Status.ABGEMELDET) +                    .build(); + +    public VehicleDAOTest() throws PersistenceException { +        vehicleDAO = +                new VehicleDatabaseDAO( +                        getJdbcConnectionManager(), +                        new RegistrationDatabaseDAO( +                                getJdbcConnectionManager(), +                                new EmployeeDatabaseDAO(getJdbcConnectionManager()))); +        // TODO: use Spring Dependency Injection! +    } + +    @Override +    protected IDataSet getDataSet() throws Exception { +        InputStream res = getClass().getClassLoader().getResourceAsStream("vehicleTestData.xml"); +        return new FlatXmlDataSetBuilder().build(res); +    } + +    @Test +    public void testListVehicle() throws PersistenceException { +        Set<Vehicle> vehicles = vehicleDAO.list(); + +        Vehicle v1 = +                Vehicle.builder() +                        .id(1) +                        .constructionType(ConstructionType.HOCHDACH) +                        .name("RTW-1") +                        .hasNef(true) +                        .status(Status.ABGEMELDET) +                        .type(VehicleType.RTW) +                        .registrations(new ArrayList<>()) +                        .build(); +        Vehicle v2 = +                Vehicle.builder() +                        .id(2) +                        .constructionType(ConstructionType.MITTELHOCHDACH) +                        .name("KTW-2") +                        .hasNef(false) +                        .status(Status.FREI_WACHE) +                        .type(VehicleType.KTW) +                        .registrations(new ArrayList<>()) +                        .build(); +        Vehicle v3 = +                Vehicle.builder() +                        .id(3) +                        .constructionType(ConstructionType.NORMAL) +                        .name("NEF-3") +                        .hasNef(false) +                        .status(Status.FREI_FUNK) +                        .type(VehicleType.NEF) +                        .registrations(new ArrayList<>()) +                        .build(); + +        Assert.assertTrue(vehicles.contains(v1)); +        Assert.assertTrue(vehicles.contains(v2)); +        Assert.assertTrue(vehicles.contains(v3)); +        Assert.assertEquals(3, vehicles.size()); +    } + +    @Test +    public void testVehicleListNoElement() throws PersistenceException { +        Set<Vehicle> vehicles = vehicleDAO.list(); + +        Vehicle v1 = +                Vehicle.builder() +                        .id(30) +                        .constructionType(ConstructionType.NORMAL) +                        .name("NEF-3") +                        .hasNef(false) +                        .status(Status.FREI_FUNK) +                        .type(VehicleType.NEF) +                        .build(); + +        Assert.assertFalse(vehicles.contains(v1)); +    } + +    @Test +    public void testUpdateValid_VehicleVersion() throws Exception { +        vehicleDAO.update(validUpdateVehicle); + +        String[] excludedColumnsVehicleVersion = new String[] {"ID", "NAME"}; +        String tableVehicleVersion = "VEHICLEVERSION"; + +        ITable actualTableData = +                Helper.getActualFilteredTableData( +                        getConnection(), tableVehicleVersion, excludedColumnsVehicleVersion); + +        ITable expectedTableData = +                Helper.getExpectedFilteredTableData( +                        tableVehicleVersion, +                        excludedColumnsVehicleVersion, +                        "vehicleTestUpdateExpectedData.xml"); +        Assertion.assertEquals(expectedTableData, actualTableData); +    } + +    @Test +    public void testUpdateValid_Vehicle() throws Exception { +        vehicleDAO.update(validUpdateVehicle); + +        String[] excludedColumnsVehicleVersion = new String[] {"VERSION", "STATUS"}; +        String tableVehicleVersion = "VEHICLE"; + +        ITable actualTableData = +                Helper.getActualFilteredTableData( +                        getConnection(), tableVehicleVersion, excludedColumnsVehicleVersion); + +        ITable expectedTableData = +                Helper.getExpectedFilteredTableData( +                        tableVehicleVersion, +                        excludedColumnsVehicleVersion, +                        "vehicleTestUpdateExpectedData.xml"); +        Assertion.assertEquals(expectedTableData, actualTableData); +    } + +    @Test(expected = ElementNotFoundException.class) +    public void testUpdateNonExistingVehicle() +            throws PersistenceException, ElementNotFoundException { +        Vehicle nonExistentVehicle = +                Vehicle.builder() +                        .id(35) +                        .constructionType(ConstructionType.NORMAL) +                        .name("NEF-3") +                        .hasNef(false) +                        .status(Status.FREI_FUNK) +                        .type(VehicleType.NEF) +                        .build(); +        vehicleDAO.update(nonExistentVehicle); +    } +} diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeServiceTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeServiceTest.java new file mode 100644 index 0000000..90f0a44 --- /dev/null +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeServiceTest.java @@ -0,0 +1,67 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; + +import static org.hamcrest.CoreMatchers.is; +import static org.mockito.ArgumentMatchers.any; +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.einsatzverwaltung.dao.EmployeeDAO; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.EmployeeDatabaseDAO; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.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.time.LocalDate; +import org.junit.Assert; +import org.junit.Test; + +public class EmployeeServiceTest { + +    private final EmployeeDAO employeePersistence = mock(EmployeeDatabaseDAO.class); +    private final EmployeeService employeeService = new EmployeeServiceImpl(employeePersistence); + +    private final Employee.Builder employeeBuilder = +            Employee.builder() +                    .name("Testperson") +                    .birthday(LocalDate.parse("1996-10-10")) +                    .educationLevel(EducationLevel.NKA) +                    .isDriver(true) +                    .isPilot(false); + +    public EmployeeServiceTest() throws PersistenceException { +        when(employeePersistence.add(any())).thenReturn(1L); +    } + +    @Test +    public void testAddValidEmployee() throws ServiceException, InvalidEmployeeException { + +        Employee employee = employeeBuilder.build(); +        Assert.assertThat(employeeService.add(employee), is(1L)); +    } + +    @Test(expected = InvalidEmployeeException.class) +    public void testAddInvalidEmployee() throws InvalidEmployeeException, ServiceException { + +        Employee employee = employeeBuilder.name("").build(); +        employeeService.add(employee); +    } + +    @Test +    public void testUpdateValidEmployee() throws ElementNotFoundException, PersistenceException { + +        Employee employee = employeeBuilder.build(); +        employeePersistence.update(employee); +    } + +    @Test(expected = ElementNotFoundException.class) +    public void testUpdateNonExistentEmployee() +            throws ElementNotFoundException, PersistenceException { + +        doThrow(ElementNotFoundException.class).when(employeePersistence).update(any()); +        Employee employee = employeeBuilder.id(1000).build(); +        employeePersistence.update(employee); +    } +} diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/employee/EmployeeServiceTestConfiguration.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeServiceTestConfiguration.java index 3668ef4..6bf2275 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/employee/EmployeeServiceTestConfiguration.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeServiceTestConfiguration.java @@ -1,9 +1,7 @@ -package at.ac.tuwien.sepm.assignment.groupphase.employee; +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service;  import static org.mockito.Mockito.mock; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.EmployeeService; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.EmployeeServiceImpl;  import org.springframework.context.annotation.Bean;  import org.springframework.context.annotation.Configuration;  import org.springframework.context.annotation.Primary; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceTest.java new file mode 100644 index 0000000..67fb77d --- /dev/null +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceTest.java @@ -0,0 +1,205 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +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.einsatzverwaltung.dao.OperationDAO; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.VehicleDAO; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.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; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class OperationServiceTest { + +    @Mock private OperationDAO operationDAO; + +    @Mock private VehicleDAO vehicleDAO; + +    @InjectMocks private OperationServiceImpl operationService; + +    private Set<Vehicle> vehicles; +    private Vehicle v1, v2, v3, v4, v5; +    private Operation baseOp, o1, o2; + +    @Before +    public void setUp() throws Exception { +        v1 = +                Vehicle.builder() +                        .id(1) +                        .name("RTW-1") +                        .constructionType(ConstructionType.HOCHDACH) +                        .type(Vehicle.VehicleType.RTW) +                        .status(Vehicle.Status.FREI_FUNK) +                        .hasNef(true) +                        .build(); + +        v2 = +                Vehicle.builder() +                        .id(2) +                        .name("KTW-1") +                        .constructionType(ConstructionType.HOCHDACH) +                        .type(Vehicle.VehicleType.KTW) +                        .status(Vehicle.Status.FREI_WACHE) +                        .hasNef(true) +                        .build(); + +        v3 = +                Vehicle.builder() +                        .id(3) +                        .name("KTW-2") +                        .constructionType(ConstructionType.MITTELHOCHDACH) +                        .type(Vehicle.VehicleType.KTW_B) +                        .status(Vehicle.Status.FREI_FUNK) +                        .hasNef(false) +                        .build(); + +        v4 = +                Vehicle.builder() +                        .id(4) +                        .name("BKTW-2") +                        .constructionType(ConstructionType.HOCHDACH) +                        .type(Vehicle.VehicleType.BKTW) +                        .status(Vehicle.Status.FREI_FUNK) +                        .hasNef(false) +                        .build(); + +        v5 = +                Vehicle.builder() +                        .id(5) +                        .name("NEF-1") +                        .constructionType(ConstructionType.NORMAL) +                        .type(Vehicle.VehicleType.NEF) +                        .status(Vehicle.Status.FREI_WACHE) +                        .hasNef(true) +                        .build(); + +        Vehicle v6 = +                Vehicle.builder() +                        .id(6) +                        .name("NAH-1") +                        .constructionType(ConstructionType.MITTELHOCHDACH) +                        .type(Vehicle.VehicleType.NAH) +                        .status(Vehicle.Status.ABGEMELDET) +                        .hasNef(true) +                        .build(); + +        vehicles = Set.of(v1, v2, v3, v4, v5, v6); + +        baseOp = +                Operation.builder() +                        .opCode("ALP-95E7") +                        .severity(Severity.E) +                        .status(Status.ACTIVE) +                        .vehicles(Collections.singleton(v1)) +                        .destination("Wiedner Hauptstraße 35, Wien") +                        .build(); + +        o1 = baseOp.toBuilder().id(1).created(Instant.now()).build(); +        o2 = o1.toBuilder().id(5).status(Status.CANCELLED).build(); + +        when(operationDAO.get(anyLong())) +                .thenAnswer( +                        ans -> { +                            long arg = ans.getArgument(0); +                            if (arg == 1L) return o1; +                            else if (arg == 5L) return o2; +                            else throw new ElementNotFoundException(""); +                        }); + +        when(vehicleDAO.get(anyLong())) +                .thenAnswer( +                        ans -> { +                            int arg = ((Long) ans.getArgument(0)).intValue(); +                            return vehicles.stream() +                                    .filter(v -> v.id() == arg) +                                    .findFirst() +                                    .orElseThrow(() -> new ElementNotFoundException("")); +                        }); +    } + +    @Test +    public void requestNormal() throws Exception { +        Set<Long> vehicleIds = Set.of(2L, 3L, 4L, 5L); +        operationService.requestVehicles(1, vehicleIds); + +        Operation result = +                operationDAO.get(1).toBuilder().vehicles(Set.of(v1, v2, v3, v4, v5)).build(); +        verify(operationDAO, times(1)).update(result); +        verify(operationDAO, times(0)).get(6L); +    } + +    @Test +    public void requestExistingVehicle() throws Exception { +        operationService.requestVehicles(1, Set.of(1L)); + +        Operation result = operationDAO.get(1); +        verify(operationDAO, times(0)).update(result); +    } + +    @Test(expected = InvalidVehicleException.class) +    public void requestInvalidVehicle() throws Exception { +        operationService.requestVehicles(1, Set.of(5L, 6L)); +    } + +    @Test(expected = InvalidOperationException.class) +    public void requestInvalidOperation() throws Exception { +        operationService.requestVehicles(2, Set.of(1L)); +    } + +    @Test(expected = InvalidVehicleException.class) +    public void requestInactiveVehicle() throws Exception { +        operationService.requestVehicles(1, Set.of(6L)); +    } + +    @Test(expected = InvalidOperationException.class) +    public void requestInactiveOperation() throws Exception { +        operationService.requestVehicles(5, Set.of(1L)); +    } + +    @Test +    public void addOperation() throws Exception { +        operationService.add(baseOp.toBuilder().severity(null).build()); + +        verify(operationDAO, times(1)) +                .add(baseOp.toBuilder().created(any()).status(Status.ACTIVE).build()); +        verify(vehicleDAO, times(1)).get(v1.id()); +    } + +    @Test(expected = InvalidOperationException.class) +    public void addWithSeverity() throws Exception { +        operationService.add(baseOp.toBuilder().severity(Severity.E).build()); +    } + +    @Test(expected = InvalidOperationException.class) +    public void addWithoutVehicles() throws Exception { +        operationService.add(baseOp.toBuilder().vehicles(Set.of()).build()); +    } + +    @Test(expected = InvalidOperationException.class) +    public void addInvalidOpcode() throws Exception { +        operationService.add(baseOp.toBuilder().opCode("ABC").build()); +    } + +    @Test(expected = InvalidOperationException.class) +    public void addWithSetCreated() throws Exception { +        operationService.add(baseOp.toBuilder().created(Instant.now()).build()); +    } +} diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationServiceImplTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationServiceTest.java index f3efbef..4d3a251 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationServiceImplTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationServiceTest.java @@ -1,25 +1,28 @@  package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; -import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong;  import static org.mockito.Mockito.when;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.RegistrationDAO; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.VehicleDAO;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.Builder;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.Status;  import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.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; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; +import java.util.HashSet; +import java.util.Set;  import org.junit.Before;  import org.junit.Rule;  import org.junit.Test; @@ -29,38 +32,35 @@ import org.mockito.MockitoAnnotations;  import org.mockito.junit.MockitoJUnit;  import org.mockito.junit.MockitoRule; -public class RegistrationServiceImplTest { +public class RegistrationServiceTest { -    @Mock RegistrationDAO daoMock; +    @Mock private RegistrationDAO registrationDAO; -    @Mock VehicleService vehicleService; +    @Mock private VehicleDAO vehicleDAO;      @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();      @Rule public ExpectedException thrown = ExpectedException.none();      @Before -    public void setUp() throws ServiceException { +    public void setUp() throws ElementNotFoundException, PersistenceException {          MockitoAnnotations.initMocks(this); -        when(vehicleService.list(any())) -                .thenReturn( -                        Arrays.asList( -                                Vehicle.builder() -                                        .id(1) -                                        .name("RTW-1") -                                        .constructionType(ConstructionType.HOCHDACH) -                                        .status(Status.ABGEMELDET) -                                        .type(VehicleType.RTW) -                                        .hasNef(true) -                                        .build())); +        Builder b = +                Vehicle.builder() +                        .name("RTW-1") +                        .constructionType(ConstructionType.HOCHDACH) +                        .status(Status.ABGEMELDET) +                        .type(VehicleType.RTW) +                        .hasNef(true); +        when(vehicleDAO.get(anyLong())).thenAnswer(ans -> b.id(ans.getArgument(0)).build());      }      @Test      public void addValidRegistrationsShouldSucceed()              throws InvalidRegistrationException, ServiceException, InvalidVehicleException {          RegistrationService registrationService = -                new RegistrationServiceImpl(daoMock, vehicleService); -        List<Registration> registrations = new LinkedList<>(); +                new RegistrationServiceImpl(registrationDAO, vehicleDAO); +        Set<Registration> registrations = new HashSet<>();          Vehicle vehicle =                  Vehicle.builder()                          .id(1) @@ -116,8 +116,8 @@ public class RegistrationServiceImplTest {              throws InvalidRegistrationException, ServiceException, InvalidVehicleException {          thrown.expect(InvalidRegistrationException.class);          RegistrationService registrationService = -                new RegistrationServiceImpl(daoMock, vehicleService); -        List<Registration> registrations = new LinkedList<>(); +                new RegistrationServiceImpl(registrationDAO, vehicleDAO); +        Set<Registration> registrations = new HashSet<>();          Vehicle vehicle =                  Vehicle.builder()                          .id(1) diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/vehicle/VehicleServiceTestConfiguration.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceTestConfiguration.java index ccd1e5d..895973a 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/vehicle/VehicleServiceTestConfiguration.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceTestConfiguration.java @@ -1,9 +1,7 @@ -package at.ac.tuwien.sepm.assignment.groupphase.vehicle; +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service;  import static org.mockito.Mockito.mock; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.VehicleService; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.VehicleServiceImpl;  import org.springframework.context.annotation.Bean;  import org.springframework.context.annotation.Configuration;  import org.springframework.context.annotation.Primary; diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/employee/EmployeePersistenceTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/employee/EmployeePersistenceTest.java deleted file mode 100644 index f8fe0f3..0000000 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/employee/EmployeePersistenceTest.java +++ /dev/null @@ -1,155 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.employee; - -import static junit.framework.TestCase.fail; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.EmployeeDAO; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.EmployeeDatabaseDao; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; -import java.nio.charset.Charset; -import java.sql.SQLException; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; -import java.util.List; -import org.dbunit.IDatabaseTester; -import org.dbunit.JdbcDatabaseTester; -import org.dbunit.dataset.DataSetException; -import org.dbunit.dataset.IDataSet; -import org.dbunit.dataset.xml.FlatXmlDataSetBuilder; -import org.dbunit.operation.DatabaseOperation; -import org.h2.tools.RunScript; -import org.junit.Assert; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -public class EmployeePersistenceTest { - -    private static final String JDBC_DRIVER = org.h2.Driver.class.getName(); -    private static final String JDBC_URL = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"; -    private static final String USER = ""; -    private static final String PASSWORD = ""; - -    private EmployeeDAO employeePersistence; - -    public EmployeePersistenceTest() throws PersistenceException { -        employeePersistence = new EmployeeDatabaseDao(new JDBCConnectionManager(JDBC_URL)); -    } - -    @BeforeClass -    public static void createSchema() throws SQLException { -        RunScript.execute( -                JDBC_URL, -                USER, -                PASSWORD, -                "classpath:sql/database.sql", -                Charset.forName("UTF8"), -                false); -    } - -    @Before -    public void importDataSet() throws Exception { -        IDataSet dataSet = readDataSet(); -        cleanlyInsert(dataSet); -    } - -    private IDataSet readDataSet() throws DataSetException { -        return new FlatXmlDataSetBuilder() -                .build( -                        getClass() -                                .getClassLoader() -                                .getResourceAsStream("employeeServiceTestData.xml")); -    } - -    private void cleanlyInsert(IDataSet dataSet) throws Exception { -        IDatabaseTester databaseTester = -                new JdbcDatabaseTester(JDBC_DRIVER, JDBC_URL, USER, PASSWORD); - -        databaseTester.setSetUpOperation(DatabaseOperation.CLEAN_INSERT); -        databaseTester.setDataSet(dataSet); -        databaseTester.onSetup(); -    } - -    @Test -    public void testListEmployees() { - -        try { -            List<Employee> employees = employeePersistence.list(); - -            Employee empOne = -                    Employee.builder() -                            .id(1) -                            .name("Adam") -                            .birthday( -                                    LocalDate.parse( -                                            "10.10.2010", -                                            DateTimeFormatter.ofPattern("dd.MM.yyyy"))) -                            .educationLevel(EducationLevel.RS) -                            .isDriver(true) -                            .isPilot(false) -                            .build(); - -            Employee empTwo = -                    Employee.builder() -                            .id(2) -                            .name("Max") -                            .birthday( -                                    LocalDate.parse( -                                            "11.11.1990", -                                            DateTimeFormatter.ofPattern("dd.MM.yyyy"))) -                            .educationLevel(EducationLevel.NFS) -                            .isDriver(false) -                            .isPilot(false) -                            .build(); - -            Employee empThree = -                    Employee.builder() -                            .id(3) -                            .name("Lisa") -                            .birthday( -                                    LocalDate.parse( -                                            "16.10.1999", -                                            DateTimeFormatter.ofPattern("dd.MM.yyyy"))) -                            .educationLevel(EducationLevel.NKI) -                            .isDriver(true) -                            .isPilot(false) -                            .build(); - -            Assert.assertTrue(employees.contains(empOne)); -            Assert.assertTrue(employees.contains(empTwo)); -            Assert.assertTrue(employees.contains(empThree)); -            Assert.assertEquals(3, employees.size()); - -        } catch (PersistenceException e) { -            fail(); -        } -    } - -    @Test -    public void testEmployeeListNoElement() { - -        try { -            List<Employee> employees = employeePersistence.list(); - -            Employee empOne = -                    Employee.builder() -                            .id(10) -                            .name("Adam") -                            .birthday( -                                    LocalDate.parse( -                                            "10.10.2010", -                                            DateTimeFormatter.ofPattern("dd.MM.yyyy"))) -                            .educationLevel(EducationLevel.RS) -                            .isDriver(true) -                            .isPilot(false) -                            .build(); - -            Assert.assertFalse(employees.contains(empOne)); - -        } catch (PersistenceException e) { -            fail(); -        } -    } -} diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/employee/EmployeeServiceTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/employee/EmployeeServiceTest.java deleted file mode 100644 index 47328b3..0000000 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/employee/EmployeeServiceTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.employee; - -import static junit.framework.TestCase.fail; -import static org.hamcrest.CoreMatchers.is; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.EmployeeDAO; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.EmployeeDatabaseDao; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.EmployeeService; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.EmployeeServiceImpl; -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.time.LocalDate; -import org.junit.Assert; -import org.junit.Test; - -public class EmployeeServiceTest { - -    private final EmployeeDAO employeePersistence = mock(EmployeeDatabaseDao.class); -    private final EmployeeService employeeService = new EmployeeServiceImpl(employeePersistence); - -    public EmployeeServiceTest() throws PersistenceException { -        when(employeePersistence.add(any())).thenReturn(1L); -    } - -    @Test -    public void testAddValidEmployee() { - -        Employee employee = -                Employee.builder() -                        .name("Testperson") -                        .birthday(LocalDate.MIN) -                        .educationLevel(EducationLevel.NA) -                        .isDriver(true) -                        .isPilot(false) -                        .build(); - -        try { -            Assert.assertThat(employeeService.add(employee), is(1L)); -        } catch (InvalidEmployeeException | ServiceException e) { -            fail(); -        } -    } - -    @Test(expected = InvalidEmployeeException.class) -    public void testAddInvalidEmployee() throws InvalidEmployeeException { - -        Employee employee = -                Employee.builder() -                        .name("") -                        .birthday(LocalDate.MIN) -                        .educationLevel(EducationLevel.NA) -                        .isDriver(true) -                        .isPilot(false) -                        .build(); - -        try { -            employeeService.add(employee); -        } catch (ServiceException e) { -            fail(); -        } -    } -} diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/operation/OperationPersistenceTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/operation/OperationPersistenceTest.java deleted file mode 100644 index be612d0..0000000 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/operation/OperationPersistenceTest.java +++ /dev/null @@ -1,109 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.operation; - -public class OperationPersistenceTest { - -    /*private final OperationDAO operationDAO = -            new DBOperationDAO(new JDBCConnectionManager("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1")); - -    @BeforeClass -    public static void createSchema() throws SQLException { -        RunScript.execute( -                "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", -                "", -                "", -                "classpath:sql/database.sql", -                Charset.forName("UTF8"), -                false); -    } - -    @Test -    public void addOperationTest() { -        Vehicle vehicle = -                Vehicle.builder() -                        .status(Vehicle.Status.FREI_FUNK) -                        .constructionType(ConstructionType.HOCHDACH) -                        .name("BKTW_123") -                        .hasNef(true) -                        .type(VehicleType.BKTW) -                        .build(); - -        Operation operation = -                Operation.builder() -                        .status(Status.ACTIVE) -                        .opCode("ALP-95E7") -                        .created(Instant.now()) -                        .destination("Wiedner Hauptstraße 35, Wien") -                        .additionalInfo("HTU Wien") -                        .severity(Severity.B) -                        .vehicles(List.of(vehicle)) -                        .build(); -        try { -            operationDAO.add(operation); -        } catch (PersistenceException e) { -            fail(); -        } -    } - -    /*@Test(expected = PersistenceException.class) -    public void addFaultyOperationTest() throws PersistenceException { -        Vehicle vehicle = -                Vehicle.builder() -                        .status(Vehicle.Status.FREI_FUNK) -                        .constructionType(ConstructionType.HOCHDACH) -                        .name("BKTW_123") -                        .hasNef(true) -                        .type(VehicleType.BKTW) -                        .build(); - -        Operation operation = -                Operation.builder() -                        .status(Status.ACTIVE) -                        .opCode("") -                        .created(Instant.now()) -                        .destination("Wiedner Hauptstraße 35, Wien") -                        .additionalInfo("HTU Wien") -                        .severity(Severity.B) -                        .vehicles(List.of(vehicle)) -                        .build(); -        operationDAO.add(operation); -    }*/ -    /* - -    @Test(expected = PersistenceException.class) -    public void addFaultyOperation1Test() throws PersistenceException { -        operationDAO.add(null); -    } - -    @Test(expected = PersistenceException.class) -    public void addFaultyOperation2Test() throws PersistenceException { -        Vehicle vehicle = -                Vehicle.builder() -                        .status(Vehicle.Status.FREI_FUNK) -                        .constructionType(ConstructionType.HOCHDACH) -                        .name("BKTW_123") -                        .hasNef(true) -                        .type(VehicleType.BKTW) -                        .build(); - -        Operation operation = -                Operation.builder() -                        .status(Status.ACTIVE) -                        .opCode("ALP-95E7") -                        .created(Instant.now()) -                        .destination( -                                "Wiednerstraße 888, 1010 Wien Wiednerstraße 888, 1010 Wien Wiednerstraße 888, 1010 Wien Wiednerstraße 888, 1010 Wien Wiednerstraße 888, 1010 Wien ") -                        .additionalInfo("HTU Wien") -                        .severity(Severity.B) -                        .vehicles(List.of(vehicle)) -                        .build(); -        operationDAO.add(operation); -    } - -    @Test(expected = PersistenceException.class) -    public void addConnectionTest() throws PersistenceException { -        operationDAO.connectVehicleToOperation(-1, 0); -    } - -    // TODO: ADD CONNECTION TESTS -    // KOMMT ID ZURÜCK?*/ -} diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/operation/OperationServiceComponentTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/operation/OperationServiceComponentTest.java deleted file mode 100644 index 286ee07..0000000 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/operation/OperationServiceComponentTest.java +++ /dev/null @@ -1,130 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.operation; - -public class OperationServiceComponentTest { - -    /*private final OperationDAO operationDAO = -            new DBOperationDAO(new JDBCConnectionManager("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1")); -    private final OperationService operationService = new OperationServiceImpl(operationDAO); - -    @Test -    public void addOperationTest() { -        Vehicle vehicle = -                Vehicle.builder() -                        .status(Vehicle.Status.FREI_FUNK) -                        .constructionType(ConstructionType.HOCHDACH) -                        .name("BKTW_123") -                        .hasNef(true) -                        .type(VehicleType.BKTW) -                        .build(); - -        Operation operation = -                Operation.builder() -                        .status(Status.ACTIVE) -                        .opCode("ALP-95E7") -                        .created(Instant.now()) -                        .destination("Wiedner Hauptstraße 35, Wien") -                        .additionalInfo("HTU Wien") -                        .severity(Severity.B) -                        .vehicles(List.of(vehicle)) -                        .build(); -        try { -            // TODO: OPERATION DOES NOT WORK -            Assert.assertThat(operationService.add(operation), is(1L)); -        } catch (InvalidOperationException | ServiceException e) { -            fail(); -        } -    } - -    @Test(expected = InvalidOperationException.class) -    public void addFaultyOperationTest() throws InvalidOperationException { -        Vehicle vehicle = -                Vehicle.builder() -                        .status(Vehicle.Status.FREI_FUNK) -                        .constructionType(ConstructionType.HOCHDACH) -                        .name("BKTW_123") -                        .hasNef(true) -                        .type(VehicleType.BKTW) -                        .build(); -        Vehicle vehicle1 = -                Vehicle.builder() -                        .status(Vehicle.Status.ABGEMELDET) -                        .constructionType(ConstructionType.HOCHDACH) -                        .name("BKTW_123") -                        .hasNef(true) -                        .type(VehicleType.BKTW) -                        .build(); - -        Operation operation = -                Operation.builder() -                        .status(Status.ACTIVE) -                        .opCode("ALP-95E7") -                        .created(Instant.now()) -                        .destination("Wiedner Hauptstraße 35, Wien") -                        .additionalInfo("HTU Wien") -                        .severity(Severity.B) -                        .vehicles(List.of(vehicle, vehicle1)) -                        .build(); -        try { -            Assert.assertThat(operationService.add(operation), is(1L)); -        } catch (ServiceException e) { -            fail(); -        } -    } - -    @Test(expected = InvalidOperationException.class) -    public void addFaultyOperation2Test() throws InvalidOperationException { -        Operation operation = -                Operation.builder() -                        .status(Status.ACTIVE) -                        .opCode("ALP-95E7") -                        .created(Instant.now()) -                        .destination("Wiedner Hauptstraße 35, Wien") -                        .additionalInfo("HTU Wien") -                        .severity(Severity.B) -                        .vehicles(List.of()) -                        .build(); -        try { -            Assert.assertThat(operationService.add(operation), is(1L)); -        } catch (ServiceException e) { -            e.printStackTrace(); -        } -    } - -    @Test(expected = InvalidOperationException.class) -    public void addFaultyOperation3Test() throws InvalidOperationException { -        Operation operation = -                Operation.builder() -                        .status(Status.ACTIVE) -                        .opCode("ALP-95E7") -                        .created(Instant.now()) -                        .destination("") -                        .additionalInfo("HTU Wien") -                        .severity(Severity.B) -                        .vehicles(List.of()) -                        .build(); -        try { -            Assert.assertThat(operationService.add(operation), is(1L)); -        } catch (ServiceException e) { -            e.printStackTrace(); -        } -    } - -    @Test(expected = InvalidOperationException.class) -    public void addFaultyOperation4Test() throws InvalidOperationException { -        Operation operation = -                Operation.builder() -                        .status(Status.ACTIVE) -                        .opCode("") -                        .created(Instant.now()) -                        .destination("Römergasse 7, 2500 Baden") -                        .additionalInfo("HTU Wien") -                        .severity(Severity.B) -                        .vehicles(List.of()) -                        .build(); -        try { -            Assert.assertThat(operationService.add(operation), is(1L)); -        } catch (ServiceException e) { -            e.printStackTrace(); -        } -    }*/ -} diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/operation/OperationServiceUnitTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/operation/OperationServiceUnitTest.java deleted file mode 100644 index fc10553..0000000 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/operation/OperationServiceUnitTest.java +++ /dev/null @@ -1,155 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.operation; - -import static junit.framework.TestCase.fail; -import static org.hamcrest.CoreMatchers.is; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.OperationDAO; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.OperationService; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.OperationServiceImpl; -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 java.time.Instant; -import java.util.List; -import org.junit.Assert; -import org.junit.Test; - -public class OperationServiceUnitTest { -    private final OperationDAO operationDAO = mock(OperationDAO.class); -    private final OperationService operationService = new OperationServiceImpl(operationDAO); - -    @Test -    public void addOperationTest() { -        try { -            when(operationDAO.add(any())).thenReturn(1L); -        } catch (PersistenceException e) { -            fail(); -        } -        Vehicle vehicle = -                Vehicle.builder() -                        .status(Vehicle.Status.FREI_FUNK) -                        .constructionType(ConstructionType.HOCHDACH) -                        .name("BKTW_123") -                        .hasNef(true) -                        .type(VehicleType.BKTW) -                        .build(); - -        Operation operation = -                Operation.builder() -                        .status(Status.ACTIVE) -                        .opCode("ALP-95E7") -                        .created(Instant.now()) -                        .destination("Wiedner Hauptstraße 35, Wien") -                        .additionalInfo("HTU Wien") -                        .severity(Severity.B) -                        .vehicles(List.of(vehicle)) -                        .build(); -        try { -            Assert.assertThat(operationService.add(operation), is(1L)); -        } catch (InvalidOperationException | ServiceException e) { -            fail(); -        } -    } - -    @Test(expected = InvalidOperationException.class) -    public void addFaultyOperationTest() throws InvalidOperationException { -        Vehicle vehicle = -                Vehicle.builder() -                        .status(Vehicle.Status.FREI_FUNK) -                        .constructionType(ConstructionType.HOCHDACH) -                        .name("BKTW_123") -                        .hasNef(true) -                        .type(VehicleType.BKTW) -                        .build(); -        Vehicle vehicle1 = -                Vehicle.builder() -                        .status(Vehicle.Status.ABGEMELDET) -                        .constructionType(ConstructionType.HOCHDACH) -                        .name("BKTW_123") -                        .hasNef(true) -                        .type(VehicleType.BKTW) -                        .build(); - -        Operation operation = -                Operation.builder() -                        .status(Status.ACTIVE) -                        .opCode("ALP-95E7") -                        .created(Instant.now()) -                        .destination("Wiedner Hauptstraße 35, Wien") -                        .additionalInfo("HTU Wien") -                        .severity(Severity.B) -                        .vehicles(List.of(vehicle, vehicle1)) -                        .build(); -        try { -            Assert.assertThat(operationService.add(operation), is(1L)); -        } catch (ServiceException e) { -            fail(); -        } -    } - -    @Test(expected = InvalidOperationException.class) -    public void addFaultyOperation2Test() throws InvalidOperationException { -        Operation operation = -                Operation.builder() -                        .status(Status.ACTIVE) -                        .opCode("ALP-95E7") -                        .created(Instant.now()) -                        .destination("Wiedner Hauptstraße 35, Wien") -                        .additionalInfo("HTU Wien") -                        .severity(Severity.B) -                        .vehicles(List.of()) -                        .build(); -        try { -            Assert.assertThat(operationService.add(operation), is(1L)); -        } catch (ServiceException e) { -            e.printStackTrace(); -        } -    } - -    @Test(expected = InvalidOperationException.class) -    public void addFaultyOperation3Test() throws InvalidOperationException { -        Operation operation = -                Operation.builder() -                        .status(Status.ACTIVE) -                        .opCode("ALP-95E7") -                        .created(Instant.now()) -                        .destination("") -                        .additionalInfo("HTU Wien") -                        .severity(Severity.B) -                        .vehicles(List.of()) -                        .build(); -        try { -            Assert.assertThat(operationService.add(operation), is(1L)); -        } catch (ServiceException e) { -            e.printStackTrace(); -        } -    } - -    @Test(expected = InvalidOperationException.class) -    public void addFaultyOperation4Test() throws InvalidOperationException { -        Operation operation = -                Operation.builder() -                        .status(Status.ACTIVE) -                        .opCode("") -                        .created(Instant.now()) -                        .destination("Römergasse 7, 2500 Baden") -                        .additionalInfo("HTU Wien") -                        .severity(Severity.B) -                        .vehicles(List.of()) -                        .build(); -        try { -            Assert.assertThat(operationService.add(operation), is(1L)); -        } catch (ServiceException e) { -            e.printStackTrace(); -        } -    } -} diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/util/Helper.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/util/Helper.java index b808206..618b06f 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/util/Helper.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/util/Helper.java @@ -6,6 +6,12 @@ import java.util.List;  import javafx.stage.Modality;  import javafx.stage.Stage;  import javafx.stage.Window; +import org.dbunit.database.IDatabaseConnection; +import org.dbunit.dataset.DataSetException; +import org.dbunit.dataset.IDataSet; +import org.dbunit.dataset.ITable; +import org.dbunit.dataset.filter.DefaultColumnFilter; +import org.dbunit.util.fileloader.FlatXmlDataFileLoader;  import org.testfx.api.FxRobotContext;  public class Helper { @@ -25,4 +31,39 @@ public class Helper {                          .findFirst()                          .orElse(null);      } + +    public static ITable getActualFilteredTableData( +            IDatabaseConnection connection, String tableName, String[] excludedColumns) +            throws Exception { +        IDataSet actualDataSet = connection.createDataSet(); +        ITable actualTable = actualDataSet.getTable(tableName); +        return getFilteredTableData(actualTable, excludedColumns); +    } + +    public static ITable getExpectedFilteredTableData( +            String tableName, String[] excludedColumns, String expectedXmlDataFileName) +            throws Exception { +        IDataSet dataSet = loadDataSet(expectedXmlDataFileName); +        ITable table = dataSet.getTable(tableName); +        return getFilteredTableData(table, excludedColumns); +    } + +    public static ITable getActualFilteredQueryTableData( +            IDatabaseConnection connection, +            String resultTableName, +            String sql, +            String[] excludedColumns) +            throws Exception { +        ITable queryData = connection.createQueryTable(resultTableName, sql); +        return getFilteredTableData(queryData, excludedColumns); +    } + +    private static ITable getFilteredTableData(ITable tableData, String[] excludedColumns) +            throws DataSetException { +        return DefaultColumnFilter.excludedColumnsTable(tableData, excludedColumns); +    } + +    private static IDataSet loadDataSet(String fileName) { +        return new FlatXmlDataFileLoader().load("/" + fileName); +    }  } diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/util/JdbcTestCase.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/util/JdbcTestCase.java new file mode 100644 index 0000000..c509a1f --- /dev/null +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/util/JdbcTestCase.java @@ -0,0 +1,160 @@ +package at.ac.tuwien.sepm.assignment.groupphase.util; + +import static org.dbunit.Assertion.assertEquals; + +import java.io.InputStream; +import java.lang.invoke.MethodHandles; +import java.sql.SQLException; +import java.sql.Types; +import java.util.Collection; +import java.util.Collections; +import org.dbunit.DefaultDatabaseTester; +import org.dbunit.IDatabaseTester; +import org.dbunit.IOperationListener; +import org.dbunit.database.DatabaseConfig; +import org.dbunit.database.DatabaseConnection; +import org.dbunit.database.IDatabaseConnection; +import org.dbunit.dataset.DataSetException; +import org.dbunit.dataset.IDataSet; +import org.dbunit.dataset.datatype.DataType; +import org.dbunit.dataset.datatype.DataTypeException; +import org.dbunit.dataset.xml.FlatXmlDataSetBuilder; +import org.dbunit.ext.postgresql.PostgresqlDataTypeFactory; +import org.dbunit.operation.DatabaseOperation; +import org.junit.After; +import org.junit.Before; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public abstract class JdbcTestCase { + +    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); +    private static final String JDBC_URL = +            "jdbc:h2:mem:test;INIT=RUNSCRIPT FROM 'classpath:sql/database.sql'"; + +    private IDatabaseTester dbTester; +    private IDatabaseConnection connection; +    private IOperationListener operationListener; +    private JDBCConnectionManager jdbcConnectionManager; + +    protected JdbcTestCase() { +        jdbcConnectionManager = new JDBCConnectionManager(JDBC_URL); +    } + +    protected abstract IDataSet getDataSet() throws Exception; + +    protected IDataSet getDataSet(String xmlname) throws DataSetException { +        InputStream res = getClass().getClassLoader().getResourceAsStream(xmlname); +        FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder(); +        builder.setColumnSensing(true); +        return builder.build(res); +    } + +    protected JDBCConnectionManager getJdbcConnectionManager() { +        return jdbcConnectionManager; +    } + +    protected IDatabaseConnection getConnection() throws Exception { +        if (connection == null) +            connection = new DatabaseConnection(jdbcConnectionManager.getConnection(), null, true); + +        return connection; +    } + +    private IOperationListener getOperationListener() { +        if (operationListener == null) { +            operationListener = +                    new IOperationListener() { +                        @Override +                        public void connectionRetrieved(IDatabaseConnection connection) { +                            setUpDatabaseConfig(connection.getConfig()); +                        } + +                        @Override +                        public void operationSetUpFinished(IDatabaseConnection connection) { +                            LOG.debug("operationSetUpFinished(connection={}) - start", connection); +                        } + +                        @Override +                        public void operationTearDownFinished(IDatabaseConnection connection) { +                            LOG.debug( +                                    "operationTearDownFinished(connection={}) - start", connection); +                            try { +                                connection.close(); +                            } catch (SQLException e) { +                                LOG.error("Failed to close connection:" + e); +                                e.printStackTrace(); +                            } +                        } +                    }; +        } + +        return operationListener; +    } + +    // override DBUnit's enum handling +    private void setUpDatabaseConfig(DatabaseConfig config) { +        PostgresqlDataTypeFactory factory = +                new PostgresqlDataTypeFactory() { +                    @Override +                    public boolean isEnumType(String sqlTypeName) { +                        if (sqlTypeName.equalsIgnoreCase("enum")) return true; + +                        return super.isEnumType(sqlTypeName); +                    } + +                    @Override +                    public DataType createDataType(int sqlType, String sqlTypeName) +                            throws DataTypeException { +                        if (isEnumType(sqlTypeName)) { +                            sqlType = Types.VARCHAR; +                        } + +                        return super.createDataType(sqlType, sqlTypeName); +                    } + +                    @Override +                    public Collection getValidDbProducts() { +                        return Collections.singletonList("H2"); +                    } +                }; + +        config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, factory); +    } + +    protected void compareWith(String xmlname, String[] tables) throws Exception { +        InputStream res = getClass().getClassLoader().getResourceAsStream(xmlname); +        IDataSet actual = getConnection().createDataSet(); +        IDataSet expected = new FlatXmlDataSetBuilder().build(res); + +        for (String table : tables) { +            assertEquals(actual.getTable(table), expected.getTable(table)); +        } +    } + +    @Before +    public void setUp() throws Exception { +        IDataSet dataSet = getDataSet(); + +        dbTester = new DefaultDatabaseTester(getConnection()); +        getOperationListener().connectionRetrieved(getConnection()); + +        dbTester.setSetUpOperation(DatabaseOperation.CLEAN_INSERT); +        dbTester.setTearDownOperation(DatabaseOperation.REFRESH); +        dbTester.setDataSet(dataSet); +        dbTester.setOperationListener(getOperationListener()); +        dbTester.onSetup(); +    } + +    @After +    public void tearDown() throws Exception { +        try { +            dbTester.onTearDown(); +            getConnection().close(); +        } finally { +            dbTester = null; +        } +    } +} diff --git a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/vehicle/CarAddTestService.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/vehicle/CarAddTestService.java deleted file mode 100644 index de7a26a..0000000 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/vehicle/CarAddTestService.java +++ /dev/null @@ -1,283 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.vehicle; - -import static junit.framework.TestCase.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.VehicleDAO; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.VehicleDatabaseDao; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.VehicleService; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.VehicleServiceImpl; -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 org.junit.Test; - -public class CarAddTestService { -    private final VehicleDAO vehicleP = mock(VehicleDatabaseDao.class); -    private final VehicleService vehicleService = new VehicleServiceImpl(vehicleP); - -    public CarAddTestService() throws PersistenceException { -        when(vehicleP.add(any())).thenReturn(1L); -    } - -    @Test -    public void testValidVehicleH() { -        Vehicle vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.HOCHDACH) -                        .type(Vehicle.VehicleType.RTW) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (InvalidVehicleException | ServiceException e) { -            fail(); -        } -        vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.HOCHDACH) -                        .type(Vehicle.VehicleType.KTW) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (InvalidVehicleException | ServiceException e) { -            fail(); -        } -        vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.HOCHDACH) -                        .type(Vehicle.VehicleType.KTW_B) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (InvalidVehicleException | ServiceException e) { -            fail(); -        } -        vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.HOCHDACH) -                        .type(Vehicle.VehicleType.BKTW) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (InvalidVehicleException | ServiceException e) { -            fail(); -        } -    } - -    @Test -    public void testValidVehicleM() { -        Vehicle vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH) -                        .type(Vehicle.VehicleType.KTW) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (InvalidVehicleException | ServiceException e) { -            fail(); -        } -        vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH) -                        .type(Vehicle.VehicleType.KTW_B) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (InvalidVehicleException | ServiceException e) { -            fail(); -        } -        vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH) -                        .type(Vehicle.VehicleType.BKTW) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (InvalidVehicleException | ServiceException e) { -            fail(); -        } -    } - -    @Test -    public void testValidVehicleN() { -        Vehicle vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.NORMAL) -                        .type(Vehicle.VehicleType.BKTW) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (InvalidVehicleException | ServiceException e) { -            fail(); -        } -        vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.NORMAL) -                        .type(Vehicle.VehicleType.NEF) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (InvalidVehicleException | ServiceException e) { -            fail(); -        } -        vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.NORMAL) -                        .type(Vehicle.VehicleType.NAH) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (InvalidVehicleException | ServiceException e) { -            fail(); -        } -    } - -    @Test(expected = InvalidVehicleException.class) -    public void testInvalidVehicleH() throws InvalidVehicleException { -        Vehicle vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.HOCHDACH) -                        .type(Vehicle.VehicleType.NEF) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (ServiceException e) { -            fail(); -        } -        vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.HOCHDACH) -                        .type(Vehicle.VehicleType.NAH) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (ServiceException e) { -            fail(); -        } -    } - -    @Test(expected = InvalidVehicleException.class) -    public void testInvalidVehicleM() throws InvalidVehicleException { -        Vehicle vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH) -                        .type(Vehicle.VehicleType.NEF) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (ServiceException e) { -            fail(); -        } -        vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH) -                        .type(Vehicle.VehicleType.NAH) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (ServiceException e) { -            fail(); -        } -        vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH) -                        .type(Vehicle.VehicleType.RTW) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (ServiceException e) { -            fail(); -        } -    } - -    @Test(expected = InvalidVehicleException.class) -    public void testInvalidVehicleN() throws InvalidVehicleException { -        Vehicle vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.NORMAL) -                        .type(Vehicle.VehicleType.RTW) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (ServiceException e) { -            fail(); -        } -        vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.NORMAL) -                        .type(Vehicle.VehicleType.KTW_B) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (ServiceException e) { -            fail(); -        } -        vehicle = -                Vehicle.builder() -                        .constructionType(Vehicle.ConstructionType.NORMAL) -                        .type(Vehicle.VehicleType.KTW) -                        .hasNef(true) -                        .status(Vehicle.Status.ABGEMELDET) -                        .name("") -                        .build(); -        try { -            vehicleService.add(vehicle); -        } catch (ServiceException e) { -            fail(); -        } -    } -} diff --git a/src/test/resources/EmployeePersistenceTestBaseData.xml b/src/test/resources/EmployeePersistenceTestBaseData.xml new file mode 100644 index 0000000..a9553a2 --- /dev/null +++ b/src/test/resources/EmployeePersistenceTestBaseData.xml @@ -0,0 +1,12 @@ +<dataset> +<EmployeeVersion id="10" name="Adam" birthday="2010-10-10" educationlevel="RS" isDriver="true" +  isPilot="false"/> +<EmployeeVersion id="20" name="Max" birthday="1990-11-11" educationlevel="NFS" isDriver="false" +  isPilot="false"/> +<EmployeeVersion id="30" name="Lisa" birthday="1999-10-16" educationlevel="NKI" isDriver="true" +  isPilot="false"/> + +<Employee id="1" version="10" /> +<Employee id="2" version="20" /> +<Employee id="3" version="30" /> +</dataset>
\ No newline at end of file diff --git a/src/test/resources/operationDAOUpdateNormal.xml b/src/test/resources/operationDAOUpdateNormal.xml new file mode 100644 index 0000000..025cdc2 --- /dev/null +++ b/src/test/resources/operationDAOUpdateNormal.xml @@ -0,0 +1,19 @@ +<dataset> +  <Operation id="1" opCode="RD-2B0M" severity="B" created="2000-01-01" +    destination="New description" status="ACTIVE" additionalInfo="Test"/> + +  <VehicleVersion id="1" name="RTW-1" constructionType="HOCHDACH" type="RTW" hasNef="true"/> +  <VehicleVersion id="2" name="KTW-1" constructionType="HOCHDACH" type="KTW" hasNef="true"/> +  <VehicleVersion id="3" name="KTW-2" constructionType="MITTELHOCHDACH" type="KTW_B" hasNef="false"/> +  <VehicleVersion id="4" name="BKTW-2" constructionType="HOCHDACH" type="BKTW" hasNef="false"/> +  <VehicleVersion id="5" name="NEF-1" constructionType="NORMAL" type="NEF" hasNef="true"/> + +  <Vehicle id="1" version="1" status="FREI_FUNK"/> +  <Vehicle id="2" version="2" status="FREI_WACHE"/> +  <Vehicle id="3" version="3" status="FREI_FUNK"/> +  <Vehicle id="4" version="4" status="FREI_WACHE"/> + +  <VehicleOperation vehicleId="1" operationId="1"/> +  <VehicleOperation vehicleId="2" operationId="1"/> +  <VehicleOperation vehicleId="3" operationId="1"/> +</dataset> diff --git a/src/test/resources/operationDAOUpdateRemoveVehicles.xml b/src/test/resources/operationDAOUpdateRemoveVehicles.xml new file mode 100644 index 0000000..6f171b4 --- /dev/null +++ b/src/test/resources/operationDAOUpdateRemoveVehicles.xml @@ -0,0 +1,17 @@ +<dataset> +  <Operation id="1" opCode="RD-2B0M" severity="B" created="2000-01-01" +    destination="New description" status="ACTIVE" additionalInfo="Test"/> + +  <VehicleVersion id="1" name="RTW-1" constructionType="HOCHDACH" type="RTW" hasNef="true"/> +  <VehicleVersion id="2" name="KTW-1" constructionType="HOCHDACH" type="KTW" hasNef="true"/> +  <VehicleVersion id="3" name="KTW-2" constructionType="MITTELHOCHDACH" type="KTW_B" hasNef="false"/> +  <VehicleVersion id="4" name="BKTW-2" constructionType="HOCHDACH" type="BKTW" hasNef="false"/> +  <VehicleVersion id="5" name="NEF-1" constructionType="NORMAL" type="NEF" hasNef="true"/> + +  <Vehicle id="1" version="1" status="FREI_FUNK"/> +  <Vehicle id="2" version="2" status="FREI_WACHE"/> +  <Vehicle id="3" version="3" status="FREI_FUNK"/> +  <Vehicle id="4" version="4" status="FREI_WACHE"/> + +  <VehicleOperation /> +</dataset> diff --git a/src/test/resources/operationDAOUpdateSetup.xml b/src/test/resources/operationDAOUpdateSetup.xml new file mode 100644 index 0000000..23d1a25 --- /dev/null +++ b/src/test/resources/operationDAOUpdateSetup.xml @@ -0,0 +1,17 @@ +<dataset> +  <Operation id="1" opCode="ALP-95E7" severity="E" created="2000-01-01" +    destination="Wiedner Hauptstraße 35, Wien" status="ACTIVE"/> + +  <VehicleVersion id="1" name="RTW-1" constructionType="HOCHDACH" type="RTW" hasNef="true"/> +  <VehicleVersion id="2" name="KTW-1" constructionType="HOCHDACH" type="KTW" hasNef="true"/> +  <VehicleVersion id="3" name="KTW-2" constructionType="MITTELHOCHDACH" type="KTW_B" hasNef="false"/> +  <VehicleVersion id="4" name="BKTW-2" constructionType="HOCHDACH" type="BKTW" hasNef="false"/> +  <VehicleVersion id="5" name="NEF-1" constructionType="NORMAL" type="NEF" hasNef="true"/> + +  <Vehicle id="1" version="1" status="FREI_FUNK"/> +  <Vehicle id="2" version="2" status="FREI_WACHE"/> +  <Vehicle id="3" version="3" status="FREI_FUNK"/> +  <Vehicle id="4" version="4" status="FREI_WACHE"/> + +  <VehicleOperation /> +</dataset> diff --git a/src/test/resources/testAddValidEmployeeJoin_expected.xml b/src/test/resources/testAddValidEmployeeJoin_expected.xml new file mode 100644 index 0000000..0977a95 --- /dev/null +++ b/src/test/resources/testAddValidEmployeeJoin_expected.xml @@ -0,0 +1,17 @@ +<dataset> +  <EMP_JOIN e_id="1" e_version="10" v_id="10" v_name="Adam" v_birthday="2010-10-10" +    v_educationlevel="RS" v_isDriver="true" +    v_isPilot="false"/> +  <EMP_JOIN e_id="2" e_version="20" v_id="20" v_name="Max" v_birthday="1990-11-11" +    v_educationlevel="NFS" +    v_isDriver="false" +    v_isPilot="false"/> +  <EMP_JOIN e_id="3" e_version="30" v_id="30" v_name="Lisa" v_birthday="1999-10-16" +    v_educationlevel="NKI" +    v_isDriver="true" +    v_isPilot="false"/> +  <EMP_JOIN e_id="4" e_version="40" v_id="40" v_name="Testperson" v_birthday="2010-11-11" +    v_educationlevel="NA" +    v_isDriver="true" +    v_isPilot="false"/> +</dataset>
\ No newline at end of file diff --git a/src/test/resources/testAddValidEmployee_expected.xml b/src/test/resources/testAddValidEmployee_expected.xml new file mode 100644 index 0000000..41ecf4e --- /dev/null +++ b/src/test/resources/testAddValidEmployee_expected.xml @@ -0,0 +1,16 @@ +<dataset> +  <EmployeeVersion id="10" name="Adam" birthday="2010-10-10" educationlevel="RS" isDriver="true" +    isPilot="false"/> +  <EmployeeVersion id="20" name="Max" birthday="1990-11-11" educationlevel="NFS" isDriver="false" +    isPilot="false"/> +  <EmployeeVersion id="30" name="Lisa" birthday="1999-10-16" educationlevel="NKI" isDriver="true" +    isPilot="false"/> +  <EmployeeVersion id="40" name="Testperson" birthday="2010-11-11" educationlevel="NA" +    isDriver="true" +    isPilot="false"/> + +  <Employee id="1" version="10"/> +  <Employee id="2" version="20"/> +  <Employee id="3" version="30"/> +  <Employee id="4" version="40"/> +</dataset>
\ No newline at end of file diff --git a/src/test/resources/employeeServiceTestData.xml b/src/test/resources/testUpdateValidEmployee_expected.xml index c21fde6..4a35a7b 100644 --- a/src/test/resources/employeeServiceTestData.xml +++ b/src/test/resources/testUpdateValidEmployee_expected.xml @@ -5,8 +5,10 @@      isPilot="false"/>    <EmployeeVersion id="30" name="Lisa" birthday="1999-10-16" educationlevel="NKI" isDriver="true"      isPilot="false"/> +  <EmployeeVersion id="31" name="Lisa" birthday="1999-10-16" educationlevel="NKA" isDriver="true" +    isPilot="true"/> -  <Employee id="1" version="10" /> -  <Employee id="2" version="20" /> -  <Employee id="3" version="30" /> +  <Employee id="1" version="10"/> +  <Employee id="2" version="20"/> +  <Employee id="3" version="31"/>  </dataset>
\ No newline at end of file diff --git a/src/test/resources/vehicleTestData.xml b/src/test/resources/vehicleTestData.xml new file mode 100644 index 0000000..c3f2e79 --- /dev/null +++ b/src/test/resources/vehicleTestData.xml @@ -0,0 +1,10 @@ +<dataset> +  <VehicleVersion id="10" name="RTW-1" constructionType="HOCHDACH" type="RTW" hasNEF="true"/> +  <VehicleVersion id="20" name="KTW-2" constructionType="MITTELHOCHDACH" type="KTW" hasNEF="false"/> +  <VehicleVersion id="30" name="NEF-3" constructionType="NORMAL" type="NEF" hasNEF="false"/> + + +  <Vehicle id="1" version="10" status="ABGEMELDET"/> +  <Vehicle id="2" version="20" status="FREI_WACHE"/> +  <Vehicle id="3" version="30" status="FREI_FUNK"/> +</dataset>
\ No newline at end of file diff --git a/src/test/resources/vehicleTestUpdateExpectedData.xml b/src/test/resources/vehicleTestUpdateExpectedData.xml new file mode 100644 index 0000000..861880b --- /dev/null +++ b/src/test/resources/vehicleTestUpdateExpectedData.xml @@ -0,0 +1,10 @@ +<dataset> +  <VehicleVersion id="10" name="RTW-1" constructionType="HOCHDACH" type="RTW" hasNEF="true"/> +  <VehicleVersion id="20" name="KTW-2" constructionType="MITTELHOCHDACH" type="KTW" hasNEF="false"/> +  <VehicleVersion id="30" name="NEF-3" constructionType="NORMAL" type="NEF" hasNEF="false"/> +  <VehicleVersion id="40" name="RTW-4" constructionType="HOCHDACH" type="RTW" hasNEF="true"/> + +  <Vehicle id="1" version="10" status="ABGEMELDET"/> +  <Vehicle id="2" version="40" status="ABGEMELDET"/> +  <Vehicle id="3" version="30" status="FREI_FUNK"/> +</dataset>
\ No newline at end of file | 
