diff options
76 files changed, 3034 insertions, 909 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 @@ -10,52 +10,48 @@ Projektbeschreibung ## Projektteam -* **Rolle:** Teamkoordinator/Testleiter Stv.\ - **Name:** Weick, Martin\ +* **Rolle:** Teamkoordinator/Testleiter Stv. + **Name:** Weick, Martin **Matrikelnummer:** e01627760 -* **Rolle:** Testleiter/Teamkoordinator Stv.\ - **Name:** Rogetzer, Dominic\ +* **Rolle:** Testleiter/Teamkoordinator Stv. + **Name:** Rogetzer, Dominic **Matrikelnummer:** e01627756 -* **Rolle:** Technischer Architekt/Git Koordinator\ - **Name:** Gschwantner, Thomas\ +* **Rolle:** Technischer Architekt/Git Koordinator + **Name:** Gschwantner, Thomas **Matrikelnummer:** e01625751 -* **Rolle:** UX-Designer/Technischer Architekt Stv.\ - **Name:** Weninger, Andreas\ +* **Rolle:** UX-Designer/Technischer Architekt Stv. + **Name:** Weninger, Andreas **Matrikelnummer:** e01526989 -* **Rolle:** Dokumentationsbeauftragter/Kommunikationsbeauftragter Stv.\ - **Name:** Kehrer, Felix\ +* **Rolle:** Dokumentationsbeauftragter/Kommunikationsbeauftragter Stv. + **Name:** Kehrer, Felix **Matrikelnummer:** e01526278 -* **Rolle:** Kommunikationsbeauftragte/Dokumentationsbeauftragte Stv./UX-Designer Stv.\ - **Name:** Pundy, Viktoria\ +* **Rolle:** Kommunikationsbeauftragte/Dokumentationsbeauftragte Stv./UX-Designer Stv. + **Name:** Pundy, Viktoria **Matrikelnummer:** e01633403 ## Kurzanleitung -* Das Programm kann mit dem Befehl:\ - ```mvnw compile```\ +* Das Programm kann mit dem Befehl: + ```mvnw compile``` gebaut werden können. -* Das Programm kann mit dem Befehl:\ - ```mvnw test```\ +* Das Programm kann mit dem Befehl: + ```mvnw test``` getestet werden können. -* Das Programm kann mit dem Befehl:\ - ```mvnw exec:java```\ +* Das Programm kann mit dem Befehl: + ```mvnw exec:java``` ausgeführt werden. -* Das Programm kann mit dem Befehl:\ - ```mvnw package```\ +* Das Programm kann mit dem Befehl: + ```mvnw package``` als ausführbares jar-File packetiert werden. -* Das Programm kann mit dem Befehl:\ - ```mvnw package```\ - als ausführbares jar-File packetiert werden. - -* Das Programm kann mit dem Befehl:\ - ```mvnw clean verify && java -jar ./target/*.jar```\ +* Das Programm kann mit dem Befehl: + ```mvnw clean verify && java -jar ./target/*.jar``` als ausführbares jar-File packetiert, verifiziert und ausgeführt werden. 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..e88e640 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,10 +35,14 @@ 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; @@ -62,6 +71,7 @@ public class CreateCarController { .map(Enum::toString) .collect(Collectors.toList()))); cmb_typ.setValue(VehicleType.BKTW.toString()); + vehicleListFP(); } @FXML @@ -71,27 +81,64 @@ public class CreateCarController { @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; + + 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..99614d0 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,37 +5,49 @@ 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; @@ -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(); + if (consumerCancelClicked != null) { + consumerCancelClicked.run(); + } } @FXML public 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/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..0d2f894 --- /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 + public void onAddEmployeeClicked() { + if (consumerAddEmployeeClicked != null) { + consumerAddEmployeeClicked.run(); + } + } + + @FXML + public 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..038b14c --- /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 + public 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/RegistrationWindowController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/RegistrationWindowController.java index bf413bb..9ed6147 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; @@ -78,7 +80,7 @@ public class RegistrationWindowController { public 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 +94,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) { @@ -147,7 +149,7 @@ public class RegistrationWindowController { public void create() { LOG.debug("Create Button clicked"); - List<Registration> registrations = new LinkedList<>(); + Set<Registration> registrations = new HashSet<>(); for (Employee employee : chosenEmployees) { registrations.add( diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java index 672424a..773ccb6 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java @@ -1,23 +1,68 @@ package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel; import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity; import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; +import java.lang.invoke.MethodHandles; +import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.util.EnumSet; +import java.util.HashSet; +import java.util.LinkedList; import java.util.List; +import java.util.Objects; +import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Repository; +@Repository public class DBOperationDAO implements OperationDAO { private JDBCConnectionManager jdbcConnectionManager; + private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); public DBOperationDAO(JDBCConnectionManager j) { jdbcConnectionManager = j; + try { + + getVehicleId = jdbcConnectionManager.getConnection().prepareStatement(GET_VEHICLE_ID); + + getVehicle = jdbcConnectionManager.getConnection().prepareStatement(GET_VEHICLE); + + getVehicleVersion = + jdbcConnectionManager.getConnection().prepareStatement(GET_VEHICLE_VERSION); + + getRegistrations = + jdbcConnectionManager.getConnection().prepareStatement(GET_REGISTRATIONS); + + getEmployee = jdbcConnectionManager.getConnection().prepareStatement(GET_EMPLOYEE); + + getEmployeeVersion = + jdbcConnectionManager.getConnection().prepareStatement(GET_EMPLOYEE_VERSION); + + } catch (SQLException e) { + + LOG.error( + "SQLException occurred while preparing Statements. Error message: {} ", + e.getMessage()); + + // TODO: nothing should be thrown here + throw new IllegalStateException("TODO: fix me"); + // throw new PersistenceException(e); + } } @Override @@ -66,7 +111,7 @@ public class DBOperationDAO implements OperationDAO { }*/ pstmt.setString(2, operation.severity().name()); if (operation.created() != null) { - pstmt.setTimestamp(3, Timestamp.from(operation.created())); + pstmt.setTimestamp(3, Timestamp.from(Objects.requireNonNull(operation.created()))); } else { throw new PersistenceException("Zeitpunkt der Erstellung darf nicht null sein!"); } @@ -110,7 +155,49 @@ public class DBOperationDAO implements OperationDAO { } @Override - public void update(Operation operation) throws ElementNotFoundException, PersistenceException {} + public void update(Operation o) throws ElementNotFoundException, PersistenceException { + String sql = + "UPDATE Operation SET opCode = ?, severity = ?, destination = ?," + + " additionalInfo = ?, status = ? WHERE id = ?"; + String sql2 = "DELETE FROM VehicleOperation WHERE operationId = ?"; + String sql3 = "INSERT INTO VehicleOperation(vehicleId, operationId) VALUES (?, ?)"; + + try { + Connection con = jdbcConnectionManager.getConnection(); + con.setAutoCommit(false); + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setString(1, o.opCode()); + pstmt.setInt(2, o.severity().ordinal()); + pstmt.setString(3, o.destination()); + pstmt.setString(4, o.additionalInfo()); + pstmt.setInt(5, o.status().ordinal()); + pstmt.setLong(6, o.id()); + + if (pstmt.executeUpdate() != 1) + throw new ElementNotFoundException("No such operationId exists: " + pstmt); + } + + try (PreparedStatement pstmt = con.prepareStatement(sql2)) { + pstmt.setLong(1, o.id()); + pstmt.executeUpdate(); + } + + try (PreparedStatement pstmt = con.prepareStatement(sql3)) { + pstmt.setLong(2, o.id()); + + for (long id : (Iterable<Long>) o.vehicles().stream().map(Vehicle::id)::iterator) { + pstmt.setLong(1, id); + pstmt.addBatch(); + } + + pstmt.executeBatch(); + } + con.commit(); + con.setAutoCommit(true); + } catch (SQLException e) { + throw new PersistenceException(e); + } + } @Override public Operation get(long operationId) throws ElementNotFoundException, PersistenceException { @@ -118,8 +205,189 @@ public class DBOperationDAO implements OperationDAO { } @Override - public List<Operation> list(EnumSet<Status> statuses) throws PersistenceException { - return null; + public Set<Operation> list(EnumSet<Status> statuses) throws PersistenceException { + String sql = "SELECT * FROM Operation WHERE status IN (?)"; + 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("INTEGER", 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 { + return Operation.builder() + .id(rs.getLong("id")) + .opCode(rs.getString("opCode")) + .severity(Severity.valueOf(rs.getString("severity"))) + .status(Status.valueOf(rs.getString("status"))) + .vehicles(getVehiclesFromOperationId(rs.getLong("id"))) + .created(rs.getTimestamp("created").toInstant()) + .destination(rs.getString("destination")) + .additionalInfo(rs.getString("additionalInfo")) + .build(); + } + + private static String GET_VEHICLE_ID = + "SELECT vehicleId FROM VehicleOperation WHERE operationId = ? ;"; + + private final PreparedStatement getVehicleId; + + private Set<Vehicle> getVehiclesFromOperationId(long operationId) throws PersistenceException { + Set<Vehicle> vehicles = new HashSet<>(); + try { + getVehicleId.setLong(1, operationId); + try (ResultSet resultSet = getVehicleId.executeQuery()) { + while (resultSet.next()) { + vehicles.add(getVehicle(resultSet.getLong("vehicleId"))); + } + } + } catch (SQLException e) { + LOG.error( + "SQLException occurred while getting VehicleId from OperationId. Error message: {}", + e.getMessage()); + throw new PersistenceException(e); + } + return vehicles; + } + + private static String GET_VEHICLE = "SELECT * FROM Vehicle WHERE id = ? ;"; + + private final PreparedStatement getVehicle; + + private Vehicle getVehicle(long vehicleId) throws PersistenceException { + try { + getVehicle.setLong(1, vehicleId); + try (ResultSet resultSet = getVehicle.executeQuery()) { + resultSet.next(); + return getVehicleVersion( + resultSet.getLong("id"), + resultSet.getLong("version"), + resultSet.getString("status")); + } + } catch (SQLException e) { + LOG.error( + "SQLException occurred while getting Vehicle by id. Error message: {}", + e.getMessage()); + throw new PersistenceException(e); + } + } + + private static String GET_VEHICLE_VERSION = "SELECT * FROM VehicleVersion WHERE id = ? ;"; + + private final PreparedStatement getVehicleVersion; + + private Vehicle getVehicleVersion(long vehicleId, long versionId, String status) + throws PersistenceException { + try { + getVehicleVersion.setLong(1, versionId); + try (ResultSet resultSet = getVehicleVersion.executeQuery()) { + resultSet.next(); + return Vehicle.builder() + .id(vehicleId) + .name(resultSet.getString("name")) + .constructionType( + ConstructionType.valueOf(resultSet.getString("constructionType"))) + .type(VehicleType.valueOf(resultSet.getString("type"))) + .status(Vehicle.Status.valueOf(status)) + .hasNef(resultSet.getBoolean("hasNef")) + .registrations(getRegistrations(vehicleId)) + .build(); + } + } catch (SQLException e) { + LOG.error( + "SQLException occurred while getting VehicleVersion. Error message: {}", + e.getMessage()); + throw new PersistenceException(e); + } + } + + private static String GET_REGISTRATIONS = "SELECT * FROM Registration WHERE id = ? ;"; + + private final PreparedStatement getRegistrations; + + private List<Registration> getRegistrations(long vehicleId) throws PersistenceException { + List<Registration> registrations = new LinkedList<>(); + try { + getRegistrations.setLong(1, vehicleId); + try (ResultSet resultSet = getRegistrations.executeQuery()) { + while (resultSet.next()) { + long registrationId = resultSet.getLong("id"); + registrations.add( + Registration.builder() + .id(registrationId) + .start(resultSet.getTimestamp("start").toInstant()) + .end(resultSet.getTimestamp("end").toInstant()) + .employee(getEmployee(resultSet.getLong("employeeId"))) + .build()); + } + } + } catch (SQLException e) { + LOG.error( + "SQLException occurred while getting Registration. Error message: {}", + e.getMessage()); + throw new PersistenceException(e); + } + return registrations; + } + + private static String GET_EMPLOYEE = "SELECT version FROM Employee WHERE id = ? ;"; + + private final PreparedStatement getEmployee; + + private Employee getEmployee(long employeeId) throws PersistenceException { + try { + getEmployee.setLong(1, employeeId); + try (ResultSet resultSet = getEmployee.executeQuery()) { + resultSet.next(); + return getEmployeeVersion(employeeId, resultSet.getLong("version")); + } + } catch (SQLException e) { + LOG.error( + "SQLException occurred while getting Employee. Error message: {}", + e.getMessage()); + throw new PersistenceException(e); + } + } + + private static String GET_EMPLOYEE_VERSION = "SELECT * FROM EmployeeVersion WHERE id = ? ;"; + + private final PreparedStatement getEmployeeVersion; + + private Employee getEmployeeVersion(long employeeId, long versionId) + throws PersistenceException { + try { + getEmployeeVersion.setLong(1, versionId); + try (ResultSet resultSet = getEmployeeVersion.executeQuery()) { + resultSet.next(); + return Employee.builder() + .id(employeeId) + .name(resultSet.getString("name")) + .birthday(resultSet.getDate("birthday").toLocalDate()) + .educationLevel( + EducationLevel.valueOf(resultSet.getString("educationLevel"))) + .isDriver(resultSet.getBoolean("isDriver")) + .isPilot(resultSet.getBoolean("isPilot")) + .build(); + } + } catch (SQLException e) { + LOG.error( + "SQLException occurred while getting EmployeeVersion. Error message: {}", + e.getMessage()); + throw new PersistenceException(e); + } } @Override @@ -136,13 +404,6 @@ public class DBOperationDAO implements OperationDAO { 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 { @@ -155,7 +416,6 @@ public class DBOperationDAO implements OperationDAO { } } } - 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 index 3e4ba12..40a9134 100644 --- 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 @@ -6,13 +6,15 @@ import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundExceptio 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.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Repository; @@ -29,15 +31,21 @@ public class EmployeeDatabaseDao implements EmployeeDAO { "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; + private final PreparedStatement insertEmployeeVersion, + insertEmployee, + listEmployee, + updateEmployee; + + private final Connection connection; public EmployeeDatabaseDao(JDBCConnectionManager connectionManager) throws PersistenceException { try { - final var connection = connectionManager.getConnection(); + connection = connectionManager.getConnection(); insertEmployeeVersion = connection.prepareStatement( INSERT_EMPLOYEE_VERSION, Statement.RETURN_GENERATED_KEYS); @@ -46,6 +54,8 @@ public class EmployeeDatabaseDao implements EmployeeDAO { listEmployee = connection.prepareStatement(LIST_EMPLOYEE); + updateEmployee = connection.prepareStatement(UPDATE_EMPLOYEE); + } catch (SQLException e) { throw new PersistenceException(e); } @@ -55,7 +65,10 @@ public class EmployeeDatabaseDao implements EmployeeDAO { 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())); @@ -72,29 +85,88 @@ public class EmployeeDatabaseDao implements EmployeeDAO { ResultSet resultSetEmployee = insertEmployee.getGeneratedKeys(); if (resultSetEmployee.next()) { + connection.commit(); return resultSetEmployee.getLong(1); } } - throw new PersistenceException("Employee was not created"); + 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 { - throw new UnsupportedOperationException(); + + 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(); + 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 List<Employee> list() throws PersistenceException { + public Set<Employee> list() throws PersistenceException { try { ResultSet rs = listEmployee.executeQuery(); - List<Employee> employees = new ArrayList<>(); + Set<Employee> employees = new HashSet<>(); while (rs.next()) { Employee employee = 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..da90cc8 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,7 @@ 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; + Set<Operation> list(EnumSet<Status> statuses) throws PersistenceException; int connectVehicleToOperation(long vehicleID, long operationID) throws PersistenceException; } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/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..13aeffc 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 @@ -10,8 +10,8 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; -import java.util.LinkedList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -47,9 +47,9 @@ 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) { 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 index ca1d45c..796dd7b 100644 --- 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 @@ -7,11 +7,13 @@ import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.Veh 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.util.LinkedList; -import java.util.List; +import java.sql.Statement; +import java.util.HashSet; +import java.util.Set; import org.springframework.stereotype.Repository; @Repository @@ -27,121 +29,181 @@ public class VehicleDatabaseDao implements VehicleDAO { 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 { + 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(); - ResultSet keyResultSet = p1.getGeneratedKeys(); + p1.executeUpdate(); + + try (ResultSet keyResultSet = p1.getGeneratedKeys()) { + + if (keyResultSet.next()) { + id = keyResultSet.getInt(1); + } + } - if (keyResultSet.next()) { - id = keyResultSet.getInt(1); + name = vehicle.type().name() + "-" + id; } - 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, id); + p3.executeUpdate(); + } - } catch (SQLException e) { - throw new PersistenceException("SQL Excpetion : " + e.toString()); - } finally { - try { - p1.close(); + try (PreparedStatement p2 = connection.prepareStatement(query2)) { - } catch (SQLException e) { - throw new PersistenceException("SQL Excpetion : " + e.toString()); + p2.setInt(1, id); + p2.setString(2, status); + p2.executeUpdate(); } - } - try { - query1 = "UPDATE VehicleVersion SET name=? WHERE id=?"; - p3 = jdbcConnectionManager.getConnection().prepareStatement(query1); - p3.setString(1, name); - p3.setInt(2, id); - p3.executeUpdate(); + connection.commit(); + connection.setAutoCommit(true); } catch (SQLException e) { - throw new PersistenceException("SQL Excpetion : " + e.toString()); - } finally { - try { - p3.close(); - } catch (SQLException e) { - throw new PersistenceException("SQL Excpetion : " + e.toString()); - } + throw new PersistenceException(e); } + return id; + } + + @Override + public void update(Vehicle vehicle) throws ElementNotFoundException, PersistenceException { + String query = "SELECT id FROM vehicle WHERE version=?"; + + long vehicleID = -1; + long vehicleVersion = -1; 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()); + 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(1); + } + } + } + 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() + "-" + vehicleVersion; + + 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); } - return id; } @Override - public void update(Vehicle vehicle) throws ElementNotFoundException, PersistenceException {} + public Set<Vehicle> list() throws PersistenceException { + Set<Vehicle> result = new HashSet<>(); - @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"); + String sql = + "Select * from VehicleVersion, Vehicle where VehicleVersion.id=Vehicle.version"; + + try (PreparedStatement pstmt = + jdbcConnectionManager.getConnection().prepareStatement(sql)) { 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); + 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); - } 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 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); + ResultSet rs = pstmt.executeQuery()) { + pstmt.setLong(1, id); + + 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 { + return Vehicle.builder() + .id(rs.getLong("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")) + .build(); + } } 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..7d91c88 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 @@ -30,13 +30,14 @@ public abstract class Operation { 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 +54,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..98a2068 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; /** @@ -56,7 +56,7 @@ public interface OperationService { * @throws InvalidOperationException if the operationId is invalid or does not exist * @throws ServiceException if loading the stored vehicles failed */ - SortedList<Vehicle> rankVehicles(long operationId) + SortedSet<Vehicle> rankVehicles(long operationId) 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 ce5613e..74d6457 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,6 +1,7 @@ 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; @@ -10,22 +11,35 @@ 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.PersistenceException; import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.lang.invoke.MethodHandles; +import java.time.Instant; import java.util.EnumSet; -import java.util.List; -import javafx.collections.transformation.SortedList; +import java.util.HashSet; +import java.util.Set; +import java.util.SortedSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +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 VehicleDAO vehicleDAO; + + public OperationServiceImpl(OperationDAO operationDAO, VehicleDAO vehicleDAO) { + this.operationDAO = operationDAO; + this.vehicleDAO = vehicleDAO; } @Override public long add(Operation operation) throws InvalidOperationException, ServiceException { - List<Vehicle> vehicles = operation.vehicles(); + Set<Vehicle> vehicles = operation.vehicles(); boolean rtw = false; if (faultyInput(operation.opCode())) { throw new InvalidOperationException("Code ist ungültig!"); @@ -84,7 +98,7 @@ public class OperationServiceImpl implements OperationService { } operation = operation.toBuilder().status(Status.ACTIVE).build(); - long operationId = -1; + long operationId; try { operationId = operationDAO.add(operation); } catch (PersistenceException e) { @@ -112,8 +126,72 @@ public class OperationServiceImpl implements OperationService { } @Override - public void requestVehicles(long operationId, List<Long> vehicleIds) - throws InvalidOperationException, InvalidVehicleException, ServiceException {} + 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 is invalid"); + Operation o = operationDAO.get(operationId); + validateOperation(o); + + if (o.status() != Status.ACTIVE) + throw new InvalidOperationException( + "Can't request vehicles for a nonactive operation"); + + if (!o.status().equals(Status.ACTIVE)) + throw new InvalidOperationException("Can't add vehicles to a nonactive operation"); + + for (Long id : vehicleIds) { + if (id <= 0) throw new InvalidVehicleException("VehicleId is invalid"); + + try { + Vehicle v = vehicleDAO.get(id); + if (v.status() == Vehicle.Status.ABGEMELDET) + throw new InvalidVehicleException("Can't request nonactive vehicles"); + + vs.add(v); + } catch (ElementNotFoundException e) { + throw new InvalidVehicleException("VehicleId does not exist"); + } + } + + vs.addAll(o.vehicles()); + if (vs.equals(o.vehicles())) return; + + operationDAO.update(o.toBuilder().vehicles(vs).build()); + } catch (ElementNotFoundException e) { + throw new InvalidOperationException("No such operationId exists"); + } catch (PersistenceException e) { + throw new ServiceException(e); + } + } + + private static final Pattern opCodePattern = Pattern.compile("(?:\\w{1,3}-\\d{0,2})(.)(?:.*)"); + + private void validateOperation(Operation o) throws InvalidOperationException { + if (o.id() <= 0) throw new InvalidOperationException("Id is invalid"); + + if (o.opCode().trim().isEmpty()) throw new InvalidOperationException("opCode is invalid"); + + Matcher m = opCodePattern.matcher(o.opCode()); + if (!m.matches()) throw new InvalidOperationException("opCode is invalid"); + + if (!m.group(1).equals(o.severity().toString())) + throw new InvalidOperationException("Severity is invalid"); + + if (o.vehicles().isEmpty()) + throw new InvalidOperationException("No vehicles assigned to operation"); + + Instant created = o.created(); + if (created == null) throw new InvalidOperationException("Created can't be empty"); + + if (created.isAfter(Instant.now())) + throw new InvalidOperationException("Vehicle was created in the future"); + + if (o.destination().trim().isEmpty()) + throw new InvalidOperationException("Destination can't be empty"); + } @Override public void complete(long operationId, Status status) @@ -137,13 +215,20 @@ public class OperationServiceImpl implements OperationService { } @Override - public SortedList<Vehicle> rankVehicles(long operationId) + public SortedSet<Vehicle> rankVehicles(long operationId) throws InvalidOperationException, ServiceException { return null; } @Override - public List<Operation> list(EnumSet<Status> statuses) throws ServiceException { - return null; + public Set<Operation> list(EnumSet<Status> statuses) throws ServiceException { + try { + return operationDAO.list(statuses); + } catch (PersistenceException e) { + LOG.debug( + "Caught PersistenceException. Throwing ServiceException. Message: {}", + e.getMessage()); + throw new ServiceException(e); + } } } 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..47a2520 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,11 +4,12 @@ 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; @@ -69,17 +70,60 @@ public class VehicleServiceImpl implements VehicleService { } public Vehicle update(Vehicle vehicle) throws InvalidVehicleException, ServiceException { - throw new UnsupportedOperationException(); + switch (vehicle.type()) { + case RTW: + if (vehicle.constructionType() == ConstructionType.NORMAL) { + throw new InvalidVehicleException("RTW darf kein Normales Dach haben"); + } else if (vehicle.constructionType() == ConstructionType.MITTELHOCHDACH) { + throw new InvalidVehicleException("RTW darf kein Mittelhochdach haben"); + } + break; + case KTW: + if (vehicle.constructionType() == ConstructionType.NORMAL) { + throw new InvalidVehicleException("KTW darf kein Normales Dach haben"); + } + break; + case KTW_B: + if (vehicle.constructionType() == ConstructionType.NORMAL) { + throw new InvalidVehicleException("KTW-B darf kein Normales Dach haben"); + } + break; + case NEF: + if (vehicle.constructionType() == ConstructionType.MITTELHOCHDACH) { + throw new InvalidVehicleException("NEF darf kein Mittelhochdach haben"); + } else if (vehicle.constructionType() == ConstructionType.HOCHDACH) { + throw new InvalidVehicleException("NEF darf kein Hochdach haben"); + } + break; + case NAH: + if (vehicle.constructionType() == ConstructionType.MITTELHOCHDACH) { + throw new InvalidVehicleException("NEF darf kein Mittelhochdach haben"); + } else if (vehicle.constructionType() == ConstructionType.HOCHDACH) { + throw new InvalidVehicleException("NEF darf kein Hochdach haben"); + } + break; + case BKTW: + break; + default: + throw new ServiceException("not a Valid type"); + } + try { + vehiclePersistence.update(vehicle); + } catch (ElementNotFoundException e) { + throw new ServiceException("Element not found"); + } catch (PersistenceException e) { + throw new ServiceException(e); + } + return vehicle; } @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 +133,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/ui/vehiclepane/VehiclePaneController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/ui/vehiclepane/VehiclePaneController.java index 2db6f37..405eee3 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/ui/vehiclepane/VehiclePaneController.java @@ -5,7 +5,6 @@ import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registratio 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,17 +61,17 @@ 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; @@ -80,5 +89,14 @@ 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, shadowed"); + else rootElement.getStyleClass().add("bg-white, shadowed"); } } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/ArchiveOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/ArchiveOperationController.java new file mode 100644 index 0000000..7b69402 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/ArchiveOperationController.java @@ -0,0 +1,127 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.userInterface; + +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.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 { + + public AnchorPane apDetails; + public Label lblCodeHeader; + public Hyperlink hypBack; + public Label lblOpCode; + public Label lblVehicles; + public Label lblDate; + public Label lblAddress; + public FlowPane fpVehicles; + private OperationService operationService; + public FlowPane archiveOperationFlowPane; + private LinkedList<Operation> list = new LinkedList<>(); + + public ArchiveOperationController() {} + + void setServices(OperationService operationService) { + this.operationService = operationService; + } + + void fillList() { + 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() { + setDetailsVisible(false); + } +} 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 index ea21691..44e28d8 100644 --- 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 @@ -1,39 +1,46 @@ 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.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.OperationServiceImpl; import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.VehicleService; +import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.ui.vehiclepane.VehiclePaneController; 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.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.time.temporal.ChronoUnit; +import java.util.ArrayList; import java.util.EnumSet; import java.util.LinkedList; import java.util.List; -import javafx.collections.FXCollections; +import java.util.Set; import javafx.event.ActionEvent; import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; 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.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.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @Controller @@ -52,10 +59,11 @@ public class CreateOperationController { public LinkedList<Vehicle> chosenVehicles = new LinkedList<>(); public AnchorPane apInvisible; @FXML private OperationDetailsController operationDetailsController; + public FlowPane fpVehicles; - // TODO: Anders? - OperationService operationService = - new OperationServiceImpl(new DBOperationDAO(new JDBCConnectionManager())); + private LinkedList<Vehicle> chosenVehicles = new LinkedList<>(); + + @Autowired private OperationService operationService; private final VehicleService vehicleService; private final SpringFXMLLoader fxmlLoader; @@ -67,88 +75,59 @@ public class CreateOperationController { @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()); - } - } - }); - 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()); - } - } - }); - - 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()); - } - } - }); - lvActiveOperations.setOnMouseClicked( - event -> { - if (event.getClickCount() == 2) { - if (lvActiveOperations.getSelectionModel().getSelectedItem() == null) { - return; - } - openDetailsWindow(lvActiveOperations.getSelectionModel().getSelectedItem()); - } - }); } public void updateList() { try { - this.lvVehicles.setItems( - FXCollections.observableArrayList( - vehicleService.list( - EnumSet.of( - Vehicle.Status.FREI_FUNK, Vehicle.Status.FREI_WACHE)))); - } catch (ServiceException e) { + fpVehicles.getChildren().clear(); + Set<Vehicle> vehicles = vehicleService.list(EnumSet.allOf(Vehicle.Status.class)); + + 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 e) { + LOG.error("Error while updating list.", e); + Alert alert = new Alert(Alert.AlertType.ERROR); alert.setTitle("Fehler"); alert.setHeaderText("Fehler!"); @@ -168,30 +147,72 @@ public class CreateOperationController { } } - /*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; - }*/ + private static 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()); + } 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).build()); + } 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() { @@ -206,7 +227,7 @@ public class CreateOperationController { .created(Instant.now()) .opCode(txtCode.getText()) .status(Status.ACTIVE) - .vehicles(List.of(vehicles)) + .vehicles(Set.of(vehicles)) .severity(Severity.A) .build(); try { @@ -232,13 +253,36 @@ public class CreateOperationController { } public void onEmployeeLinkClicked(ActionEvent actionEvent) { - openNewWindow("createNewEmployee.fxml"); + openNewWindow("listEmployees.fxml"); } public void onVehicleLinkClicked(ActionEvent actionEvent) { openNewWindow("createCar.fxml"); } + public void onArchivLinkClicked() { + openNewArchivWindow(); + } + + private void openNewArchivWindow() { + Stage stage = new Stage(); + try { + FXMLLoader fxmlLoader = + new FXMLLoader(getClass().getResource("/fxml/ArchiveOperation.fxml")); + Parent node = fxmlLoader.load(); + ArchiveOperationController archiveOperationController = fxmlLoader.getController(); + archiveOperationController.setServices(operationService); + archiveOperationController.fillList(); + stage.setScene(new Scene(node)); + } 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(); @@ -261,13 +305,13 @@ public class CreateOperationController { updateList(); } + public void setVisible(boolean b) { + apInvisible.setVisible(!b); + } + private void openDetailsWindow(Operation operation) { operationDetailsController.setControllers(this, operationService, vehicleService); apInvisible.setVisible(true); operationDetailsController.initOperation(operation); } - - void setVisible(boolean b) { - apInvisible.setVisible(!b); - } } diff --git a/src/main/resources/fxml/ArchiveOperation.fxml b/src/main/resources/fxml/ArchiveOperation.fxml new file mode 100644 index 0000000..45d128c --- /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.userInterface.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 99f2e22..dbdb4ef 100644 --- a/src/main/resources/fxml/CreateOperationController.fxml +++ b/src/main/resources/fxml/CreateOperationController.fxml @@ -6,92 +6,73 @@ <?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);" /> - <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" /> - </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.userInterface.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" + 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="12.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/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..a9efaa6 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.ui.vehiclepane.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"> <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.png Binary files differnew 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.png Binary files differnew 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.png Binary files differnew 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.png Binary files differnew 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/EmployeePersistenceTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeePersistenceTest.java new file mode 100644 index 0000000..5536c1c --- /dev/null +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeePersistenceTest.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 EmployeePersistenceTest extends JdbcTestCase { + + private EmployeeDAO employeePersistence; + + public EmployeePersistenceTest() 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..726735d --- /dev/null +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAOTest.java @@ -0,0 +1,81 @@ +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.util.JdbcTestCase; +import java.time.Instant; +import java.util.Collections; +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 OperationDAO operationDAO; + + private final Operation o; + + public OperationDAOTest() { + this.operationDAO = new DBOperationDAO(getJdbcConnectionManager()); + + 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); + } +} 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/einsatzverwaltung/dao/OperationPersistenceTest.java index be612d0..a5e4993 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/operation/OperationPersistenceTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationPersistenceTest.java @@ -1,8 +1,27 @@ -package at.ac.tuwien.sepm.assignment.groupphase.operation; +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; + +import static junit.framework.TestCase.fail; + +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.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; +import java.nio.charset.Charset; +import java.sql.SQLException; +import java.time.Instant; +import java.util.Arrays; +import java.util.Set; +import org.h2.tools.RunScript; +import org.junit.BeforeClass; +import org.junit.Test; public class OperationPersistenceTest { - /*private final OperationDAO operationDAO = + private final OperationDAO operationDAO = new DBOperationDAO(new JDBCConnectionManager("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1")); @BeforeClass @@ -35,7 +54,7 @@ public class OperationPersistenceTest { .destination("Wiedner Hauptstraße 35, Wien") .additionalInfo("HTU Wien") .severity(Severity.B) - .vehicles(List.of(vehicle)) + .vehicles(Set.of(vehicle)) .build(); try { operationDAO.add(operation); @@ -44,7 +63,7 @@ public class OperationPersistenceTest { } } - /*@Test(expected = PersistenceException.class) + @Test(expected = PersistenceException.class) public void addFaultyOperationTest() throws PersistenceException { Vehicle vehicle = Vehicle.builder() @@ -58,16 +77,15 @@ public class OperationPersistenceTest { Operation operation = Operation.builder() .status(Status.ACTIVE) - .opCode("") + .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(List.of(vehicle)) + .vehicles(Set.of(vehicle)) .build(); operationDAO.add(operation); - }*/ - /* + } @Test(expected = PersistenceException.class) public void addFaultyOperation1Test() throws PersistenceException { @@ -94,7 +112,7 @@ public class OperationPersistenceTest { "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)) + .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/RegistrationDatabaseDAOTest.java index 03059ff..09699c5 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/RegistrationDatabaseDAOTest.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; @@ -79,7 +79,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 +139,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/vehicle/CarAddTestService.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/CarAddTestService.java index de7a26a..fd8b43f 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/vehicle/CarAddTestService.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/CarAddTestService.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.sepm.assignment.groupphase.vehicle; +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; import static junit.framework.TestCase.fail; import static org.mockito.ArgumentMatchers.any; @@ -8,8 +8,6 @@ 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; 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..c49cd9d --- /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..70185d3 --- /dev/null +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceTest.java @@ -0,0 +1,175 @@ +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; + +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.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 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; + + @Before + public void setUp() throws ElementNotFoundException, PersistenceException { + v1 = + Vehicle.builder() + .id(1) + .name("RTW-1") + .constructionType(Vehicle.ConstructionType.HOCHDACH) + .type(Vehicle.VehicleType.RTW) + .status(Vehicle.Status.FREI_FUNK) + .hasNef(true) + .build(); + + v2 = + Vehicle.builder() + .id(2) + .name("KTW-1") + .constructionType(Vehicle.ConstructionType.HOCHDACH) + .type(Vehicle.VehicleType.KTW) + .status(Vehicle.Status.FREI_WACHE) + .hasNef(true) + .build(); + + v3 = + Vehicle.builder() + .id(3) + .name("KTW-2") + .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH) + .type(Vehicle.VehicleType.KTW_B) + .status(Vehicle.Status.FREI_FUNK) + .hasNef(false) + .build(); + + v4 = + Vehicle.builder() + .id(4) + .name("BKTW-2") + .constructionType(Vehicle.ConstructionType.HOCHDACH) + .type(Vehicle.VehicleType.BKTW) + .status(Vehicle.Status.FREI_FUNK) + .hasNef(false) + .build(); + + v5 = + Vehicle.builder() + .id(5) + .name("NEF-1") + .constructionType(Vehicle.ConstructionType.NORMAL) + .type(Vehicle.VehicleType.NEF) + .status(Vehicle.Status.FREI_WACHE) + .hasNef(true) + .build(); + + Vehicle v6 = + Vehicle.builder() + .id(6) + .name("NAH-1") + .constructionType(Vehicle.ConstructionType.MITTELHOCHDACH) + .type(Vehicle.VehicleType.NAH) + .status(Vehicle.Status.ABGEMELDET) + .hasNef(true) + .build(); + + vehicles = Set.of(v1, v2, v3, v4, v5, v6); + + Operation o = + Operation.builder() + .id(1) + .opCode("ALP-95E7") + .severity(Severity.E) + .status(Status.ACTIVE) + .vehicles(Collections.singleton(v1)) + .created(Instant.now()) + .destination("Wiedner Hauptstraße 35, Wien") + .build(); + + Operation o2 = o.toBuilder().status(Status.CANCELLED).build(); + + when(operationDAO.get(anyLong())) + .thenAnswer( + ans -> { + long arg = ans.getArgument(0); + if (arg == 1L) return o; + 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)); + } +} 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/einsatzverwaltung/service/OperationServiceUnitTest.java index fc10553..7b574a1 100644 --- a/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/operation/OperationServiceUnitTest.java +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceUnitTest.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.sepm.assignment.groupphase.operation; +package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; import static junit.framework.TestCase.fail; import static org.hamcrest.CoreMatchers.is; @@ -7,25 +7,26 @@ 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.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.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 java.util.Set; 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); + private final VehicleDAO vehicleDAO = mock(VehicleDAO.class); + private final OperationService operationService = + new OperationServiceImpl(operationDAO, vehicleDAO); @Test public void addOperationTest() { @@ -51,7 +52,7 @@ public class OperationServiceUnitTest { .destination("Wiedner Hauptstraße 35, Wien") .additionalInfo("HTU Wien") .severity(Severity.B) - .vehicles(List.of(vehicle)) + .vehicles(Set.of(vehicle)) .build(); try { Assert.assertThat(operationService.add(operation), is(1L)); @@ -87,7 +88,7 @@ public class OperationServiceUnitTest { .destination("Wiedner Hauptstraße 35, Wien") .additionalInfo("HTU Wien") .severity(Severity.B) - .vehicles(List.of(vehicle, vehicle1)) + .vehicles(Set.of(vehicle, vehicle1)) .build(); try { Assert.assertThat(operationService.add(operation), is(1L)); @@ -106,7 +107,7 @@ public class OperationServiceUnitTest { .destination("Wiedner Hauptstraße 35, Wien") .additionalInfo("HTU Wien") .severity(Severity.B) - .vehicles(List.of()) + .vehicles(Set.of()) .build(); try { Assert.assertThat(operationService.add(operation), is(1L)); @@ -125,7 +126,7 @@ public class OperationServiceUnitTest { .destination("") .additionalInfo("HTU Wien") .severity(Severity.B) - .vehicles(List.of()) + .vehicles(Set.of()) .build(); try { Assert.assertThat(operationService.add(operation), is(1L)); @@ -144,7 +145,7 @@ public class OperationServiceUnitTest { .destination("Römergasse 7, 2500 Baden") .additionalInfo("HTU Wien") .severity(Severity.B) - .vehicles(List.of()) + .vehicles(Set.of()) .build(); try { Assert.assertThat(operationService.add(operation), is(1L)); 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/RegistrationServiceImplTest.java index f3efbef..95d8d77 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/RegistrationServiceImplTest.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; @@ -31,36 +34,33 @@ import org.mockito.junit.MockitoRule; public class RegistrationServiceImplTest { - @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/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/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..daf4ec4 --- /dev/null +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/util/JdbcTestCase.java @@ -0,0 +1,153 @@ +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 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); + } + }; + + 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/VehiclePersistenceTest.java b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/vehicle/VehiclePersistenceTest.java new file mode 100644 index 0000000..81ebf63 --- /dev/null +++ b/src/test/java/at/ac/tuwien/sepm/assignment/groupphase/vehicle/VehiclePersistenceTest.java @@ -0,0 +1,153 @@ +package at.ac.tuwien.sepm.assignment.groupphase.vehicle; + +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.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.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 VehiclePersistenceTest 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 VehiclePersistenceTest() { + vehicleDAO = new VehicleDatabaseDao(getJdbcConnectionManager()); + } + + @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) + .build(); + Vehicle v2 = + Vehicle.builder() + .id(2) + .constructionType(ConstructionType.MITTELHOCHDACH) + .name("KTW-2") + .hasNef(false) + .status(Status.FREI_WACHE) + .type(VehicleType.KTW) + .build(); + Vehicle v3 = + Vehicle.builder() + .id(3) + .constructionType(ConstructionType.NORMAL) + .name("NEF-3") + .hasNef(false) + .status(Status.FREI_FUNK) + .type(VehicleType.NEF) + .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/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..19d25ad --- /dev/null +++ b/src/test/resources/vehicleTestData.xml @@ -0,0 +1,10 @@ +<dataset> + <VehicleVersion id="1" name="RTW-1" constructionType="HOCHDACH" type="RTW" hasNEF="true"/> + <VehicleVersion id="2" name="KTW-2" constructionType="MITTELHOCHDACH" type="KTW" hasNEF="false"/> + <VehicleVersion id="3" name="NEF-3" constructionType="NORMAL" type="NEF" hasNEF="false"/> + + + <Vehicle id="10" version="1" status="ABGEMELDET"/> + <Vehicle id="20" version="2" status="FREI_WACHE"/> + <Vehicle id="30" version="3" 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..159ccaa --- /dev/null +++ b/src/test/resources/vehicleTestUpdateExpectedData.xml @@ -0,0 +1,10 @@ +<dataset> + <VehicleVersion id="1" name="RTW-1" constructionType="HOCHDACH" type="RTW" hasNEF="true"/> + <VehicleVersion id="2" name="KTW-2" constructionType="MITTELHOCHDACH" type="KTW" hasNEF="false"/> + <VehicleVersion id="3" name="NEF-3" constructionType="NORMAL" type="NEF" hasNEF="false"/> + <VehicleVersion id="4" name="RTW-4" constructionType="HOCHDACH" type="RTW" hasNEF="true"/> + + <Vehicle id="10" version="1" status="ABGEMELDET"/> + <Vehicle id="20" version="4" status="ABGEMELDET"/> + <Vehicle id="30" version="3" status="FREI_FUNK"/> +</dataset>
\ No newline at end of file |