diff options
Diffstat (limited to 'src/main/java/at/ac/tuwien/sepm/assignment')
47 files changed, 2395 insertions, 1702 deletions
diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/application/MainApplication.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/application/MainApplication.java index d8365a7..a6c0566 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/application/MainApplication.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/application/MainApplication.java @@ -1,6 +1,7 @@  package at.ac.tuwien.sepm.assignment.groupphase.application; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.CreateOperationController; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.CreateOperationController; +import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager;  import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader;  import javafx.application.Application;  import javafx.application.Platform; @@ -25,7 +26,13 @@ public class MainApplication extends Application {      public void start(Stage primaryStage) throws Exception {          primaryStage.setTitle("Einsatz erstellen");          primaryStage.centerOnScreen(); -        primaryStage.setOnCloseRequest(event -> Platform.exit()); +        primaryStage.setOnCloseRequest( +                event -> { +                    final var jdbcConnectionManager = +                            configApplicationContext.getBean(JDBCConnectionManager.class); +                    jdbcConnectionManager.closeConnection(); +                    Platform.exit(); +                });          configApplicationContext = new AnnotationConfigApplicationContext(MainApplication.class);          final var fxmlLoader = configApplicationContext.getBean(SpringFXMLLoader.class); diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/application/PopulateDB.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/application/PopulateDB.java new file mode 100644 index 0000000..4ff1f78 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/application/PopulateDB.java @@ -0,0 +1,20 @@ +package at.ac.tuwien.sepm.assignment.groupphase.application; + +import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; +import java.io.InputStreamReader; +import java.sql.SQLException; +import org.h2.tools.RunScript; +import org.springframework.core.io.ClassPathResource; + +public class PopulateDB { +    public static void main(String[] args) throws SQLException { +        JDBCConnectionManager jdbcConnectionManager = new JDBCConnectionManager(); + +        RunScript.execute( +                jdbcConnectionManager.getConnection(), +                new InputStreamReader( +                        ClassPathResource.class.getResourceAsStream("/sql/testdata.sql"))); + +        jdbcConnectionManager.closeConnection(); +    } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ArchiveOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ArchiveOperationController.java deleted file mode 100644 index 80d9fc4..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ArchiveOperationController.java +++ /dev/null @@ -1,127 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.OperationService; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.time.LocalDateTime; -import java.time.ZoneOffset; -import java.util.Collection; -import java.util.EnumSet; -import java.util.LinkedList; -import java.util.Objects; -import java.util.stream.Collectors; -import javafx.fxml.FXML; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.Button; -import javafx.scene.control.Hyperlink; -import javafx.scene.control.Label; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.FlowPane; -import org.springframework.stereotype.Controller; - -@Controller -public class ArchiveOperationController { -    @FXML private AnchorPane apDetails; -    @FXML private Label lblCodeHeader; -    @FXML private Hyperlink hypBack; -    @FXML private Label lblOpCode; -    @FXML private Label lblVehicles; -    @FXML private Label lblDate; -    @FXML private Label lblAddress; -    @FXML private FlowPane fpVehicles; -    private final OperationService operationService; -    @FXML private FlowPane archiveOperationFlowPane; -    private LinkedList<Operation> list = new LinkedList<>(); - -    public ArchiveOperationController(OperationService operationService) { -        this.operationService = operationService; -    } - -    @FXML -    private void initialize() { -        try { -            list.addAll(operationService.list(EnumSet.of(Status.CANCELLED, Status.COMPLETED))); -        } catch (ServiceException e) { -            Alert alert = new Alert(AlertType.ERROR); -            alert.setTitle("Fehler"); -            alert.setHeaderText("Fehler!"); -            alert.setContentText("Die Einsätze konnten nicht geladen werden!"); -            alert.showAndWait(); -        } -        for (Operation operation : list) { -            Button b = new Button(); -            b.setPrefHeight(200); -            b.setPrefWidth(750 / 2); -            b.setText(operation.opCode()); -            b.setOnAction(event -> buttonClicked(b)); -            archiveOperationFlowPane.getChildren().add(b); -        } -    } - -    private Operation detailOperation; - -    private void buttonClicked(Button button) { -        int size = archiveOperationFlowPane.getChildren().size(); -        int index = 0; -        for (int i = 0; i < size; i++) { -            if (archiveOperationFlowPane.getChildren().get(i) == button) { -                index = i; -                break; -            } -        } -        detailOperation = list.get(index); -        setOperation(); -        setDetailsVisible(true); -    } - -    private void setOperation() { -        lblCodeHeader.setText(detailOperation.opCode()); -        String date = "am "; -        if (detailOperation.created() != null) { -            LocalDateTime myDateTime = -                    LocalDateTime.ofInstant( -                            Objects.requireNonNull(detailOperation.created()), ZoneOffset.UTC); -            date += -                    myDateTime.getDayOfMonth() -                            + "." -                            + myDateTime.getMonth().getValue() -                            + "." -                            + myDateTime.getYear(); -            lblDate.setText(date); -        } else { -            lblDate.setText("---"); -        } - -        lblOpCode.setText(detailOperation.opCode()); -        Collection<String> elements = -                detailOperation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList()); -        String result = String.join(", ", elements); - -        lblVehicles.setText(result); -        lblAddress.setText(detailOperation.destination()); - -        for (Vehicle vehicle : detailOperation.vehicles()) { -            Button b = new Button(); -            b.setPrefHeight(200); -            b.setPrefWidth(600 / 2); -            b.setText(vehicle.name()); -            fpVehicles.getChildren().add(b); -        } -    } - -    public void setListVisible(boolean b) { -        archiveOperationFlowPane.setVisible(b); -    } - -    private void setDetailsVisible(boolean b) { -        apDetails.setVisible(b); -    } - -    public void backClicked() { -        fpVehicles.getChildren().clear(); -        setDetailsVisible(false); -    } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateCarController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateCarController.java deleted file mode 100644 index ce795da..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateCarController.java +++ /dev/null @@ -1,206 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -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.einsatzverwaltung.service.VehicleService; -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; -import org.springframework.stereotype.Controller; - -@Controller -public class CreateCarController { - -    @FXML private ChoiceBox<String> cmb_Ctyp; -    @FXML private ChoiceBox<String> cmb_typ; -    @FXML private Button btn_cancel; -    @FXML private Button btn_create; -    @FXML private CheckBox cbx_NEF; -    @FXML private FlowPane fp_vehicleList; - -    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); -    private final VehicleService vehicleService; -    private boolean update = false; -    private long vid = -1; - -    public CreateCarController(VehicleService vehicleService) { -        this.vehicleService = vehicleService; -    } - -    @FXML -    private void initialize() { -        cmb_Ctyp.setItems( -                FXCollections.observableArrayList( -                        Stream.of( -                                        ConstructionType.NORMAL, -                                        ConstructionType.MITTELHOCHDACH, -                                        ConstructionType.HOCHDACH) -                                .map(Enum::toString) -                                .collect(Collectors.toList()))); -        cmb_Ctyp.setValue(ConstructionType.NORMAL.toString()); -        cmb_typ.setItems( -                FXCollections.observableArrayList( -                        Stream.of( -                                        VehicleType.BKTW, -                                        VehicleType.KTW_B, -                                        VehicleType.KTW, -                                        VehicleType.RTW, -                                        VehicleType.NEF, -                                        VehicleType.NAH) -                                .map(Enum::toString) -                                .collect(Collectors.toList()))); -        cmb_typ.setValue(VehicleType.BKTW.toString()); -        vehicleListFP(); -    } - -    @FXML -    private void onCancelClicked() { -        ((Stage) btn_cancel.getScene().getWindow()).close(); -    } - -    @FXML -    private void createCar(ActionEvent actionEvent) { - -        if (!update) { -            Vehicle vehicle = -                    Vehicle.builder() -                            .constructionType(parseConstructionType()) -                            .type(parseType()) -                            .name("") -                            .status(Status.ABGEMELDET) -                            .hasNef(cbx_NEF.isSelected()) -                            .build(); -            try { -                vehicleService.add(vehicle); -                setToStart(); -            } catch (InvalidVehicleException e) { -                LOG.error("Invalid Vehicle: {}", e); -                createComplete(AlertType.ERROR, "Ungültige Eingabe", e.getMessage()); -                setToStart(); -                return; -            } catch (ServiceException e) { -                LOG.error("Exception: {}", e); -                createComplete(AlertType.ERROR, "Fehler", e.getMessage()); -                setToStart(); -                return; -            } -            createComplete( -                    AlertType.CONFIRMATION, -                    "Speichern Erfolgreich", -                    "Auto wurde erfolgreich angelegt"); -        } else { -            try { -                Vehicle vehicle = -                        Vehicle.builder() -                                .id(vid) -                                .constructionType(parseConstructionType()) -                                .type(parseType()) -                                .name("") -                                .status(Status.ABGEMELDET) -                                .hasNef(cbx_NEF.isSelected()) -                                .build(); -                vehicleService.update(vehicle); -                setToStart(); -            } catch (InvalidVehicleException e) { -                LOG.error("Invalid Vehicle: {}", e); -                createComplete(AlertType.ERROR, "Ungültige Eingabe", e.getMessage()); -                setToStart(); -                return; -            } catch (ServiceException e) { -                LOG.error("Exception: {}", e); -                createComplete(AlertType.ERROR, "Fehler", e.getMessage()); -                setToStart(); -                return; -            } -            createComplete( -                    AlertType.CONFIRMATION, -                    "Bearbiten Erfolgreich", -                    "Auto wurde erfolgreich bearbeitet"); -        } -        vehicleListFP(); -    } - -    private ConstructionType parseConstructionType() { -        if (cmb_Ctyp.getSelectionModel().getSelectedItem() == null) { -            return ConstructionType.NORMAL; -        } -        return ConstructionType.valueOf(cmb_Ctyp.getSelectionModel().getSelectedItem().toString()); -    } - -    private VehicleType parseType() { -        if (cmb_typ.getSelectionModel().getSelectedItem() == null) { -            return VehicleType.BKTW; -        } -        return VehicleType.valueOf(cmb_typ.getSelectionModel().getSelectedItem().toString()); -    } - -    private void createComplete(AlertType alertType, String headerText, String contentText) { -        Alert alert = new Alert(alertType, contentText, ButtonType.OK); -        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/OperationDetailsController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/OperationDetailsController.java deleted file mode 100644 index dc7e969..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/OperationDetailsController.java +++ /dev/null @@ -1,162 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.OperationService; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.VehicleService; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.util.Collection; -import java.util.EnumSet; -import java.util.stream.Collectors; -import javafx.collections.FXCollections; -import javafx.fxml.FXML; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.ListCell; -import javafx.scene.control.ListView; -import javafx.scene.layout.AnchorPane; -import org.springframework.stereotype.Controller; - -@Controller -public class OperationDetailsController { - -    public Operation operation; -    private final OperationService operationService; -    private final VehicleService vehicleService; -    private final CreateOperationController createOperationController; -    @FXML private ListView<Vehicle> lvVehicles; -    @FXML private ListView<Operation> lvActiveOperations; -    @FXML private Label lblChosenVehicles; -    @FXML private Button btnCloseOperation; -    @FXML private Button btnCancelOperation; -    @FXML private Label lblCode, lblAdditionalInfo, lblAddress; -    @FXML private AnchorPane operationDetailsAP; - -    public OperationDetailsController( -            OperationService operationService, -            VehicleService vehicleService, -            CreateOperationController createOperationController) { -        this.operationService = operationService; -        this.vehicleService = vehicleService; -        this.createOperationController = createOperationController; -    } - -    @FXML -    private void initialize() { -        lvVehicles.setCellFactory( -                param -> -                        new ListCell<>() { -                            @Override -                            protected void updateItem(Vehicle item, boolean empty) { -                                super.updateItem(item, empty); - -                                if (empty || item == null || item.name() == null) { -                                    setText(null); -                                } else { -                                    setText(item.name()); -                                } -                            } -                        }); -        lvActiveOperations.setCellFactory( -                param -> -                        new ListCell<>() { -                            @Override -                            protected void updateItem(Operation item, boolean empty) { -                                super.updateItem(item, empty); - -                                if (empty || item == null || item.opCode() == null) { -                                    setText(null); -                                } else { -                                    setText(item.opCode()); -                                } -                            } -                        }); -        lvActiveOperations.setOnMouseClicked( -                event -> { -                    if (event.getClickCount() == 2) { -                        if (lvActiveOperations.getSelectionModel().getSelectedItem() == null) { -                            return; -                        } -                        initOperation(lvActiveOperations.getSelectionModel().getSelectedItem()); -                    } -                }); -    } - -    void initOperation(Operation operation) { -        fillActiveList(); -        this.operation = operation; -        lblCode.setText(operation.opCode()); -        Collection<String> vehicleNames = -                operation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList()); -        String result = String.join(", ", vehicleNames); -        lblChosenVehicles.setText(result.toString()); -        lblAdditionalInfo.setText(operation.additionalInfo()); -        lblAddress.setText(operation.destination()); -        lvVehicles.setItems(FXCollections.observableArrayList(operation.vehicles())); -        operationDetailsAP.setVisible(true); -    } - -    private void fillActiveList() { -        try { -            lvActiveOperations.setItems( -                    FXCollections.observableArrayList( -                            operationService.list(EnumSet.of(Status.ACTIVE)))); -        } catch (ServiceException e) { -            Alert alert = new Alert(AlertType.ERROR); -            alert.setTitle("Fehler"); -            alert.setHeaderText("Fehler!"); -            alert.setContentText(e.getMessage()); -            alert.showAndWait(); -        } -    } - -    @FXML -    public void closeOperationClicked() { -        try { -            operationService.complete(operation.id(), Status.COMPLETED); -        } catch (InvalidOperationException | ServiceException e) { -            Alert alert = new Alert(AlertType.ERROR); -            alert.setTitle("Fehler"); -            alert.setHeaderText("Fehler!"); -            alert.setContentText(e.getMessage()); -            alert.showAndWait(); -            return; -        } -        Alert alert = new Alert(AlertType.CONFIRMATION); -        alert.setTitle("Erfolg"); -        alert.setHeaderText("Erfolgreich aktualisiert"); -        alert.setContentText("Der Einsatz wurde erfolgreich aktualisiert."); -        alert.showAndWait(); -        closeWindow(); -        createOperationController.updateList(); -    } - -    public void cancelOperationClicked() { -        try { -            operationService.complete(operation.id(), Status.CANCELLED); -        } catch (InvalidOperationException | ServiceException e) { -            Alert alert = new Alert(AlertType.ERROR); -            alert.setTitle("Fehler"); -            alert.setHeaderText("Fehler!"); -            alert.setContentText(e.getMessage()); -            alert.showAndWait(); -            return; -        } -        Alert alert = new Alert(AlertType.CONFIRMATION); -        alert.setTitle("Erfolg"); -        alert.setHeaderText("Erfolgreich aktualisiert"); -        alert.setContentText("Der Einsatz wurde erfolgreich aktualisiert."); -        alert.showAndWait(); -        closeWindow(); -        createOperationController.updateList(); -    } - -    public void closeWindow() { -        operationDetailsAP.setVisible(false); -        this.createOperationController.setVisible(true); -    } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/RegistrationWindowController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/RegistrationWindowController.java deleted file mode 100644 index 4653663..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/RegistrationWindowController.java +++ /dev/null @@ -1,213 +0,0 @@ -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.dto.Registration; -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.einsatzverwaltung.service.EmployeeService; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.RegistrationService; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.VehicleService; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidRegistrationException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.OffsetDateTime; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import javafx.beans.property.SimpleStringProperty; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.fxml.FXML; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.ChoiceBox; -import javafx.scene.control.Label; -import javafx.scene.control.TableColumn; -import javafx.scene.control.TableView; -import javafx.scene.control.TextField; -import javafx.stage.Stage; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; - -@Controller -public class RegistrationWindowController { - -    private static final Logger LOG = LoggerFactory.getLogger(RegistrationWindowController.class); - -    private final EmployeeService employeeService; - -    private final VehicleService vehicleService; - -    private final RegistrationService registrationService; - -    public RegistrationWindowController( -            EmployeeService employeeService, -            VehicleService vehicleService, -            RegistrationService registrationService) { -        this.employeeService = employeeService; -        this.vehicleService = vehicleService; -        this.registrationService = registrationService; -    } - -    @FXML private ChoiceBox<Integer> cbStart; -    @FXML private ChoiceBox<Integer> cbEnd; -    @FXML private Label lVehicles; -    @FXML private Label lEmployees; -    @FXML private TextField tfVehicleSearch; -    @FXML private TextField tfEmployeeSearch; -    @FXML private TableView<Vehicle> tvVehicles; -    @FXML private TableView<Employee> tvEmployees; -    @FXML private TableColumn<Vehicle, String> tcVehicles; -    @FXML private TableColumn<Employee, String> tcEmployees; - -    private Vehicle chosenVehicle; -    private List<Employee> chosenEmployees = new LinkedList<>(); - -    @FXML -    private void initialize() { -        // will have to be replaced for FlowPane -        try { -            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) { -            LOG.warn( -                    "Caught ServiceException while getting vehicles. Showing it to user. Error message: {}", -                    e.getMessage()); -            Alert alert = new Alert(AlertType.ERROR); -            alert.setTitle("Fahrzeuge - Fehler!"); -            alert.setHeaderText("Beim Auflisten der Fahrzeug ist ein Fehler aufgetreten."); -            alert.setContentText(e.getMessage()); -            alert.show(); -        } -        try { -            Set<Employee> employees = employeeService.list(); -            tcEmployees.setCellValueFactory(x -> new SimpleStringProperty(x.getValue().name())); -            tvEmployees.setItems(FXCollections.observableArrayList(employees)); -        } catch (ServiceException e) { -            LOG.warn( -                    "Caught ServiceException while getting employees. Showing it to user. Error message: {}", -                    e.getMessage()); -            Alert alert = new Alert(AlertType.ERROR); -            alert.setTitle("Personal - Fehler!"); -            alert.setHeaderText("Beim Auflisten des Personals ist ein Fehler aufgetreten."); -            alert.setContentText(e.getMessage()); -            alert.show(); -        } -        tvVehicles.setOnMousePressed( -                mouseEvent -> { -                    if (mouseEvent.isPrimaryButtonDown() && mouseEvent.getClickCount() == 2) { -                        chosenVehicle = tvVehicles.getSelectionModel().getSelectedItem(); -                        if (chosenVehicle == null) { -                            return; -                        } -                        lVehicles.setText(chosenVehicle.name()); -                    } -                }); -        tvEmployees.setOnMousePressed( -                mouseEvent -> { -                    if (mouseEvent.isPrimaryButtonDown() && mouseEvent.getClickCount() == 2) { -                        Employee selection = tvEmployees.getSelectionModel().getSelectedItem(); -                        if (selection == null) { -                            return; -                        } else if (chosenEmployees.contains(selection)) { -                            chosenEmployees.remove(selection); -                        } else { -                            chosenEmployees.add(selection); -                        } - -                        StringBuilder text = new StringBuilder(); -                        for (Employee employee : chosenEmployees) { -                            text.append(employee.name()).append("\n"); -                        } -                        lEmployees.setText(text.toString()); -                    } -                }); -        ObservableList<Integer> hours = -                FXCollections.observableArrayList( -                        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, -                        21, 22, 23); -        cbStart.setItems(hours); -        cbStart.setValue(0); -        cbEnd.setItems(hours); -        cbEnd.setValue(12); -    } - -    public void cancel() { -        LOG.debug("Cancel Button clicked"); -        chosenEmployees.clear(); -        ((Stage) lVehicles.getScene().getWindow()).close(); -    } - -    public void create() { -        LOG.debug("Create Button clicked"); - -        Set<Registration> registrations = new HashSet<>(); -        try { -            if (chosenVehicle == null) { -                throw new InvalidVehicleException("no Vehicle"); -            } -            for (Employee employee : chosenEmployees) { -                registrations.add( -                        Registration.builder() -                                .id(chosenVehicle.id()) -                                .employee(employee) -                                .start( -                                        LocalDateTime.of( -                                                        LocalDate.now(), -                                                        LocalTime.of(cbStart.getValue(), 0)) -                                                .toInstant(OffsetDateTime.now().getOffset())) -                                .end( -                                        LocalDateTime.of( -                                                        LocalDate.now(), -                                                        LocalTime.of(cbEnd.getValue(), 0)) -                                                .toInstant(OffsetDateTime.now().getOffset())) -                                .build()); -            } - -            registrationService.add(chosenVehicle.id(), registrations); -            chosenEmployees.clear(); -            ((Stage) lVehicles.getScene().getWindow()).close(); - -        } catch (InvalidVehicleException e) { -            // NOT THROWN ANYWHERE RIGHT NOW -            LOG.info( -                    "Caught InvalidVehicleException. Showing it to user. Error message: {}", -                    e.getClass().toString(), -                    e.getMessage()); -            Alert alert = new Alert(AlertType.WARNING); -            alert.setTitle("Ungültiges Fahrzeug"); -            alert.setHeaderText("Das spezifizierte Fahrzeug ist nicht gültig."); -            alert.setContentText(e.getMessage()); -            alert.show(); -            chosenEmployees.clear(); -        } catch (ServiceException e) { -            LOG.warn( -                    "Caught ServiceException while getting vehicles. Showing it to user. Error message: {}", -                    e.getMessage()); -            Alert alert = new Alert(AlertType.ERROR); -            alert.setTitle("Anmeldung - Fehler!"); -            alert.setHeaderText("Beim Erstellen der Anmeldung ist ein Fehler aufgetreten."); -            alert.setContentText(e.getMessage()); -            alert.show(); -            chosenEmployees.clear(); -        } catch (InvalidRegistrationException e) { -            LOG.info( -                    "Caught InvalidRegistrationException. Showing it to user. Error message: {}", -                    e.getMessage()); -            Alert alert = new Alert(AlertType.WARNING); -            alert.setTitle("Ungültige Eingabe"); -            alert.setHeaderText( -                    "Die gewählte Kombination von Fahrzeug und Personal ist nicht gültig!"); -            alert.setContentText(e.getMessage()); -            alert.show(); -            chosenEmployees.clear(); -        } -    } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDatabaseDAO.java deleted file mode 100644 index 43a5c9d..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDatabaseDAO.java +++ /dev/null @@ -1,201 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; -import java.lang.invoke.MethodHandles; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Savepoint; -import java.sql.Statement; -import java.sql.Timestamp; -import java.util.HashSet; -import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Repository; - -@Repository -public class EmployeeDatabaseDAO implements EmployeeDAO { - -    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); -    private static final String INSERT_EMPLOYEE_VERSION = -            "INSERT INTO EmployeeVersion(name, birthday, educationLevel, isDriver, isPilot) " -                    + "VALUES(?, ?, ?, ?, ?)"; -    private static final String INSERT_EMPLOYEE = "INSERT INTO Employee(version) VALUES(?)"; -    private static final String LIST_EMPLOYEE = -            "SELECT emp.id, v.name, v.birthday, v.educationLevel, v.isDriver, v.isPilot " -                    + "FROM employee emp " -                    + "JOIN EmployeeVersion v ON v.id = emp.version"; -    private static final String UPDATE_EMPLOYEE = "UPDATE Employee SET version = ? WHERE id = ?"; - -    private final PreparedStatement insertEmployeeVersion, -            insertEmployee, -            listEmployee, -            updateEmployee; - -    private final Connection connection; - -    public EmployeeDatabaseDAO(JDBCConnectionManager connectionManager) -            throws PersistenceException { - -        try { - -            connection = connectionManager.getConnection(); -            insertEmployeeVersion = -                    connection.prepareStatement( -                            INSERT_EMPLOYEE_VERSION, Statement.RETURN_GENERATED_KEYS); -            insertEmployee = -                    connection.prepareStatement(INSERT_EMPLOYEE, Statement.RETURN_GENERATED_KEYS); - -            listEmployee = connection.prepareStatement(LIST_EMPLOYEE); - -            updateEmployee = connection.prepareStatement(UPDATE_EMPLOYEE); - -        } catch (SQLException e) { -            throw new PersistenceException(e); -        } -    } - -    @Override -    public long add(Employee employee) throws PersistenceException { - -        // Assumption: the given employee is already validated (from service) -        Savepoint savepoint = null; -        try { -            savepoint = connection.setSavepoint(); -            connection.setAutoCommit(false); -            insertEmployeeVersion.setString(1, employee.name()); -            insertEmployeeVersion.setTimestamp( -                    2, Timestamp.valueOf(employee.birthday().atStartOfDay())); -            insertEmployeeVersion.setString(3, employee.educationLevel().toString()); -            insertEmployeeVersion.setBoolean(4, employee.isDriver()); -            insertEmployeeVersion.setBoolean(5, employee.isPilot()); -            insertEmployeeVersion.executeUpdate(); -            try (ResultSet resultSetEmployeeVersion = insertEmployeeVersion.getGeneratedKeys()) { -                if (resultSetEmployeeVersion.next()) { -                    long versionId = resultSetEmployeeVersion.getLong(1); - -                    insertEmployee.setLong(1, versionId); -                    insertEmployee.executeUpdate(); - -                    try (ResultSet resultSetEmployee = insertEmployee.getGeneratedKeys()) { -                        if (resultSetEmployee.next()) { -                            connection.commit(); -                            return resultSetEmployee.getLong(1); -                        } -                    } -                } -            } - -            throw new PersistenceException("Employee was not updated"); - -        } catch (SQLException e) { -            try { -                if (savepoint != null) { -                    connection.rollback(savepoint); -                } -            } catch (SQLException e1) { -                throw new PersistenceException(e); -            } -            throw new PersistenceException(e); -        } finally { -            try { -                connection.setAutoCommit(true); -            } catch (SQLException e) { -                throw new PersistenceException(e); -            } -        } -    } - -    @Override -    public void update(Employee employee) throws ElementNotFoundException, PersistenceException { - -        Savepoint savepoint = null; -        try { -            savepoint = connection.setSavepoint(); -            connection.setAutoCommit(false); - -            insertEmployeeVersion.setString(1, employee.name()); -            insertEmployeeVersion.setTimestamp( -                    2, Timestamp.valueOf(employee.birthday().atStartOfDay())); -            insertEmployeeVersion.setString(3, employee.educationLevel().toString()); -            insertEmployeeVersion.setBoolean(4, employee.isDriver()); -            insertEmployeeVersion.setBoolean(5, employee.isPilot()); -            insertEmployeeVersion.executeUpdate(); -            try (ResultSet resultSetEmployeeVersion = insertEmployeeVersion.getGeneratedKeys()) { - -                if (resultSetEmployeeVersion.next()) { -                    long versionId = resultSetEmployeeVersion.getLong(1); - -                    updateEmployee.setLong(1, versionId); -                    updateEmployee.setLong(2, employee.id()); -                    int affectedRows = updateEmployee.executeUpdate(); - -                    if (affectedRows == 1) { -                        connection.commit(); -                    } else { -                        throw new ElementNotFoundException( -                                "element not found with id: " + employee.id()); -                    } -                } -            } - -        } catch (SQLException e) { -            try { -                if (savepoint != null) { -                    connection.rollback(savepoint); -                } -            } catch (SQLException e1) { -                throw new PersistenceException(e); -            } -            throw new PersistenceException(e); -        } finally { -            try { -                connection.setAutoCommit(true); -            } catch (SQLException e) { -                throw new PersistenceException(e); -            } -        } -    } - -    @Override -    public Set<Employee> list() throws PersistenceException { - -        try { -            Set<Employee> employees; -            try (ResultSet rs = listEmployee.executeQuery()) { - -                employees = new HashSet<>(); -                while (rs.next()) { - -                    Employee employee = -                            Employee.builder() -                                    .id(rs.getLong(1)) -                                    .name(rs.getString(2)) -                                    .birthday(rs.getTimestamp(3).toLocalDateTime().toLocalDate()) -                                    .educationLevel(EducationLevel.valueOf(rs.getString(4))) -                                    .isDriver(rs.getBoolean(5)) -                                    .isPilot(rs.getBoolean(6)) -                                    .build(); - -                    employees.add(employee); -                } -            } - -            return employees; - -        } catch (SQLException e) { -            throw new PersistenceException(e); -        } -    } - -    @Override -    public void remove(long id) throws ElementNotFoundException, PersistenceException { -        throw new UnsupportedOperationException(); -    } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDatabaseDAO.java deleted file mode 100644 index 13f2c0f..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDatabaseDAO.java +++ /dev/null @@ -1,147 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Repository; - -@Repository -public class RegistrationDatabaseDAO implements RegistrationDAO { - -    private static final Logger LOG = LoggerFactory.getLogger(RegistrationDatabaseDAO.class); - -    private static final String ADD_REGISTRATION = -            "INSERT INTO Registration (vehicleId, employeeId, start, end, active) VALUES (?,?,?,?,?);"; -    private static final String UPDATE_VEHICLE = -            "UPDATE Vehicle SET status = 'FREI_WACHE' WHERE id = ?;"; -    private static final String FETCH_REGISTRATIONS = -            "SELECT * FROM Registration WHERE vehicleId = ?"; - -    private PreparedStatement addRegistration; -    private PreparedStatement updateVehicle; -    private PreparedStatement fetchRegistrations; - -    private Connection connection; -    private EmployeeDAO employeePersistence; - -    @Autowired -    public RegistrationDatabaseDAO( -            JDBCConnectionManager connectionManager, EmployeeDAO employeePersistence) -            throws PersistenceException { -        this.employeePersistence = employeePersistence; -        try { -            connection = connectionManager.getConnection(); -            addRegistration = -                    connection.prepareStatement(ADD_REGISTRATION, Statement.RETURN_GENERATED_KEYS); -            updateVehicle = connection.prepareStatement(UPDATE_VEHICLE); -            fetchRegistrations = connection.prepareStatement(FETCH_REGISTRATIONS); -        } catch (SQLException e) { -            LOG.error("Could not get connection or preparation of statement failed"); -            throw new PersistenceException(e); -        } -    } - -    @Override -    public Set<Long> add(long vehicleId, Set<Registration> registrations) -            throws PersistenceException { -        Set<Long> returnValues = new HashSet<>(); -        try { -            connection.setAutoCommit(false); -            for (Registration registration : registrations) { -                addRegistration.setLong(1, vehicleId); -                addRegistration.setLong(2, registration.employee().id()); -                addRegistration.setTimestamp(3, Timestamp.from(registration.start())); -                addRegistration.setTimestamp(4, Timestamp.from(registration.end())); -                addRegistration.setBoolean( -                        5, true); // ASSUMPTION: Registration gets created as active -                addRegistration.executeUpdate(); -                try (ResultSet rs = addRegistration.getGeneratedKeys()) { -                    if (rs.next()) { -                        returnValues.add(rs.getLong(1)); -                    } else { -                        LOG.error("No ResultSet was created while adding registration"); -                        throw new PersistenceException( -                                "Anmeldung konnte nicht gespeichert werden."); -                    } -                } -            } - -            updateVehicle.setLong(1, vehicleId); -            updateVehicle.executeUpdate(); - -            connection.commit(); -            return returnValues; -        } catch (SQLException e) { -            LOG.error( -                    "An SQLException occurred while trying to save registrations to database. " -                            + "Attempting a rollback. Error message: {}", -                    e.getMessage()); -            try { -                connection.rollback(); -            } catch (SQLException e1) { -                LOG.error("Rollback failed :("); -            } -            throw new PersistenceException(e); -        } finally { -            try { -                connection.setAutoCommit(true); -            } catch (SQLException e) { -                LOG.error( -                        "Setting back AutoCommit to false failed! Error message: {}", -                        e.getMessage()); -                // SonarLint insists on me not throwing anything here... -            } -        } -    } - -    @Override -    public void remove(long id) throws ElementNotFoundException, PersistenceException { -        throw new UnsupportedOperationException(); -    } - -    public List<Registration> list(long vehicleId) throws PersistenceException { -        List<Registration> registrationList = new ArrayList<>(); -        try { -            fetchRegistrations.setLong(1, vehicleId); -            ResultSet rs = fetchRegistrations.executeQuery(); -            while (rs.next()) { -                long employeeId = rs.getLong("employeeId"); -                // TODO: replace the following with employeePersistence.get once implemented -                Employee emp = -                        employeePersistence -                                .list() -                                .stream() -                                .filter(employee -> employee.id() == employeeId) -                                .findAny() -                                .orElse(null); -                Registration registration = -                        Registration.builder() -                                .id(rs.getLong("id")) -                                .start(rs.getTimestamp("start").toInstant()) -                                .end(rs.getTimestamp("end").toInstant()) -                                .employee(emp) -                                .build(); -                registrationList.add(registration); -            } -        } catch (SQLException e) { -            throw new PersistenceException(e); -        } - -        return registrationList; -    } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDatabaseDAO.java deleted file mode 100644 index 6d50588..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDatabaseDAO.java +++ /dev/null @@ -1,220 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.HashSet; -import java.util.Set; -import org.springframework.stereotype.Repository; - -@Repository -public class VehicleDatabaseDAO implements VehicleDAO { - -    private final JDBCConnectionManager jdbcConnectionManager; -    private RegistrationDatabaseDAO registrationDatabaseDao; - -    public VehicleDatabaseDAO( -            JDBCConnectionManager j, RegistrationDatabaseDAO registrationDatabaseDao) { -        jdbcConnectionManager = j; -        this.registrationDatabaseDao = registrationDatabaseDao; -    } - -    public long add(Vehicle vehicle) throws PersistenceException { -        String query1 = -                "INSERT INTO VehicleVersion (name,hasNef,constructionType,type) VALUES (?,?,?,?)"; -        String query2 = "INSERT INTO Vehicle (version,status) VALUES (?,?)"; - -        String status = "ABGEMELDET"; -        String name = ""; -        int id = -1; -        int version = -1; -        try { -            Connection connection = jdbcConnectionManager.getConnection(); -            connection.setAutoCommit(false); -            try (PreparedStatement p1 = -                    connection.prepareStatement(query1, PreparedStatement.RETURN_GENERATED_KEYS)) { - -                p1.setString(1, name); -                p1.setBoolean(2, vehicle.hasNef()); -                p1.setString(3, vehicle.constructionType().name()); - -                p1.setString(4, vehicle.type().name()); - -                p1.executeUpdate(); -                try (ResultSet keyResultSet = p1.getGeneratedKeys()) { - -                    if (keyResultSet.next()) { -                        version = keyResultSet.getInt(1); -                    } -                } -            } -            try (PreparedStatement p2 = -                    connection.prepareStatement(query2, Statement.RETURN_GENERATED_KEYS)) { - -                p2.setInt(1, version); -                p2.setString(2, status); -                p2.executeUpdate(); -                try (ResultSet keyResultSet = p2.getGeneratedKeys()) { - -                    if (keyResultSet.next()) { -                        id = keyResultSet.getInt(1); -                    } -                } - -                name = vehicle.type().name() + "-" + id; -            } -            query1 = "UPDATE VehicleVersion SET name=? WHERE id=?"; -            try (PreparedStatement p3 = connection.prepareStatement(query1)) { -                p3.setString(1, name); -                p3.setInt(2, version); -                p3.executeUpdate(); -            } - -            connection.commit(); -            connection.setAutoCommit(true); -        } catch (SQLException e) { -            throw new PersistenceException(e); -        } -        return id; -    } - -    @Override -    public void update(Vehicle vehicle) throws ElementNotFoundException, PersistenceException { -        String query = "SELECT * FROM vehicle WHERE id=?"; - -        long vehicleID = -1; -        long vehicleVersion = -1; -        try { -            Connection connection = jdbcConnectionManager.getConnection(); -            connection.setAutoCommit(false); -            try (PreparedStatement p = -                    connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) { - -                p.setLong(1, vehicle.id()); -                p.executeQuery(); -                try (ResultSet rs = p.getResultSet()) { -                    while (rs.next()) { -                        vehicleID = rs.getLong("id"); -                    } -                } -            } -            if (vehicleID == -1) { -                throw new ElementNotFoundException("Vehicle don´t found"); -            } - -            query = -                    "INSERT INTO VehicleVersion (name,hasNef,constructionType,type) VALUES (?,?,?,?)"; -            String name = ""; -            try (PreparedStatement p = -                    connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) { -                p.setString(1, name); -                p.setBoolean(2, vehicle.hasNef()); -                p.setString(3, vehicle.constructionType().name()); - -                p.setString(4, vehicle.type().name()); - -                p.executeUpdate(); - -                try (ResultSet keyResultSet = p.getGeneratedKeys()) { - -                    if (keyResultSet.next()) { -                        vehicleVersion = keyResultSet.getInt(1); -                    } -                } -                if (vehicleVersion == -1) { -                    throw new ElementNotFoundException("Vehicle don´t found"); -                } -            } -            name = vehicle.type().name() + "-" + vehicleID; - -            query = "UPDATE VehicleVersion SET name=? WHERE id=?"; -            try (PreparedStatement p = connection.prepareStatement(query)) { - -                p.setString(1, name); -                p.setLong(2, vehicleVersion); -                p.executeUpdate(); -            } -            query = "UPDATE Vehicle SET version=? WHERE id=?"; -            try (PreparedStatement p = connection.prepareStatement(query)) { - -                p.setLong(1, vehicleVersion); -                p.setLong(2, vehicleID); -                p.executeUpdate(); -            } -            connection.commit(); -            connection.setAutoCommit(true); -        } catch (SQLException e) { -            throw new PersistenceException(e); -        } -    } - -    @Override -    public Set<Vehicle> list() throws PersistenceException { -        Set<Vehicle> result = new HashSet<>(); - -        String sql = -                "Select * from VehicleVersion, Vehicle where VehicleVersion.id=Vehicle.version"; - -        try (PreparedStatement pstmt = -                jdbcConnectionManager.getConnection().prepareStatement(sql)) { -            pstmt.executeQuery(); -            try (ResultSet rs = pstmt.getResultSet()) { -                while (rs.next()) { -                    result.add(vehicleFromRS(rs)); -                } -            } -        } catch (SQLException e) { -            throw new PersistenceException("Die Werte konnten nicht geladen werden.", e); -        } -        return result; -    } - -    @Override -    public Vehicle get(long id) throws ElementNotFoundException, PersistenceException { -        String sql = -                "SELECT a.id, b.name, b.constructionType, b.type, a.status, b.hasNef" -                        + " FROM Vehicle a" -                        + " INNER JOIN VehicleVersion b" -                        + " ON version = b.id" -                        + " WHERE a.id = ?"; - -        try { -            Connection con = jdbcConnectionManager.getConnection(); -            try (PreparedStatement pstmt = con.prepareStatement(sql)) { -                pstmt.setLong(1, id); - -                try (ResultSet rs = pstmt.executeQuery()) { -                    if (!rs.first()) throw new ElementNotFoundException("No such vehicle exists"); - -                    return vehicleFromRS(rs); -                } -            } -        } catch (SQLException e) { -            throw new PersistenceException(e); -        } -    } - -    @Override -    public void remove(long id) throws ElementNotFoundException, PersistenceException {} - -    private Vehicle vehicleFromRS(ResultSet rs) throws SQLException, PersistenceException { -        return Vehicle.builder() -                .id(rs.getLong("Vehicle.id")) -                .name(rs.getString("name")) -                .constructionType(ConstructionType.values()[rs.getInt("constructionType")]) -                .type(VehicleType.valueOf(rs.getString("type"))) -                .status(Status.values()[rs.getInt("status")]) -                .hasNef(rs.getBoolean("hasNef")) -                .registrations(registrationDatabaseDao.list(rs.getLong("id"))) -                .build(); -    } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java new file mode 100644 index 0000000..212dba6 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java @@ -0,0 +1,281 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.OperationService; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import java.io.IOException; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.Arrays; +import java.util.Collection; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.FlowPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class ArchiveOperationController { + +    private static final Logger LOG = LoggerFactory.getLogger(ArchiveOperationController.class); +    @FXML private TextField txtSearch; + +    @FXML private ImageView imvVehicleDetail; +    @FXML private Label lblStatus; +    @FXML private AnchorPane apMainDetails; +    @FXML private Label lblOperations; +    @FXML private Label lblCompleted; +    @FXML private Label lblCancelled; +    @FXML private AnchorPane backApMain; +    @FXML private AnchorPane backApDetails; +    @FXML private AnchorPane archiveOperationAP; +    @FXML private AnchorPane apDetails; +    @FXML private Label lblCodeHeader; +    @FXML private Label lblOpCode; +    @FXML private Label lblVehicles; +    @FXML private Label lblDate; +    @FXML private Label lblAddress; +    @FXML private FlowPane fpVehicles; +    private final OperationService operationService; +    @FXML private FlowPane archiveOperationFlowPane; +    private final CreateOperationController createOperationController; +    private Set<Operation> list = new HashSet<>(); +    private final SpringFXMLLoader fxmlLoader; + +    public ArchiveOperationController( +            OperationService operationService, +            CreateOperationController createOperationController, +            SpringFXMLLoader fxmlLoader) { +        this.operationService = operationService; +        this.createOperationController = createOperationController; +        this.fxmlLoader = fxmlLoader; +    } + +    @FXML +    private void initialize() { +        update(); +    } + +    public void update() { +        archiveOperationFlowPane.getChildren().clear(); +        list.clear(); +        try { +            list.addAll(operationService.list(EnumSet.of(Status.CANCELLED, Status.COMPLETED))); +            long cancelledAmount = 0; +            long completedAmount = 0; +            for (Operation operation : list) { +                if (operation.status() == Status.CANCELLED) cancelledAmount++; +                else completedAmount++; +            } +            lblCancelled.setText("storniert: " + cancelledAmount); +            lblCompleted.setText("abgeschlossen: " + completedAmount); +            lblOperations.setText("Einsätze: " + list.size()); +        } catch (ServiceException e) { +            LOG.error("ServiceException in update().", e); +            showServiceExceptionAlertAndWait("Die Einsätze konnten nicht geladen werden!"); +            ; +        } +        setFlowPane(list); +    } + +    public void update(Set<Operation> operations) { +        long cancelledAmount = 0; +        long completedAmount = 0; +        for (Operation operation : operations) { +            if (operation.status() == Status.CANCELLED) cancelledAmount++; +            else completedAmount++; +        } +        lblCancelled.setText("storniert: " + cancelledAmount); +        lblCompleted.setText("abgeschlossen: " + completedAmount); +        lblOperations.setText("Einsätze: " + operations.size()); +        setFlowPane(operations); +    } + +    private void setFlowPane(Set<Operation> operations) { +        try { +            archiveOperationFlowPane.getChildren().clear(); +            for (Operation operation : sortSet(operations)) { +                OperationInArchiveController opInAController = +                        OperationInArchiveController.create(); +                opInAController.set(operation); +                opInAController +                        .getRoot() +                        .setOnMouseClicked( +                                event -> { +                                    detailOperation = operation; +                                    backApMain.setVisible(false); +                                    apMainDetails.setVisible(false); +                                    backApDetails.setVisible(true); +                                    setOperation(); +                                    setDetailsVisible(true); +                                    imvVehicleDetail.setImage(new Image("/images/Vehicle.png")); +                                }); +                archiveOperationFlowPane.getChildren().add(opInAController.getRoot()); +            } +        } catch (IOException e) { +            LOG.error("IOException in setFlowPane(). ", e); +            showServiceExceptionAlertAndWait("Die Elemente konnten nicht geladen werden!"); +        } +    } + +    private Operation detailOperation; + +    private List<Operation> sortSet(Set<Operation> operationsSet) { +        Operation[] array = operationsSet.toArray(new Operation[operationsSet.size()]); +        for (int i = array.length - 1; i > 0; i--) { +            for (int j = 0; j < i; j++) { +                LocalDateTime first = +                        LocalDateTime.ofInstant( +                                Objects.requireNonNull(array[j].created()), ZoneOffset.UTC); +                LocalDateTime second = +                        LocalDateTime.ofInstant( +                                Objects.requireNonNull(array[j + 1].created()), ZoneOffset.UTC); +                if (first.isBefore(second)) { +                    Operation help = array[j]; +                    array[j] = array[j + 1]; +                    array[j + 1] = help; +                } +            } +        } +        return Arrays.asList(array); +    } + +    private void setOperation() { +        lblCodeHeader.setText(detailOperation.opCode()); +        if (detailOperation.created() != null) { +            LocalDateTime dateTime = +                    LocalDateTime.ofInstant( +                            Objects.requireNonNull(detailOperation.created()), ZoneOffset.UTC); +            lblDate.setText( +                    "am " +                            + dateTime.getDayOfMonth() +                            + "." +                            + dateTime.getMonth().getValue() +                            + "." +                            + dateTime.getYear()); +        } else { +            lblDate.setText("---"); +        } +        lblStatus.setText( +                "Status: " +                        + (detailOperation.status() == Status.CANCELLED +                                ? "storniert" +                                : "abgeschlossen")); +        lblOpCode.setText(detailOperation.opCode()); +        Collection<String> elements = +                detailOperation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList()); +        String result = String.join(", ", elements); + +        lblVehicles.setText(result); +        lblAddress.setText(detailOperation.destination()); + +        fpVehicles.getChildren().clear(); +        try { +            for (Vehicle vehicle : detailOperation.vehicles()) { +                DetailArchiveOperationController controller = null; + +                controller = DetailArchiveOperationController.create(fxmlLoader); + +                controller.set(vehicle, detailOperation); +                fpVehicles.getChildren().add(controller.getRoot()); +            } +        } catch (IOException e) { +            LOG.error("IOException in setOperation(). ", e); +            showServiceExceptionAlertAndWait("Die Element konnte nicht geladen werden!"); +        } +    } + +    private void setDetailsVisible(boolean b) { +        apDetails.setVisible(b); +    } + +    public void backClicked() { +        LOG.debug("Hyperlink \"Zurück\" in archive detail view clicked."); +        fpVehicles.getChildren().clear(); +        setDetailsVisible(false); +        backApDetails.setVisible(false); +        apMainDetails.setVisible(true); +        backApMain.setVisible(true); +    } + +    public void backToMain() { +        LOG.debug("Hyperlink \"Zurück\" in archive main view clicked."); +        this.setVisible(false); +        createOperationController.setVisible(true); +    } + +    void setVisible(boolean b) { +        archiveOperationAP.setVisible(b); +        backApMain.setVisible(b); +        apMainDetails.setVisible(b); +    } + +    @FXML +    public void searchInput() { +        LOG.debug("Search for operations in archive detail view started."); +        String text = txtSearch.getText(); +        Set<Operation> chosenOperations = new HashSet<>(); +        if (emptyText(text)) update(); +        else { +            for (Operation operation : list) { +                if (checkEquality(operation, text)) chosenOperations.add(operation); +            } +            update(chosenOperations); +        } +    } + +    private boolean emptyText(String text) { +        if (text == null) return true; +        text = text.replaceAll("\\s+", ""); +        return text.isEmpty(); +    } + +    private boolean checkEquality(Operation operation, String text) { +        if (isEqual(text, operation.opCode()) +                || isEqual(text, operation.destination()) +                || isEqual(text, reformDateToString(operation.created()))) return true; +        for (Vehicle vehicle : operation.vehicles()) { +            if (isEqual(text, vehicle.name())) return true; +        } +        return false; +    } + +    private String reformDateToString(Instant time) { +        LocalDateTime dateTime = +                LocalDateTime.ofInstant(Objects.requireNonNull(time), ZoneOffset.UTC); +        return "am " +                + dateTime.getDayOfMonth() +                + "." +                + dateTime.getMonth().getValue() +                + "." +                + dateTime.getYear(); +    } + +    private boolean isEqual(String text, String realText) { +        for (int i = 0; (i + text.length()) < realText.length(); i++) { +            StringBuilder result = new StringBuilder(); +            for (int j = i; j < i + text.length(); j++) { +                result.append(realText.charAt(j)); +            } +            if ((text.toLowerCase()).equals(result.toString().toLowerCase())) return true; +        } +        return false; +    } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java new file mode 100644 index 0000000..4da46a2 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java @@ -0,0 +1,231 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showSuccessAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; +import java.io.IOException; +import java.util.EnumSet; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javafx.collections.FXCollections; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ChoiceBox; +import javafx.scene.input.MouseButton; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.FlowPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class CreateCarController { + +    @FXML private AnchorPane createCarAP; +    @FXML private ChoiceBox<String> cmbCtype; +    @FXML private ChoiceBox<String> cmbTyp; + +    @FXML private Button btnCreate; +    @FXML private CheckBox cbxNEF; +    @FXML private FlowPane fpVehicleList; +    private final CreateOperationController createOperationController; + +    private static final Logger LOG = LoggerFactory.getLogger(CreateCarController.class); +    private final VehicleService vehicleService; +    private boolean update = false; +    private long vid = -1; + +    private Vehicle chooseVehicle; + +    public CreateCarController( +            CreateOperationController createOperationController, VehicleService vehicleService) { +        this.createOperationController = createOperationController; +        this.vehicleService = vehicleService; +    } + +    @FXML +    private void initialize() { +        fpVehicleList.setHgap(5); +        fpVehicleList.setVgap(5); + +        cmbCtype.setItems( +                FXCollections.observableArrayList( +                        Stream.of( +                                        ConstructionType.NORMAL, +                                        ConstructionType.MITTELHOCHDACH, +                                        ConstructionType.HOCHDACH) +                                .map(Enum::toString) +                                .collect(Collectors.toList()))); +        cmbCtype.setValue(ConstructionType.NORMAL.toString()); +        cmbTyp.setItems( +                FXCollections.observableArrayList( +                        Stream.of( +                                        VehicleType.BKTW, +                                        VehicleType.KTW_B, +                                        VehicleType.KTW, +                                        VehicleType.RTW, +                                        VehicleType.NEF, +                                        VehicleType.NAH) +                                .map(Enum::toString) +                                .collect(Collectors.toList()))); +        cmbTyp.setValue(VehicleType.BKTW.toString()); + +        updateVehiclePane(); +    } + +    @FXML +    private void createCar(ActionEvent actionEvent) { + +        if (!update) { +            LOG.debug("Button \"Erstellen\" clicked."); +            Vehicle vehicle = +                    Vehicle.builder() +                            .constructionType(parseConstructionType()) +                            .type(parseType()) +                            .name("") +                            .status(Status.ABGEMELDET) +                            .hasNef(cbxNEF.isSelected()) +                            .build(); +            try { +                vehicleService.add(vehicle); +                setToStart(); +            } catch (InvalidVehicleException e) { +                LOG.debug("Validation of Vehicle failed"); +                showValidationErrorAlertAndWait(e.getMessage()); +                setToStart(); +                return; +            } catch (ServiceException e) { +                LOG.error("ServiceException in createCar(). ", e); +                showServiceExceptionAlertAndWait( +                        "Ein Fehler beim Erstellen des Fahrzeuges ist aufgetreten."); +                setToStart(); +                return; +            } +            showSuccessAlertAndWait("Auto wurde erfolgreich angelegt."); +        } else { +            LOG.debug("Button \"Speichern\" clicked."); +            try { +                Vehicle vehicle = +                        Vehicle.builder() +                                .id(vid) +                                .constructionType(parseConstructionType()) +                                .type(parseType()) +                                .name("") +                                .status(Status.ABGEMELDET) +                                .hasNef(cbxNEF.isSelected()) +                                .build(); +                vehicleService.update(vehicle); +                setToStart(); +                chooseVehicle = null; +            } catch (InvalidVehicleException e) { +                LOG.debug("Validation of Vehicle failed"); +                showValidationErrorAlertAndWait(e.getMessage()); +                setToStart(); +                return; +            } catch (ServiceException e) { +                LOG.error("ServiceException in createCar(). ", e); +                showServiceExceptionAlertAndWait(e.getMessage()); +                setToStart(); +                return; +            } +            showSuccessAlertAndWait("Auto wurde erfolgreich bearbeitet."); +        } + +        updateVehiclePane(); +    } + +    private ConstructionType parseConstructionType() { +        if (cmbCtype.getSelectionModel().getSelectedItem() == null) { +            return ConstructionType.NORMAL; +        } +        return ConstructionType.valueOf(cmbCtype.getSelectionModel().getSelectedItem()); +    } + +    private VehicleType parseType() { +        if (cmbTyp.getSelectionModel().getSelectedItem() == null) { +            return VehicleType.BKTW; +        } +        return VehicleType.valueOf(cmbTyp.getSelectionModel().getSelectedItem()); +    } + +    private void setToStart() { +        btnCreate.setText("Erstellen"); +        cbxNEF.setSelected(false); +        cmbTyp.setValue(VehicleType.BKTW.name()); +        cmbCtype.setValue(ConstructionType.NORMAL.name()); +        update = false; +    } + +    private void updateVehicle(Vehicle vehicle) { + +        cmbCtype.setValue(vehicle.constructionType().name()); +        cmbTyp.setValue(vehicle.type().name()); +        cbxNEF.setSelected(vehicle.hasNef()); +        btnCreate.setText("Speichern"); +        vid = vehicle.id(); +        update = true; +        chooseVehicle = vehicle; +    } + +    public void setVisible(boolean b) { +        createCarAP.setVisible(b); +    } + +    @FXML +    private void backToMain() { +        LOG.debug("Hyperlink \"zurück\" clicked."); +        this.setVisible(false); +        createOperationController.setVisible(true); +    } + +    void updateVehiclePane() { +        try { +            fpVehicleList.getChildren().clear(); + +            Set<Vehicle> vehicles; + +            vehicles = vehicleService.list(EnumSet.of(Status.ABGEMELDET)); + +            for (Vehicle vehicle : vehicles) { +                VehiclePaneController controller = VehiclePaneController.createVehiclePane(); + +                controller.setData(vehicle, false, false); +                controller +                        .getRootElement() +                        .setOnMouseClicked( +                                event -> { +                                    if (event.getButton().equals(MouseButton.PRIMARY)) { +                                        if (chooseVehicle == null || vehicle == chooseVehicle) { +                                            if (update == false) { +                                                chooseVehicle = vehicle; +                                                updateVehicle(vehicle); +                                                controller.setSelected(true); +                                            } else { +                                                setToStart(); +                                                controller.setSelected(false); + +                                                chooseVehicle = null; +                                            } +                                        } +                                    } +                                }); + +                fpVehicleList.getChildren().add(controller.getRootElement()); +            } +        } catch (ServiceException | IOException e) { +            LOG.error("Exception in updateVehiclePane(). ", e); +            showServiceExceptionAlertAndWait(e.getMessage()); +        } +    } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewEmployeeController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeController.java index 15282cc..3e0240c 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/missioncontrol/controller/CreateNewEmployeeController.java @@ -1,24 +1,24 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showSuccessAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; -import at.ac.tuwien.sepm.assignment.groupphase.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.exception.InvalidEmployeeException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.EmployeeService;  import at.ac.tuwien.sepm.assignment.groupphase.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.Label; @@ -32,7 +32,7 @@ import org.springframework.stereotype.Controller;  @Scope("prototype")  public class CreateNewEmployeeController { -    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); +    private static final Logger LOG = LoggerFactory.getLogger(CreateNewEmployeeController.class);      private final EmployeeService employeeService;      @FXML private Label lblHeader; @@ -80,6 +80,7 @@ public class CreateNewEmployeeController {      @FXML      private void onCancelClicked() { +        LOG.debug("Hyperlink \"abbrechen\" clicked.");          if (consumerCancelClicked != null) {              consumerCancelClicked.run();          } @@ -87,6 +88,7 @@ public class CreateNewEmployeeController {      @FXML      private void onCreateClicked() { +        LOG.debug("Button {} clicked.", btnCreate.getText());          employee =                  employee.toBuilder() @@ -104,40 +106,24 @@ public class CreateNewEmployeeController {                  employeeService.add(employee);              }          } catch (InvalidEmployeeException e) { -            LOG.error("Invalid Employee: {}", e); - -            showModalDialogWithOkButton( -                    AlertType.ERROR, -                    "Ungültige Eingabe", -                    "Mindestens eines der Eingabefelder haben einen ungültigen Wert!"); +            LOG.debug("Validation for Employee failed"); +            showValidationErrorAlertAndWait(e.getMessage());              return;          } catch (ServiceException e) { -            LOG.error("Employee could not be saved: {}", e); - -            showModalDialogWithOkButton( -                    AlertType.ERROR, -                    "Speicherfehler", +            LOG.error("ServiceException in onCreateClicked(). ", e); +            showServiceExceptionAlertAndWait(                      "Der Eintrag konnte nicht gespeichert werden. Bitte versuchen Sie es erneut.");              return;          } -        showModalDialogWithOkButton( -                AlertType.INFORMATION, -                "Erfolgreich angelegt", -                "Mitarbeiter wurde erfolgreich angelegt und gespeichert!"); +        showSuccessAlertAndWait( +                "Der/die MitarbeiterIn wurde erfolgreich angelegt und gespeichert!");          if (consumerCreateClicked != null) {              consumerCreateClicked.run();          }      } -    private void showModalDialogWithOkButton( -            AlertType alertType, String headerText, String contentText) { -        Alert alert = new Alert(alertType, contentText, ButtonType.OK); -        alert.setHeaderText(headerText); -        alert.showAndWait(); -    } -      private EducationLevel parseEducationLevel() {          if (inputQualification.getSelectionModel().getSelectedItem() == null) {              return EducationLevel.RS; @@ -152,7 +138,6 @@ public class CreateNewEmployeeController {          inputQualification.setValue(employee.educationLevel().name());          inputIsDriver.setSelected(employee.isDriver());          inputIsPilot.setSelected(employee.isPilot()); -          lblHeader.setText("Person bearbeiten");          btnCreate.setText("Speichern");      } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java index 57759e3..f06b43f 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateOperationController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java @@ -1,31 +1,26 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showSuccessAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.OperationService; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.VehicleService;  import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidRegistrationException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.OperationService; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.RegistrationService; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService;  import java.io.IOException; -import java.lang.invoke.MethodHandles; -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.ArrayList;  import java.util.EnumSet;  import java.util.LinkedList; -import java.util.List;  import java.util.Set;  import javafx.collections.FXCollections; -import javafx.event.ActionEvent;  import javafx.fxml.FXML; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType;  import javafx.scene.control.Button;  import javafx.scene.control.ContextMenu;  import javafx.scene.control.Label; @@ -38,7 +33,7 @@ import javafx.scene.input.KeyEvent;  import javafx.scene.input.MouseButton;  import javafx.scene.layout.AnchorPane;  import javafx.scene.layout.FlowPane; -import javafx.stage.Stage; +import javafx.scene.layout.GridPane;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory;  import org.springframework.stereotype.Controller; @@ -46,9 +41,10 @@ import org.springframework.stereotype.Controller;  @Controller  public class CreateOperationController { -    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); +    private static final Logger LOG = LoggerFactory.getLogger(CreateOperationController.class);      public AnchorPane apCreateOperation; +    @FXML private GridPane grdWindowContainer;      @FXML private TextField txtCode;      @FXML private TextField txtAddress;      @FXML private TextField txtNote; @@ -58,40 +54,33 @@ public class CreateOperationController {      @FXML private Label lblChosenVehicles;      @FXML private AnchorPane apInvisible;      @FXML private OperationDetailsController operationDetailsController; +    @FXML private ManageEmployeesController manageEmployeesController; +    @FXML private CreateCarController createCarController; +    @FXML private RegistrationWindowController registrationWindowController; +    @FXML private ArchiveOperationController archiveOperationController;      @FXML private FlowPane fpVehicles;      private LinkedList<Vehicle> chosenVehicles = new LinkedList<>();      private final OperationService operationService;      private final VehicleService vehicleService; -    private final SpringFXMLLoader fxmlLoader; +    private final RegistrationService registrationService;      public CreateOperationController(              OperationService operationService,              VehicleService vehicleService, -            SpringFXMLLoader fxmlLoader) { +            RegistrationService registrationService) {          this.operationService = operationService;          this.vehicleService = vehicleService; -        this.fxmlLoader = fxmlLoader; +        this.registrationService = registrationService;      }      @FXML      private void initialize() { +          lblChosenVehicles.setText("keine ausgewählt"); -        lvActiveOperations.setCellFactory( -                param -> -                        new ListCell<>() { -                            @Override -                            protected void updateItem(Operation item, boolean empty) { -                                super.updateItem(item, empty); +        lvActiveOperations.setCellFactory(param -> generateOpCodeListItem()); -                                if (empty || item == null || item.opCode() == null) { -                                    setText(null); -                                } else { -                                    setText(item.opCode()); -                                } -                            } -                        });          lvActiveOperations.setOnMouseClicked(                  event -> {                      if (event.getClickCount() == 2) { @@ -101,6 +90,12 @@ public class CreateOperationController {                          openDetailsWindow(lvActiveOperations.getSelectionModel().getSelectedItem());                      }                  }); + +        setVisible(true); +        createCarController.setVisible(false); +        registrationWindowController.setVisible(false); + +        updateList();      }      public void updateList() { @@ -120,13 +115,16 @@ public class CreateOperationController {              for (Vehicle vehicle : vehicles) {                  VehiclePaneController controller = VehiclePaneController.createVehiclePane(); -                controller.setData(vehicle, true); +                controller.setData(vehicle, true, false);                  controller                          .getRootElement()                          .setOnMouseClicked(                                  event -> {                                      if (event.getButton().equals(MouseButton.SECONDARY)) { -                                        createContextMenu(vehicle, vehicleService) +                                        createContextMenu( +                                                        vehicle, +                                                        vehicleService, +                                                        registrationService)                                                  .show(                                                          controller.getRootElement(),                                                          event.getScreenX(), @@ -157,37 +155,36 @@ public class CreateOperationController {                                      }                                  }); +                if (chosenVehicles.stream().anyMatch(v -> v.id() == vehicle.id())) +                    controller.setSelected(true); +                  fpVehicles.getChildren().add(controller.getRootElement());              } -        } catch (ServiceException | IOException | InvalidOperationException e) { -            LOG.error("Error while updating list.", e); - -            Alert alert = new Alert(Alert.AlertType.ERROR); -            alert.setTitle("Fehler"); -            alert.setHeaderText("Fehler!"); -            alert.setContentText(e.getMessage()); -            alert.showAndWait(); +        } catch (ServiceException | IOException e) { +            LOG.error("Exception in updateList(). ", e); +            showServiceExceptionAlertAndWait( +                    "Beim Erstellen des Ranking ist ein Fehler aufgetreten."); +        } catch (InvalidOperationException e) { +            LOG.debug("Validation error in updateList(). ", e); +            showValidationErrorAlertAndWait(e.getMessage());          }          try {              lvActiveOperations.setItems(                      FXCollections.observableArrayList(                              operationService.list(EnumSet.of(Status.ACTIVE))));          } catch (ServiceException e) { -            Alert alert = new Alert(Alert.AlertType.ERROR); -            alert.setTitle("Fehler - Einsätze"); -            alert.setHeaderText("Beim Holen der aktiven Einsätze ist ein Fehler aufgetreten."); -            alert.setContentText(e.getMessage()); -            alert.showAndWait(); +            LOG.error("ServiceException in updateList(). ", e); +            showServiceExceptionAlertAndWait( +                    "Beim Holen der aktiven Einsätze ist ein Fehler aufgetreten");          }      } -    private ContextMenu createContextMenu(Vehicle data, VehicleService vehicleService) { +    private ContextMenu createContextMenu( +            Vehicle data, VehicleService vehicleService, RegistrationService registrationService) {          ContextMenu menu = new ContextMenu();          for (Vehicle.Status status : Vehicle.Status.values()) { -            if (status == Vehicle.Status.ABGEMELDET) { -                continue; -            } +            if (status == Vehicle.Status.ABGEMELDET) continue;              MenuItem mi = new MenuItem(status.name()); @@ -202,10 +199,15 @@ public class CreateOperationController {                          try {                              vehicleService.update(data.toBuilder().status(status).build());                              this.updateList(); -                        } catch (InvalidVehicleException | ServiceException e) { -                            LOG.error("Error while setting status.", e); -                            Alert a = new Alert(AlertType.ERROR, e.getMessage()); -                            a.show(); +                        } catch (InvalidVehicleException e) { +                            LOG.debug( +                                    "Validation error in createContextMenu(). (mi.setOnAction) ", +                                    e); +                            showValidationErrorAlertAndWait(e.getMessage()); +                        } catch (ServiceException e) { +                            LOG.error("Exception in createContextMenu(). (mi.setOnAction) ", e); +                            showServiceExceptionAlertAndWait( +                                    "Beim Aktualisieren der Fahrzeuge ist ein Fehler aufgetreten.");                          }                      }); @@ -217,35 +219,23 @@ public class CreateOperationController {          abmelden.setOnAction(                  event -> {                      try { -                        List<Registration> registrations = data.registrations(); -                        assert registrations -                                != null; // Otherwise the element shouldn't be in the list. +                        if (data.registrations() == null) return; -                        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); -                        } +                        for (Registration registration : data.registrations()) +                            registrationService.remove(registration.id());                          vehicleService.update( -                                data.toBuilder() -                                        .registrations(newRegistrations) -                                        .status(Vehicle.Status.ABGEMELDET) -                                        .build()); - +                                data.toBuilder().status(Vehicle.Status.ABGEMELDET).build());                          this.updateList(); -                    } catch (InvalidVehicleException | ServiceException e) { -                        LOG.error("Error while unregistering.", e); -                        Alert a = new Alert(AlertType.ERROR, e.getMessage()); -                        a.show(); +                    } catch (InvalidVehicleException | InvalidRegistrationException e) { +                        LOG.debug( +                                "Validation error in createContextMenu(). (abmelden.setOnAction) ", +                                e); +                        showValidationErrorAlertAndWait(e.getMessage()); +                    } catch (ServiceException e) { +                        LOG.error("Exception in createContextMenu(). (abmelden.setOnAction) ", e); +                        showServiceExceptionAlertAndWait( +                                "Beim Aktualisieren der Fahrzeuge ist ein Fehler aufgetreten.");                      }                  }); @@ -255,6 +245,7 @@ public class CreateOperationController {      @FXML      protected void createOperationClicked() { +        LOG.debug("Button \"Erstellen\" clicked.");          Vehicle[] vehicles = new Vehicle[chosenVehicles.size()];          for (int i = 0; i < chosenVehicles.size(); i++) {              vehicles[i] = chosenVehicles.get(i); @@ -269,19 +260,17 @@ public class CreateOperationController {                          .build();          try {              operationService.add(operation); -        } catch (ServiceException | InvalidOperationException e) { -            Alert alert = new Alert(Alert.AlertType.ERROR); -            alert.setTitle("Fehler"); -            alert.setHeaderText("Fehler!"); -            alert.setContentText(e.getMessage()); -            alert.showAndWait(); +        } catch (ServiceException e) { +            LOG.error("Exception in createOperationClicked(). ", e); +            showServiceExceptionAlertAndWait( +                    "Beim Erstellen des Einsatzes ist ein Fehler aufgetreten."); +            return; +        } catch (InvalidOperationException e) { +            LOG.debug("Validation error in createOperationClicked(). ", e); +            showValidationErrorAlertAndWait(e.getMessage());              return;          } -        Alert alert = new Alert(AlertType.CONFIRMATION); -        alert.setTitle("Erfolg"); -        alert.setHeaderText("Erfolgreich gespeichert"); -        alert.setContentText("Der Einsatz wurde erfolgreich gespeichert."); -        alert.showAndWait(); +        showSuccessAlertAndWait("Der Einsatz wurde erfolgreich gespeichert.");          updateList();          lblChosenVehicles.setText("keine ausgewählt");          txtAddress.setText(""); @@ -290,76 +279,83 @@ public class CreateOperationController {          chosenVehicles = new LinkedList<>();      } -    public void onRegistrationLinkClicked(ActionEvent actionEvent) { -        openNewWindow("RegistrationWindow.fxml"); +    @FXML +    private void onRegistrationLinkClicked() { +        LOG.debug("Hyperlink \"Anmeldungen\" clicked."); +        openRegistrationWindow();      } -    public void onEmployeeLinkClicked(ActionEvent actionEvent) { -        openNewWindow("listEmployees.fxml"); +    @FXML +    private void onEmployeeLinkClicked() { +        LOG.debug("Hyperlink \"Personen\" clicked."); +        openCreateNewEmployeeWindow();      } -    public void onVehicleLinkClicked(ActionEvent actionEvent) { -        openNewWindow("createCar.fxml"); +    @FXML +    private void onVehicleLinkClicked() { +        LOG.debug("Hyperlink \"Fahrzeuge\" clicked."); +        openCreateCarWindow();      } -    public void onArchivLinkClicked() { -        openNewArchivWindow(); +    @FXML +    private void onArchivLinkClicked() { +        LOG.debug("Hyperlink \"Archiv\" clicked."); +        archiveOperationController.update(); +        openArchivWindow();      } -    private void openNewArchivWindow() { -        Stage stage = new Stage(); -        try { -            stage.setScene( -                    new Scene( -                            (Parent) -                                    fxmlLoader.load( -                                            getClass() -                                                    .getResourceAsStream( -                                                            "/fxml/ArchiveOperation.fxml")))); -        } catch (IOException e) { -            LOG.error("Could not open new window: {}", e); -        } -        stage.setTitle("Einsatz erstellen"); -        stage.centerOnScreen(); -        stage.show(); -        updateList(); +    private void openArchivWindow() { +        archiveOperationController.setVisible(true); +        this.setVisible(false);      } -    private void openNewWindow(String fxmlFileName) { +    void setVisible(boolean b) { +        apInvisible.setVisible(!b); +        grdWindowContainer.setVisible(!b); -        Stage stage = new Stage(); -        try { -            stage.setScene( -                    new Scene( -                            (Parent) -                                    fxmlLoader.load( -                                            getClass() -                                                    .getResourceAsStream( -                                                            "/fxml/" + fxmlFileName)))); -        } catch (IOException e) { -            LOG.error("Could not open new window: {}", e); -        } +        // if (b) updateList(); +    } -        stage.setTitle("Ressourcenverwaltung"); -        stage.centerOnScreen(); -        stage.showAndWait(); // important to call wait so that updateList is executed afterwards +    private void openDetailsWindow(Operation operation) { +        operationDetailsController.initOperation(operation); +        this.setVisible(false); +    } -        updateList(); +    private void openCreateNewEmployeeWindow() { +        this.setVisible(false); +        manageEmployeesController.setVisible(true);      } -    void setVisible(boolean b) { -        apInvisible.setVisible(!b); +    private void openCreateCarWindow() { +        this.setVisible(false); +        createCarController.setVisible(true); +        createCarController.updateVehiclePane();      } -    private void openDetailsWindow(Operation operation) { -        operationDetailsController.initOperation(operation); +    private void openRegistrationWindow() {          this.setVisible(false); +        registrationWindowController.setVisible(true);      }      @FXML -    public void onOperationCodeChanged(KeyEvent keyEvent) { +    private void onOperationCodeChanged(KeyEvent keyEvent) {          if (keyEvent.getCode() == KeyCode.ENTER) {              updateList();          }      } + +    static ListCell<Operation> generateOpCodeListItem() { +        return new ListCell<>() { +            @Override +            protected void updateItem(Operation item, boolean empty) { +                super.updateItem(item, empty); + +                if (empty || item == null || item.opCode() == null) { +                    setText(null); +                } else { +                    setText(item.opCode()); +                } +            } +        }; +    }  } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CustomListItemController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CustomListItemController.java new file mode 100644 index 0000000..ced0c10 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CustomListItemController.java @@ -0,0 +1,24 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import javafx.scene.Node; + +public abstract class CustomListItemController { + +    protected Node rootElement; + +    public Node getRootElement() { +        return rootElement; +    } + +    public void setSelected(boolean selected) { +        rootElement.getStyleClass().clear(); + +        if (selected) { +            rootElement.getStyleClass().add("bg-yellow"); +            rootElement.getStyleClass().add("shadowed"); +        } else { +            rootElement.getStyleClass().add("bg-white"); +            rootElement.getStyleClass().add("shadowed"); +        } +    } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/DetailArchiveOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/DetailArchiveOperationController.java new file mode 100644 index 0000000..a866653 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/DetailArchiveOperationController.java @@ -0,0 +1,96 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; +import java.io.IOException; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.layout.VBox; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class DetailArchiveOperationController { +    private static final Logger LOG = +            LoggerFactory.getLogger(DetailArchiveOperationController.class); + +    @FXML private VBox vBoxVehicle; +    @FXML private VBox vBoxPeople; +    private final SpringFXMLLoader fxmlLoader; + +    public DetailArchiveOperationController(SpringFXMLLoader fxmlLoader) { +        this.fxmlLoader = fxmlLoader; +    } + +    static DetailArchiveOperationController create(SpringFXMLLoader fxmlLoader) throws IOException { +        FXMLWrapper<Object, DetailArchiveOperationController> wrapper = +                fxmlLoader.loadAndWrap( +                        "/fxml/DetailArchiveOperation.fxml", +                        DetailArchiveOperationController.class); + +        Node root = (Node) wrapper.getLoadedObject(); +        DetailArchiveOperationController result = wrapper.getController(); +        result.rootElement = root; + +        return result; +    } + +    public Node getRoot() { +        return rootElement; +    } + +    private Node rootElement; + +    public void set(Vehicle vehicle, Operation operation) { +        VehiclePaneController controller; +        try { +            controller = VehiclePaneController.createVehiclePane(); +            controller.setData(vehicle, false, false); +            vBoxVehicle.getChildren().add(controller.getRootElement()); +        } catch (IOException e) { +            LOG.error("IOException in set(Vehicle). (vBoxVehicle) ", e); +            showServiceExceptionAlertAndWait( +                    "Ein interner Fehler ist aufgetreten. Bitte wenden Sie sich an den/die SystemadministratorIn."); +        } +        try { +            List<Registration> registrations = +                    Objects.requireNonNull(vehicle.registrations()) +                            .stream() +                            .filter( +                                    registration -> +                                            registration +                                                            .start() +                                                            .isBefore( +                                                                    Objects.requireNonNull( +                                                                            operation.created())) +                                                    && registration +                                                            .end() +                                                            .isAfter( +                                                                    Objects.requireNonNull( +                                                                            operation.created()))) +                            .collect(Collectors.toList()); + +            for (Registration registration : registrations) { +                Employee employee = registration.employee(); +                EmployeeListItemController employeeListItemController = +                        EmployeeListItemController.createEmployeeListItemController( +                                fxmlLoader, employee); +                vBoxPeople.getChildren().add(employeeListItemController.getRootElement()); +            } +        } catch (IOException e) { +            LOG.error("IOException in set(Vehicle). (vBoxPeople) ", e); +            showServiceExceptionAlertAndWait( +                    "Ein interner Fehler ist aufgetreten. Bitte wenden Sie sich an den/die SystemadministratorIn."); +        } +    } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListController.java new file mode 100644 index 0000000..12f6bff --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListController.java @@ -0,0 +1,133 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; +import javafx.fxml.FXML; +import javafx.geometry.Insets; +import javafx.scene.Node; +import javafx.scene.layout.FlowPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Controller; + +@Controller +@Scope("prototype") +public class EmployeeListController { + +    private static final Logger LOG = LoggerFactory.getLogger(EmployeeListController.class); + +    @FXML private FlowPane flowPaneEmployeeList; + +    private Consumer<Employee> onEmployeeClicked; + +    private final SpringFXMLLoader fxmlLoader; +    private Node rootElement; +    private List<EmployeeListItemController> employeeListItemControllers; +    private Insets listItemMargins = new Insets(10, 5, 0, 5); + +    public EmployeeListController(SpringFXMLLoader fxmlLoader) { +        this.fxmlLoader = fxmlLoader; +        this.employeeListItemControllers = new ArrayList<>(); +    } + +    public void setListItemMargins(Insets value) { +        this.listItemMargins = value; +    } + +    public void setData(Set<Employee> employeeList) { +        setData(employeeList, null, null); +    } + +    public void setData(Set<Employee> employeeList, Consumer<Employee> onEmployeeClicked) { +        setData(employeeList, onEmployeeClicked, null); +    } + +    public void setData( +            Set<Employee> employeeList, +            Consumer<Employee> onEmployeeClicked, +            Consumer<EmployeeListItemController> onEmployeeListItemClicked) { + +        flowPaneEmployeeList.getChildren().clear(); +        employeeListItemControllers.clear(); +        employeeList.forEach( +                employee -> +                        addEmployeeToFlowPane( +                                employee, onEmployeeClicked, onEmployeeListItemClicked)); +    } + +    private void addEmployeeToFlowPane( +            Employee employee, +            Consumer<Employee> onEmployeeClicked, +            Consumer<EmployeeListItemController> onEmployeeListItemClicked) { + +        try { +            EmployeeListItemController controller = +                    EmployeeListItemController.createEmployeeListItemController( +                            fxmlLoader, employee); +            Node rootElement = controller.getRootElement(); +            flowPaneEmployeeList.getChildren().add(rootElement); +            employeeListItemControllers.add(controller); +            FlowPane.setMargin(rootElement, listItemMargins); +            if (onEmployeeClicked != null) { +                controller.setConsumerEmployeeClicked(onEmployeeClicked); +            } +            if (onEmployeeListItemClicked != null) { +                controller.setConsumerEmployeeListItemClicked( +                        employeeListItemController -> { +                            onEmployeeListItemClicked.accept(employeeListItemController); +                            if (this.onEmployeeClicked != null) { +                                this.onEmployeeClicked.accept( +                                        employeeListItemController.getEmployee()); +                            } +                        }); +            } +        } catch (IOException e) { +            LOG.error("IOException in addEmployeeToFlowPane. ", e); +        } +    } + +    private void setEmployeeSelected(Employee employee, boolean selected) { +        employeeListItemControllers +                .stream() +                .filter(controller -> controller.getEmployee().equals(employee)) +                .forEach(controller -> controller.setSelected(selected)); +    } + +    public void selectEmployee(Employee employee) { +        setEmployeeSelected(employee, true); +    } + +    public void deselectEmployee(Employee employee) { +        setEmployeeSelected(employee, false); +    } + +    public void deselectAllEmployees() { +        employeeListItemControllers.forEach( +                employeeListItemController -> employeeListItemController.setSelected(false)); +    } + +    public static EmployeeListController createEmployeeListController(SpringFXMLLoader loader) +            throws IOException { +        FXMLWrapper<Object, EmployeeListController> wrapper = +                loader.loadAndWrap("/fxml/employeeList.fxml", EmployeeListController.class); +        Node root = (Node) wrapper.getLoadedObject(); +        EmployeeListController controller = wrapper.getController(); +        controller.rootElement = root; +        return controller; +    } + +    public Node getRootElement() { +        return rootElement; +    } + +    public void setOnEmployeeClicked(Consumer<Employee> onEmployeeClicked) { +        this.onEmployeeClicked = onEmployeeClicked; +    } +} 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/missioncontrol/controller/EmployeeListItemController.java index 11b5626..d445b43 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/EmployeeListItemController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListItemController.java @@ -1,6 +1,6 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee;  import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader;  import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper;  import java.io.IOException; @@ -15,7 +15,7 @@ import org.springframework.stereotype.Controller;  @Controller  @Scope("prototype") -public class EmployeeListItemController { +public class EmployeeListItemController extends CustomListItemController {      @FXML private Label lblName;      @FXML private Label lblQualification; @@ -25,15 +25,24 @@ public class EmployeeListItemController {      @FXML private ImageView imgDriver;      @FXML private ImageView imgQualification; -    private Node rootElement;      private Employee employee; -    private Consumer<Employee> consumerEditEmployeeClicked; +    private Consumer<Employee> consumerEmployeeClicked; +    private Consumer<EmployeeListItemController> consumerEmployeeListItemClicked; + +    private static Image imageQualification = new Image("/images/Qualification.png"); +    private static Image imagePilot = new Image("/images/Pilot.png"); +    private static Image imageNotPilot = new Image("/images/NotPilot.png"); +    private static Image imageDriver = new Image("images/Driver.png"); +    private static Image imageNotDriver = new Image("images/NotDriver.png");      @FXML -    public void onEditEmployeeClicked() { -        if (consumerEditEmployeeClicked != null) { -            consumerEditEmployeeClicked.accept(employee); +    private void onEmployeeClicked() { +        if (consumerEmployeeClicked != null) { +            consumerEmployeeClicked.accept(employee); +        } +        if (consumerEmployeeListItemClicked != null) { +            consumerEmployeeListItemClicked.accept(this);          }      } @@ -43,13 +52,9 @@ public class EmployeeListItemController {          lblQualification.setText(employee.educationLevel().name());          lblPilot.setText(String.format("%s Pilot", employee.isPilot() ? "ist" : "nicht"));          lblDriver.setText(String.format("%s Fahrer", employee.isDriver() ? "ist" : "nicht")); -        imgQualification.setImage(new Image("/images/Qualification.png")); -        String imgSrcPilot = -                String.format("/images/%s", employee.isPilot() ? "Pilot.png" : "NotPilot.png"); -        imgPilot.setImage(new Image(imgSrcPilot)); -        String imgSrcDriver = -                String.format("/images/%s", employee.isDriver() ? "Driver.png" : "NotDriver.png"); -        imgDriver.setImage(new Image(imgSrcDriver)); +        imgQualification.setImage(imageQualification); +        imgPilot.setImage(employee.isPilot() ? imagePilot : imageNotPilot); +        imgDriver.setImage(employee.isDriver() ? imageDriver : imageNotDriver);      }      public static EmployeeListItemController createEmployeeListItemController( @@ -69,15 +74,16 @@ public class EmployeeListItemController {          return controller;      } -    public Node getRootElement() { -        return rootElement; -    } -      public Employee getEmployee() {          return employee;      } -    public void setConsumerEditEmployeeClicked(Consumer<Employee> consumerEditEmployeeClicked) { -        this.consumerEditEmployeeClicked = consumerEditEmployeeClicked; +    public void setConsumerEmployeeClicked(Consumer<Employee> consumerEmployeeClicked) { +        this.consumerEmployeeClicked = consumerEmployeeClicked; +    } + +    public void setConsumerEmployeeListItemClicked( +            Consumer<EmployeeListItemController> consumerEmployeeListItemClicked) { +        this.consumerEmployeeListItemClicked = consumerEmployeeListItemClicked;      }  } 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/missioncontrol/controller/FilterEmployeesController.java index 6d6214d..a31c3e3 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/FilterEmployeesController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/FilterEmployeesController.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller;  import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader;  import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; @@ -7,12 +7,15 @@ import java.util.function.Consumer;  import javafx.fxml.FXML;  import javafx.scene.Node;  import javafx.scene.control.TextField; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory;  import org.springframework.context.annotation.Scope;  import org.springframework.stereotype.Controller;  @Controller  @Scope("prototype")  public class FilterEmployeesController { +    private static final Logger LOG = LoggerFactory.getLogger(FilterEmployeesController.class);      @FXML private TextField inputFilterString; @@ -23,6 +26,7 @@ public class FilterEmployeesController {      @FXML      private void onAddEmployeeClicked() { +        LOG.debug("Button \"Person hinzufügen\" clicked.");          if (consumerAddEmployeeClicked != null) {              consumerAddEmployeeClicked.run();          } @@ -30,6 +34,7 @@ public class FilterEmployeesController {      @FXML      private void onFilterTextChanged() { +        LOG.debug("Filter text changed.");          if (consumerFilterTextChanged != null) {              consumerFilterTextChanged.accept(inputFilterString.getText());          } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/Helper.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/Helper.java new file mode 100644 index 0000000..f120eb6 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/Helper.java @@ -0,0 +1,34 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.ButtonType; + +public class Helper { + +    static final String ALERT_TITLE_VALIDATION_ERROR = "Validierungsfehler"; +    static final String ALERT_TITLE_SERVICE_EXCEPTION = "Fehler"; +    static final String ALERT_TITLE_SUCCESS = "Erfolg"; + +    private Helper() {} // SonarLint insisted to create a private constructor to hide the public one + +    static void showValidationErrorAlertAndWait(String message) { +        showAlertWithOkButtonAndWait(AlertType.ERROR, ALERT_TITLE_VALIDATION_ERROR, message); +    } + +    static void showServiceExceptionAlertAndWait(String message) { +        showAlertWithOkButtonAndWait(AlertType.ERROR, ALERT_TITLE_SERVICE_EXCEPTION, message); +    } + +    static void showSuccessAlertAndWait(String message) { +        showAlertWithOkButtonAndWait(AlertType.INFORMATION, ALERT_TITLE_SUCCESS, message); +    } + +    static void showAlertWithOkButtonAndWait( +            AlertType alertType, String headerText, String contentText) { +        Alert alert = new Alert(alertType, contentText, ButtonType.OK); +        alert.setTitle(headerText); +        alert.setHeaderText(headerText); +        alert.showAndWait(); +    } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ListEmployeesController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ManageEmployeesController.java index 25f1263..fa228de 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ListEmployeesController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ManageEmployeesController.java @@ -1,34 +1,38 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.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.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.EmployeeService;  import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader;  import java.io.IOException; -import java.lang.invoke.MethodHandles; +import java.util.HashSet; +import java.util.stream.Collectors;  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()); +public class ManageEmployeesController { +    private static final Logger LOG = LoggerFactory.getLogger(ManageEmployeesController.class); +    @FXML private AnchorPane listEmployeesAP;      @FXML private AnchorPane containerHeader; -    @FXML private FlowPane flowPaneEmployeeList; +    @FXML private EmployeeListController employeeListController;      private final EmployeeService employeeService;      private final SpringFXMLLoader fxmlLoader; -    public ListEmployeesController(EmployeeService employeeService, SpringFXMLLoader fxmlLoader) { +    private final CreateOperationController createOperationController; + +    public ManageEmployeesController( +            EmployeeService employeeService, +            SpringFXMLLoader fxmlLoader, +            CreateOperationController createOperationController) {          this.employeeService = employeeService;          this.fxmlLoader = fxmlLoader; +        this.createOperationController = createOperationController;      }      @FXML @@ -44,19 +48,21 @@ public class ListEmployeesController {              containerHeader.getChildren().add(filterEmployeesController.getRootElement());              filterEmployeesController.setOnFilterTextChangedListener(this::updateEmployeeList);              filterEmployeesController.setOnAddEmployeeClickedListener(this::openAddEmployee); -              updateEmployeeList();          } catch (IOException e) { -            LOG.error("Could not initialize controller: {}", e); +            LOG.error("IOException in openFilter().", e);          }      }      private void openAddEmployee() { +        employeeListController.deselectAllEmployees();          openEmployee(null);      }      private void openEditEmployee(Employee employee) { +        employeeListController.deselectAllEmployees(); +        employeeListController.selectEmployee(employee);          openEmployee(employee);      } @@ -73,7 +79,7 @@ public class ListEmployeesController {              createNewEmployeeController.setConsumerCancelClicked(this::openFilter);              createNewEmployeeController.setConsumerCreateClicked(this::openFilter);          } catch (IOException e) { -            LOG.error("Could not prepare UI for adding employee: {}", e); +            LOG.error("IOException in openEmployee(). ", e);          }      } @@ -82,36 +88,33 @@ public class ListEmployeesController {      }      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); +            employeeListController.setData( +                    employeeService +                            .list() +                            .stream() +                            .filter( +                                    employee -> +                                            searchString.trim().isEmpty() +                                                    || employee.name() +                                                            .toLowerCase() +                                                            .contains(searchString.toLowerCase())) +                            .collect(Collectors.toCollection(HashSet::new)), +                    this::openEditEmployee); +          } catch (ServiceException e) { -            LOG.error("Could not fetch employee list: {}", e); +            LOG.error("ServiceException in updateEmployeeList(). ", e);          }      } -    private void addEmployeeToFlowPane(Employee employee) { -        Insets listItemMargins = new Insets(0, 5, 10, 5); +    public void setVisible(boolean b) { +        listEmployeesAP.setVisible(b); +    } -        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); -        } +    public void backToMain() { +        LOG.debug("Hyperlink \"Zurück\" clicked."); +        this.setVisible(false); +        createOperationController.setVisible(true);      }  } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java new file mode 100644 index 0000000..daeaedd --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java @@ -0,0 +1,194 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showAlertWithOkButtonAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showSuccessAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.OperationService; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; +import java.io.IOException; +import java.util.Collection; +import java.util.EnumSet; +import java.util.Set; +import java.util.stream.Collectors; +import javafx.collections.FXCollections; +import javafx.fxml.FXML; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ListView; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.FlowPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class OperationDetailsController { +    private static final Logger LOG = LoggerFactory.getLogger(OperationDetailsController.class); + +    public Operation operation; +    private final OperationService operationService; +    private final VehicleService vehicleService; +    private final CreateOperationController createOperationController; +    @FXML private FlowPane fpVehicles; +    @FXML private FlowPane fpAdditional; +    @FXML private ListView<Operation> lvActiveOperations; +    @FXML private Label lblChosenVehicles; +    @FXML private Button btnCloseOperation; +    @FXML private Button btnCancelOperation; +    @FXML private Label lblCode, lblAdditionalInfo, lblAddress; +    @FXML private AnchorPane operationDetailsAP; + +    public OperationDetailsController( +            OperationService operationService, +            VehicleService vehicleService, +            CreateOperationController createOperationController) { +        this.operationService = operationService; +        this.vehicleService = vehicleService; +        this.createOperationController = createOperationController; +    } + +    @FXML +    private void initialize() { +        lvActiveOperations.setCellFactory( +                param -> CreateOperationController.generateOpCodeListItem()); +        lvActiveOperations.setOnMouseClicked( +                event -> { +                    if (event.getClickCount() == 2) { +                        if (lvActiveOperations.getSelectionModel().getSelectedItem() == null) { +                            return; +                        } +                        initOperation(lvActiveOperations.getSelectionModel().getSelectedItem()); +                    } +                }); +    } + +    private void updateFlowPane() { +        try { +            fpVehicles.getChildren().clear(); +            for (Vehicle vehicle : operation.vehicles()) { +                VehiclePaneController controller = VehiclePaneController.createVehiclePane(); +                controller.setData(vehicle, true, false); +                fpVehicles.getChildren().add(controller.getRootElement()); +            } + +            fpAdditional.getChildren().clear(); +            for (Vehicle vehicle : operationService.rankVehicles(operation.opCode())) { +                if (operation.vehicles().contains(vehicle)) continue; + +                VehiclePaneController controller = VehiclePaneController.createVehiclePane(); +                controller.setData(vehicle, true, true); +                controller.getBtnRequest().setOnAction(e -> requestVehicleClicked(controller)); +                fpAdditional.getChildren().add(controller.getRootElement()); +            } +        } catch (IOException | ServiceException e) { +            LOG.error("Error while updating list.", e); +            showServiceExceptionAlertAndWait("Error while updating list."); +        } catch (InvalidOperationException e) { +            LOG.debug("Validation for Operation failed"); +            showValidationErrorAlertAndWait(e.getMessage()); +        } +    } + +    void initOperation(Operation operation) { +        fillActiveList(); +        this.operation = operation; +        lblCode.setText(operation.opCode()); +        Collection<String> vehicleNames = +                operation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList()); +        String result = String.join(", ", vehicleNames); +        lblChosenVehicles.setText(result.toString()); +        lblAdditionalInfo.setText(operation.additionalInfo()); +        lblAddress.setText(operation.destination()); +        updateFlowPane(); +        operationDetailsAP.setVisible(true); +    } + +    private void fillActiveList() { +        try { +            lvActiveOperations.setItems( +                    FXCollections.observableArrayList( +                            operationService.list(EnumSet.of(Status.ACTIVE)))); +        } catch (ServiceException e) { +            LOG.error("ServiceException in fillActiveList(). ", e); +            showServiceExceptionAlertAndWait(e.getMessage()); +        } +    } + +    @FXML +    public void closeOperationClicked() { +        LOG.debug("Button \"Abschließen\" clicked."); +        try { +            operationService.complete(operation.id(), Status.COMPLETED); +        } catch (InvalidOperationException e) { +            LOG.debug("Validation error in closeOperationClicked(). ", e); +            showAlertWithOkButtonAndWait(AlertType.ERROR, "Validierungsfehler", e.getMessage()); +            return; +        } catch (ServiceException e) { +            LOG.error("Exception in closeOperationClicked(). ", e); +            showServiceExceptionAlertAndWait(e.getMessage()); +            return; +        } +        showSuccessAlertAndWait("Der Einsatz wurde erfolgreich aktualisiert"); +        createOperationController.updateList(); +        closeWindow(); +    } + +    public void cancelOperationClicked() { +        LOG.debug("Button \"Stornieren\" clicked."); +        try { +            operationService.complete(operation.id(), Status.CANCELLED); +        } catch (InvalidOperationException e) { +            LOG.debug("Validation error in cancelOperationClicked(). ", e); +            showValidationErrorAlertAndWait(e.getMessage()); +            return; +        } catch (ServiceException e) { +            LOG.error("Exception in cancelOperationClicked(). ", e); +            showServiceExceptionAlertAndWait(e.getMessage()); +            return; +        } +        showSuccessAlertAndWait("Der Einsatz wurde erfolgreich aktualisiert"); +        createOperationController.updateList(); +        closeWindow(); +    } + +    private void requestVehicleClicked(VehiclePaneController v) { +        LOG.debug("Button \"Nachfordern\" clicked."); + +        Vehicle vehicle = null; + +        try { +            vehicle = v.getData(); +            if (vehicle == null) return; + +            operationService.requestVehicles(operation.id(), Set.of(vehicle.id())); +        } catch (ServiceException e) { +            LOG.error("ServiceException in requestVehicleClicked()", e); +            showServiceExceptionAlertAndWait(e.getMessage()); +            return; +        } catch (InvalidVehicleException e) { +            LOG.debug("Validation of Vehicle failed"); +            showValidationErrorAlertAndWait(e.getMessage()); +        } catch (InvalidOperationException e) { +            LOG.debug("Validation of Operation failed"); +            showValidationErrorAlertAndWait(e.getMessage()); +        } +        showSuccessAlertAndWait("Das Fahrzeug wurde erfolgreich angefordert"); +        operation.vehicles().add(vehicle); +        updateFlowPane(); +    } + +    public void closeWindow() { +        LOG.debug("Hyperlink \"Zurück\" clicked."); +        operationDetailsAP.setVisible(false); +        this.createOperationController.setVisible(true); +    } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationInArchiveController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationInArchiveController.java new file mode 100644 index 0000000..17f0f55 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationInArchiveController.java @@ -0,0 +1,65 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.Collection; +import java.util.Objects; +import java.util.stream.Collectors; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Node; +import javafx.scene.text.Text; + +public class OperationInArchiveController { + +    @FXML private Text txtAddress; +    @FXML private Text txtVehicles; +    @FXML private Text txtDate; +    @FXML private Text txtOpCode; + +    static OperationInArchiveController create() throws IOException { +        FXMLLoader fxmlLoader = +                new FXMLLoader( +                        OperationInArchiveController.class.getResource( +                                "/fxml/OperationInArchive.fxml")); +        Node root = fxmlLoader.load(); +        OperationInArchiveController result = fxmlLoader.getController(); +        result.rootElement = root; + +        return result; +    } + +    public Node getRoot() { +        return rootElement; +    } + +    private Node rootElement; + +    public void set(Operation operation) { +        txtAddress.setText(operation.destination()); +        String date = "am "; +        if (operation.created() != null) { +            LocalDateTime myDateTime = +                    LocalDateTime.ofInstant( +                            Objects.requireNonNull(operation.created()), ZoneOffset.UTC); +            date += +                    myDateTime.getDayOfMonth() +                            + "." +                            + myDateTime.getMonth().getValue() +                            + "." +                            + myDateTime.getYear(); +            txtDate.setText(date); +        } else { +            txtDate.setText("---"); +        } +        txtOpCode.setText(operation.opCode()); +        Collection<String> elements = +                operation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList()); +        String result = String.join(", ", elements); + +        txtVehicles.setText(result); +    } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java new file mode 100644 index 0000000..c445a12 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java @@ -0,0 +1,289 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidRegistrationException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.EmployeeService; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.RegistrationService; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import java.io.IOException; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.geometry.Insets; +import javafx.scene.Node; +import javafx.scene.control.ChoiceBox; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; +import javafx.scene.input.KeyEvent; +import javafx.scene.input.MouseButton; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.VBox; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class RegistrationWindowController { + +    private static final Logger LOG = LoggerFactory.getLogger(RegistrationWindowController.class); + +    private final EmployeeService employeeService; +    private final VehicleService vehicleService; +    private final RegistrationService registrationService; +    private final CreateOperationController createOperationController; +    private final SpringFXMLLoader fxmlLoader; + +    @FXML private GridPane root; +    @FXML private VBox vbVehicles; +    @FXML private ScrollPane listEmployee; +    @FXML private ChoiceBox<Integer> cbStart; +    @FXML private ChoiceBox<Integer> cbEnd; +    @FXML private Label lVehicles; +    @FXML private Label lEmployees; +    @FXML private TextField tfVehicleSearch; +    @FXML private TextField tfEmployeeSearch; +    private EmployeeListController employeeListController; + +    private Vehicle chosenVehicle; +    private List<Employee> chosenEmployees = new LinkedList<>(); + +    public RegistrationWindowController( +            EmployeeService employeeService, +            VehicleService vehicleService, +            CreateOperationController createOperationController, +            RegistrationService registrationService, +            SpringFXMLLoader fxmlLoader) { +        this.employeeService = employeeService; +        this.vehicleService = vehicleService; +        this.createOperationController = createOperationController; +        this.registrationService = registrationService; +        this.fxmlLoader = fxmlLoader; +    } + +    @FXML +    private void initialize() throws IOException { +        employeeListController = EmployeeListController.createEmployeeListController(fxmlLoader); +        employeeListController.setListItemMargins(new Insets(10, 6, 0, 6)); +        //        listEmployee. .getChildren().add(employeeListController.getRootElement()); +        Node emplList = employeeListController.getRootElement(); +        //        emplList.(360); +        listEmployee.setContent(emplList); + +        ObservableList<Integer> hours = +                FXCollections.observableArrayList( +                        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, +                        21, 22, 23); +        cbStart.setItems(hours); +        cbEnd.setItems(hours); +        setDefaultTime(); +        // reset(); +    } + +    private void setDefaultTime() { +        cbStart.setValue(LocalDateTime.now().getHour()); +        cbEnd.setValue((LocalDateTime.now().getHour() + 4) % 24); +    } + +    private void updateEmplList() { +        employeeListController.deselectAllEmployees(); + +        try { +            Set<Employee> employees = +                    employeeService +                            .list() +                            .stream() +                            .filter( +                                    e -> +                                            e.name() +                                                    .toLowerCase() +                                                    .contains( +                                                            tfEmployeeSearch +                                                                    .getText() +                                                                    .toLowerCase())) +                            .collect(Collectors.toCollection(HashSet::new)); +            employeeListController.setData( +                    employees, +                    selection -> { +                        if (selection == null) { +                            return; +                        } else if (chosenEmployees.contains(selection)) { +                            chosenEmployees.remove(selection); +                        } else { +                            chosenEmployees.add(selection); +                        } + +                        StringBuilder text = new StringBuilder(); +                        boolean first = true; +                        for (Employee employee : chosenEmployees) { +                            if (!first) { +                                text.append(", "); +                            } +                            text.append(employee.name()); +                            first = false; +                        } +                        lEmployees.setText(text.toString()); +                    }, +                    contr -> contr.setSelected(chosenEmployees.contains(contr.getEmployee()))); + +            employees.forEach( +                    e -> { +                        if (chosenEmployees.contains(e)) employeeListController.selectEmployee(e); +                    }); +        } catch (ServiceException e) { +            LOG.error("ServiceException in updateEmplList(). ", e); +            showServiceExceptionAlertAndWait( +                    "Beim Auflisten des Personals ist ein Fehler aufgetreten."); +        } +    } + +    private void updateVehList() { +        vbVehicles.getChildren().clear(); + +        try { +            Set<Vehicle> vehicles = vehicleService.list(EnumSet.of(Status.ABGEMELDET)); + +            boolean anyMatch = false; + +            for (Vehicle vehicle : vehicles) { +                if (!vehicle.name().toLowerCase().contains(tfVehicleSearch.getText().toLowerCase())) +                    continue; + +                anyMatch = true; + +                VehiclePaneController vp = VehiclePaneController.createVehiclePane(); +                vp.setData(vehicle, false, false); +                vbVehicles.getChildren().add(vp.getRootElement()); + +                vp.getRootElement() +                        .setOnMouseClicked( +                                event -> { +                                    if (event.getButton() == MouseButton.PRIMARY) { +                                        chosenVehicle = vehicle; +                                        lVehicles.setText(chosenVehicle.name()); +                                        updateVehList(); +                                    } +                                }); +                if (chosenVehicle != null && chosenVehicle.id() == vehicle.id()) +                    vp.setSelected(true); +            } + +            if (!anyMatch) { +                // Kind of ugly, but best way to get the size of a VehiclePane +                VehiclePaneController vp = VehiclePaneController.createVehiclePane(); +                vp.getRootElement().setVisible(false); +                vbVehicles.getChildren().add(vp.getRootElement()); +            } +        } catch (ServiceException e) { +            LOG.error("ServiceException in updateVehList(). ", e); +            showServiceExceptionAlertAndWait( +                    "Beim Auflisten der Fahrzeuge ist ein Fehler aufgetreten"); +        } catch (IOException e) { +            LOG.error("IOException in updateVehList(). ", e); +            showServiceExceptionAlertAndWait("Beim Laden der Fahrzeuge ist ein Fehler aufgetreten"); +        } +    } + +    public void cancel() { +        LOG.debug("Hyperlink \"schließen\" clicked"); +        this.setVisible(false); +        createOperationController.setVisible(true); +    } + +    private void reset() { +        chosenEmployees.clear(); +        chosenVehicle = null; +        tfEmployeeSearch.setText(""); +        tfVehicleSearch.setText(""); +        lEmployees.setText("-"); +        lVehicles.setText("-"); +        updateVehList(); +        updateEmplList(); +        setDefaultTime(); +    } + +    public void create() { +        LOG.debug("Button \"ERSTELLEN\" clicked"); + +        Set<Registration> registrations = new HashSet<>(); +        try { +            if (chosenVehicle == null) { +                throw new InvalidVehicleException("no Vehicle"); +            } + +            LocalDateTime startDate = +                    LocalDateTime.of( +                            LocalDate.now(), +                            LocalTime.of( +                                    cbStart.getValue(), +                                    LocalDateTime.now().getMinute(), +                                    LocalDateTime.now().getSecond())); + +            LocalDateTime endDate = +                    LocalDateTime.of( +                            LocalDate.now() +                                    .plusDays(cbStart.getValue() >= cbEnd.getValue() ? 1 : 0), +                            LocalTime.of(cbEnd.getValue(), 0)); + +            for (Employee employee : chosenEmployees) { +                registrations.add( +                        Registration.builder() +                                .id(chosenVehicle.id()) +                                .employee(employee) +                                .start(startDate.toInstant(OffsetDateTime.now().getOffset())) +                                .end(endDate.toInstant(OffsetDateTime.now().getOffset())) +                                .build()); +            } + +            registrationService.add(chosenVehicle.id(), registrations); +            chosenEmployees.clear(); +            // ((Stage) lVehicles.getScene().getWindow()).close(); +            this.setVisible(false); +            createOperationController.setVisible(true); +            createOperationController.updateList(); +            // reset(); +        } catch (InvalidVehicleException e) { +            LOG.debug("Validation of Vehicle in Registration failed."); +            showValidationErrorAlertAndWait(e.getMessage()); +        } catch (ServiceException e) { +            LOG.error("ServiceException in create(). ", e); +            showServiceExceptionAlertAndWait( +                    "Beim Erstellen der Anmeldung ist ein Fehler aufgetreten."); +        } catch (InvalidRegistrationException e) { +            LOG.debug("Validation of Registration failed."); +            showValidationErrorAlertAndWait(e.getMessage()); +        } +    } + +    public void setVisible(boolean b) { +        if (b) reset(); +        root.setVisible(b); +    } + +    public void tfVehicleSearch_TextChanged(KeyEvent keyEvent) { +        updateVehList(); +    } + +    public void tfEmployeeSearch_TextChanged(KeyEvent keyEvent) { +        updateEmplList(); +    } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/VehiclePaneController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/VehiclePaneController.java index 6c0932b..66b45d2 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/VehiclePaneController.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/VehiclePaneController.java @@ -1,8 +1,9 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status;  import java.io.IOException;  import java.time.Instant;  import java.util.List; @@ -10,15 +11,13 @@ import java.util.Optional;  import javafx.fxml.FXML;  import javafx.fxml.FXMLLoader;  import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.Label;  import javafx.scene.image.Image;  import javafx.scene.image.ImageView;  import javafx.scene.text.Text; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -public class VehiclePaneController { - -    private static Logger LOG = LoggerFactory.getLogger(VehiclePaneController.class); +public class VehiclePaneController extends CustomListItemController {      public static VehiclePaneController createVehiclePane() throws IOException {          FXMLLoader fxmlLoader = @@ -30,6 +29,7 @@ public class VehiclePaneController {          return result;      } +    @FXML private Label txtStatus;      @FXML private Text txtType;      @FXML private Text txtNumber;      @FXML private ImageView ivNEF; @@ -37,14 +37,10 @@ public class VehiclePaneController {      @FXML private ImageView ivQualification;      @FXML private Text txtQualification;      @FXML private Text txtRooftype; +    @FXML private Button btnRequest; -    private Node rootElement;      private Vehicle data; -    public Node getRootElement() { -        return rootElement; -    } -      public Vehicle getData() {          return data;      } @@ -53,10 +49,10 @@ public class VehiclePaneController {       * * Set the displayed data of this VehiclePane.       *       * @param vehicle The data to display. -     * @param showQualification If true, the most recent registration of vehicle will be searched -     *     for the highest qualification. +     * @param showStatusInfo If true, the highest qualification of the vehicle's active registration +     *     and the vehicle's status will be shown.       */ -    public void setData(Vehicle vehicle, boolean showQualification) { +    public void setData(Vehicle vehicle, boolean showStatusInfo, boolean showRequestVehicle) {          txtType.setText(vehicle.type().name());          String constrType = vehicle.constructionType().name();          txtRooftype.setText( @@ -69,7 +65,22 @@ public class VehiclePaneController {              ivNEF.setImage(new Image("images/NotNEF.png"));              txtNEF.setText("keine NEF-Halterung");          } -        if (showQualification) { + +        if (showRequestVehicle) { +            btnRequest.setVisible(true); +            btnRequest.setManaged(true); +        } else { +            btnRequest.setVisible(false); +            btnRequest.setManaged(false); +        } + +        if (showStatusInfo) { +            txtStatus.setText(vehicle.status().name()); +            if (vehicle.status() == Status.FREI_FUNK || vehicle.status() == Status.FREI_WACHE) { +                txtStatus.getStyleClass().add("bg-status-green"); +            } else { +                txtStatus.getStyleClass().add("bg-status-orange"); +            }              Instant now = Instant.now();              List<Registration> regs = vehicle.registrations(); @@ -94,20 +105,14 @@ public class VehiclePaneController {              txtQualification.setManaged(false);              ivQualification.setVisible(false);              ivQualification.setManaged(false); + +            txtStatus.setVisible(false);          }          this.data = vehicle;      } -    public void setSelected(boolean selected) { -        rootElement.getStyleClass().clear(); - -        if (selected) { -            rootElement.getStyleClass().add("bg-yellow"); -            rootElement.getStyleClass().add("shadowed"); -        } else { -            rootElement.getStyleClass().add("bg-white"); -            rootElement.getStyleClass().add("shadowed"); -        } +    public Button getBtnRequest() { +        return btnRequest;      }  } 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/missioncontrol/dao/EmployeeDAO.java index 539a8e5..675e951 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/missioncontrol/dao/EmployeeDAO.java @@ -1,8 +1,8 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.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 at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee;  import java.util.Set;  public interface EmployeeDAO { diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDatabaseDAO.java new file mode 100644 index 0000000..32dd6d2 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDatabaseDAO.java @@ -0,0 +1,144 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; +import org.springframework.stereotype.Repository; + +@Repository +public class EmployeeDatabaseDAO implements EmployeeDAO { + +    private JDBCConnectionManager jdbcConnectionManager; + +    public EmployeeDatabaseDAO(JDBCConnectionManager jdbcConnectionManager) { +        this.jdbcConnectionManager = jdbcConnectionManager; +    } + +    private long createEmployeeVersion(Connection con, Employee e) +            throws PersistenceException, SQLException { +        String sql = +                "INSERT INTO EmployeeVersion(name, birthday, educationLevel, isDriver, isPilot) " +                        + "VALUES(?, ?, ?, ?, ?)"; + +        try (PreparedStatement pstmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { +            pstmt.setString(1, e.name()); +            pstmt.setObject(2, e.birthday()); +            pstmt.setInt(3, e.educationLevel().ordinal()); +            pstmt.setBoolean(4, e.isDriver()); +            pstmt.setBoolean(5, e.isPilot()); +            pstmt.executeUpdate(); + +            try (ResultSet rs = pstmt.getGeneratedKeys()) { +                if (!rs.next()) throw new PersistenceException("Failed to insert EmployeeVersion"); + +                return rs.getLong(1); +            } +        } +    } + +    @Override +    public long add(Employee employee) throws PersistenceException { +        String sql = "INSERT INTO Employee(version) VALUES(?)"; + +        try { +            Connection con = jdbcConnectionManager.getConnection(); +            con.setAutoCommit(false); + +            long versionId = createEmployeeVersion(con, employee); + +            try (PreparedStatement pstmt = +                    con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { +                pstmt.setLong(1, versionId); +                pstmt.executeUpdate(); + +                try (ResultSet rs = pstmt.getGeneratedKeys()) { +                    if (!rs.next()) { +                        con.rollback(); +                        throw new PersistenceException("Failed to insert Employee"); +                    } + +                    con.commit(); +                    return rs.getLong(1); +                } +            } +        } catch (SQLException e) { +            jdbcConnectionManager.rollbackConnection(); +            throw new PersistenceException(e); +        } +    } + +    @Override +    public void update(Employee employee) throws ElementNotFoundException, PersistenceException { +        String sql = "UPDATE Employee SET version = ? WHERE id = ?"; + +        try { +            Connection con = jdbcConnectionManager.getConnection(); +            con.setAutoCommit(false); + +            long versionId = createEmployeeVersion(con, employee); + +            try (PreparedStatement pstmt = con.prepareStatement(sql)) { +                pstmt.setLong(1, versionId); +                pstmt.setLong(2, employee.id()); + +                if (pstmt.executeUpdate() != 1) { +                    con.rollback(); +                    throw new ElementNotFoundException("No such employeeId exists"); +                } +            } + +            con.commit(); +        } catch (SQLException e) { +            jdbcConnectionManager.rollbackConnection(); +            throw new PersistenceException(e); +        } +    } + +    @Override +    public Set<Employee> list() throws PersistenceException { +        String sql = +                "SELECT emp.id, v.name, v.birthday, v.educationLevel, v.isDriver, v.isPilot " +                        + "FROM employee emp " +                        + "JOIN EmployeeVersion v ON v.id = emp.version"; + +        try { +            Connection con = jdbcConnectionManager.getConnection(); +            Set<Employee> employees = new HashSet<>(); + +            try (PreparedStatement pstmt = con.prepareStatement(sql)) { +                try (ResultSet rs = pstmt.executeQuery()) { +                    while (rs.next()) { +                        employees.add( +                                Employee.builder() +                                        .id(rs.getLong(1)) +                                        .name(rs.getString(2)) +                                        .birthday(rs.getObject(3, LocalDate.class)) +                                        .educationLevel(EducationLevel.valueOf(rs.getString(4))) +                                        .isDriver(rs.getBoolean(5)) +                                        .isPilot(rs.getBoolean(6)) +                                        .build()); +                    } +                } +            } + +            return employees; +        } catch (SQLException e) { +            throw new PersistenceException(e); +        } +    } + +    @Override +    public void remove(long id) throws ElementNotFoundException, PersistenceException { +        throw new UnsupportedOperationException(); +    } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAO.java index d82f768..e496898 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/missioncontrol/dao/OperationDAO.java @@ -1,9 +1,9 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status;  import java.util.EnumSet;  import java.util.Set; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java index 0a465f2..238a2a8 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDatabaseDAO.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java @@ -1,20 +1,22 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Severity; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType;  import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager;  import java.sql.Connection;  import java.sql.PreparedStatement;  import java.sql.ResultSet;  import java.sql.SQLException; -import java.sql.Timestamp; +import java.time.OffsetDateTime; +import java.time.ZoneId;  import java.util.EnumSet;  import java.util.HashSet; -import java.util.Objects;  import java.util.Set;  import java.util.stream.Collectors;  import org.springframework.lang.NonNull; @@ -25,11 +27,15 @@ public class OperationDatabaseDAO implements OperationDAO {      private JDBCConnectionManager jdbcConnectionManager;      private VehicleDAO vehicleDAO; +    private RegistrationDatabaseDAO registrationDAO;      public OperationDatabaseDAO( -            JDBCConnectionManager jdbcConnectionManager, VehicleDAO vehicleDAO) { +            JDBCConnectionManager jdbcConnectionManager, +            VehicleDAO vehicleDAO, +            RegistrationDatabaseDAO registrationDAO) {          this.jdbcConnectionManager = jdbcConnectionManager;          this.vehicleDAO = vehicleDAO; +        this.registrationDAO = registrationDAO;      }      @Override @@ -37,7 +43,6 @@ public class OperationDatabaseDAO implements OperationDAO {          String sql =                  "INSERT INTO Operation(opCode, severity, created, destination, additionalInfo,"                          + "            status) VALUES (?, ?, ?, ?, ?, ?)"; -        String sql2 = "INSERT INTO VehicleOperation(vehicleId, operationId) VALUES (?, ?)";          long operationId;          try { @@ -46,7 +51,7 @@ public class OperationDatabaseDAO implements OperationDAO {              try (PreparedStatement pstmt = con.prepareStatement(sql)) {                  pstmt.setString(1, o.opCode());                  pstmt.setInt(2, o.severity().ordinal()); -                pstmt.setTimestamp(3, Timestamp.from(Objects.requireNonNull(o.created()))); +                pstmt.setObject(3, OffsetDateTime.ofInstant(o.created(), ZoneId.systemDefault()));                  pstmt.setString(4, o.destination());                  pstmt.setString(5, o.additionalInfo());                  pstmt.setInt(6, o.status().ordinal()); @@ -59,20 +64,11 @@ public class OperationDatabaseDAO implements OperationDAO {                  }              } -            try (PreparedStatement pstmt = con.prepareStatement(sql2)) { -                pstmt.setLong(2, operationId); - -                for (long id : (Iterable<Long>) o.vehicles().stream().map(Vehicle::id)::iterator) { -                    pstmt.setLong(1, id); -                    pstmt.addBatch(); -                } - -                pstmt.executeBatch(); -            } +            createVehicleOperation(con, operationId, o.vehicles());              con.commit(); -            con.setAutoCommit(true);              return operationId;          } catch (SQLException e) { +            jdbcConnectionManager.rollbackConnection();              throw new PersistenceException(e);          }      } @@ -84,7 +80,6 @@ public class OperationDatabaseDAO implements OperationDAO {                  "UPDATE Operation SET opCode = ?, severity = ?, destination = ?,"                          + " additionalInfo = ?, status = ? WHERE id = ?";          String sql2 = "DELETE FROM VehicleOperation WHERE operationId = ?"; -        String sql3 = "INSERT INTO VehicleOperation(vehicleId, operationId) VALUES (?, ?)";          try {              Connection con = jdbcConnectionManager.getConnection(); @@ -106,23 +101,39 @@ public class OperationDatabaseDAO implements OperationDAO {                  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(); -            } +            createVehicleOperation(con, o.id(), o.vehicles());              con.commit(); -            con.setAutoCommit(true);          } catch (SQLException e) { +            jdbcConnectionManager.rollbackConnection();              throw new PersistenceException(e);          }      } +    private void createVehicleOperation(Connection con, long operationId, Set<Vehicle> vehicles) +            throws SQLException { +        String sql = +                "INSERT INTO VehicleOperation(vehicleId, operationId)" +                        + " SELECT version, ? FROM Vehicle WHERE id = ?"; +        String sqlUpdateVehicleStatus = +                "UPDATE Vehicle SET status = 'ZUM_BERUFUNGSORT' WHERE id = ?"; + +        try (PreparedStatement pstmt = con.prepareStatement(sql); +                PreparedStatement stmtUpdateVehicleStatus = +                        con.prepareStatement(sqlUpdateVehicleStatus)) { +            pstmt.setLong(1, operationId); + +            for (long id : (Iterable<Long>) vehicles.stream().map(Vehicle::id)::iterator) { +                pstmt.setLong(2, id); +                stmtUpdateVehicleStatus.setLong(1, id); +                pstmt.addBatch(); +                stmtUpdateVehicleStatus.addBatch(); +            } + +            pstmt.executeBatch(); +            stmtUpdateVehicleStatus.executeBatch(); +        } +    } +      @Override      public Operation get(long operationId) throws ElementNotFoundException, PersistenceException {          String sql = "Select * from operation where id = ?"; @@ -150,11 +161,14 @@ public class OperationDatabaseDAO implements OperationDAO {          // This hack exists because H2 currently has a bug that prevents IN (?) with an array of          // ids, i.e. pstmt.setArray(1, con.createArrayOf("INT", intarray) from working. See          // commented code below. + +        // SELECT * FROM Operation WHERE status IN ('COMPLETED', 'CANCELLED') is BUGGED on H2! +        // for this reason we use the ordinal values instead          String str =                  statuses.stream() -                        .map(Enum::name) -                        .map(s -> "'" + s + "'") +                        .map(e -> Integer.toString(e.ordinal()))                          .collect(Collectors.joining(",")); +          String sql = "SELECT * FROM Operation WHERE status IN (" + str + ")";          Set<Operation> operations = new HashSet<>(); @@ -185,14 +199,19 @@ public class OperationDatabaseDAO implements OperationDAO {                  .severity(Severity.valueOf(rs.getString("severity")))                  .status(Status.valueOf(rs.getString("status")))                  .vehicles(getVehiclesFromOperationId(operationId)) -                .created(rs.getTimestamp("created").toInstant()) +                .created((rs.getObject("created", OffsetDateTime.class)).toInstant())                  .destination(rs.getString("destination"))                  .additionalInfo(rs.getString("additionalInfo"))                  .build();      }      private Set<Vehicle> getVehiclesFromOperationId(long operationId) throws PersistenceException { -        String sql = "SELECT vehicleId FROM VehicleOperation WHERE operationId = ?"; +        /*String sql = +        "SELECT id FROM Vehicle WHERE version IN" +                + " (SELECT vehicleId FROM VehicleOperation WHERE operationId = ?)";*/ +        String sql = +                "SELECT vv.* FROM VehicleOperation vo JOIN VehicleVersion vv ON vv.id = vo.vehicleId WHERE operationId = ?"; +          Set<Vehicle> vehicles = new HashSet<>();          try { @@ -203,7 +222,7 @@ public class OperationDatabaseDAO implements OperationDAO {                  try (ResultSet rs = pstmt.getResultSet()) {                      while (rs.next()) { -                        vehicles.add(vehicleDAO.get(rs.getLong("vehicleId"))); +                        vehicles.add(vehicleFromRS(rs));                      }                  }              } @@ -215,4 +234,20 @@ public class OperationDatabaseDAO implements OperationDAO {          return vehicles;      } + +    private Vehicle vehicleFromRS(ResultSet rs) +            throws SQLException, PersistenceException, ElementNotFoundException { +        String name = rs.getString("VehicleVersion.name"); +        long vehicleId = Long.parseLong(name.split("-")[1]); +        return Vehicle.builder() +                .id(vehicleId) +                .name(rs.getString("VehicleVersion.name")) +                .constructionType( +                        ConstructionType.values()[rs.getInt("VehicleVersion.constructionType")]) +                .type(VehicleType.valueOf(rs.getString("VehicleVersion.type"))) +                .status(vehicleDAO.get(vehicleId).status()) +                .hasNef(rs.getBoolean("VehicleVersion.hasNef")) +                .registrations(registrationDAO.list(rs.getLong("VehicleVersion.id"))) +                .build(); +    }  } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAO.java index 36b6f1b..4a35f86 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/missioncontrol/dao/RegistrationDAO.java @@ -1,8 +1,8 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.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 at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration;  import java.util.Set;  public interface RegistrationDAO { diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java new file mode 100644 index 0000000..b624056 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java @@ -0,0 +1,189 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.time.Instant; +import java.time.LocalDate; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +@Repository +public class RegistrationDatabaseDAO implements RegistrationDAO { + +    private JDBCConnectionManager jdbcConnectionManager; +    private EmployeeDAO employeePersistence; + +    @Autowired +    public RegistrationDatabaseDAO( +            JDBCConnectionManager jdbcConnectionManager, EmployeeDAO employeePersistence) { +        this.jdbcConnectionManager = jdbcConnectionManager; +        this.employeePersistence = employeePersistence; +    } + +    private long getVehicleVersionId(long vehicleId) throws PersistenceException { +        String sqlGetVehicleVersionId = "SELECT * FROM vehicle WHERE id = ?"; +        try (PreparedStatement stmt = +                jdbcConnectionManager.getConnection().prepareStatement(sqlGetVehicleVersionId)) { +            stmt.setLong(1, vehicleId); +            try (ResultSet rs = stmt.executeQuery()) { +                if (rs.next()) { +                    return rs.getLong("version"); +                } else { +                    throw new PersistenceException("vehicle id not found"); +                } +            } +        } catch (SQLException e) { +            throw new PersistenceException(e); +        } +    } + +    private long getEmployeeVersionId(long employeeId) throws PersistenceException { +        String sqlGetEmployeeVersionId = "SELECT * FROM employee WHERE id = ?"; +        try (PreparedStatement stmt = +                jdbcConnectionManager.getConnection().prepareStatement(sqlGetEmployeeVersionId)) { +            stmt.setLong(1, employeeId); +            try (ResultSet rs = stmt.executeQuery()) { +                if (rs.next()) { +                    return rs.getLong("version"); +                } else { +                    throw new PersistenceException("employee id not found"); +                } +            } +        } catch (SQLException e) { +            throw new PersistenceException(e); +        } +    } + +    @Override +    public Set<Long> add(long vehicleId, Set<Registration> registrations) +            throws PersistenceException { +        String sql = +                "INSERT INTO Registration (vehicleId, employeeId, start, end, active) VALUES (?,?,?,?,?)"; +        String sql2 = "UPDATE Vehicle SET status = 'FREI_WACHE' WHERE id = ?;"; + +        Set<Long> vehicleIds = new HashSet<>(); + +        try { +            Connection con = jdbcConnectionManager.getConnection(); +            con.setAutoCommit(false); + +            try (PreparedStatement pstmt = +                    con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + +                // vehicleId is a Vehicle.id as it comes from GUI => fetch VehicleVersion.id +                pstmt.setLong(1, getVehicleVersionId(vehicleId)); + +                for (Registration r : registrations) { +                    pstmt.setLong(2, getEmployeeVersionId(r.employee().id())); +                    pstmt.setObject(3, OffsetDateTime.ofInstant(r.start(), ZoneId.systemDefault())); +                    pstmt.setObject(4, OffsetDateTime.ofInstant(r.end(), ZoneId.systemDefault())); +                    pstmt.setBoolean(5, true); +                    pstmt.addBatch(); +                } + +                pstmt.executeBatch(); + +                try (ResultSet rs = pstmt.getGeneratedKeys()) { +                    while (rs.next()) vehicleIds.add(rs.getLong(1)); +                } +            } + +            try (PreparedStatement pstmt = con.prepareStatement(sql2)) { +                pstmt.setLong(1, vehicleId); +                if (pstmt.executeUpdate() != 1) { +                    con.rollback(); +                    throw new PersistenceException("Failed to persist registration"); +                } +            } + +            con.commit(); +            return vehicleIds; +        } catch (SQLException e) { +            jdbcConnectionManager.rollbackConnection(); +            throw new PersistenceException(e); +        } +    } + +    @Override +    public void remove(long id) throws ElementNotFoundException, PersistenceException { +        String sql = "UPDATE Registration SET active = 0, end = ? WHERE id = ?"; + +        try { +            Connection con = jdbcConnectionManager.getConnection(); + +            try (PreparedStatement pstmt = con.prepareStatement(sql)) { +                pstmt.setObject(1, OffsetDateTime.ofInstant(Instant.now(), ZoneId.systemDefault())); +                pstmt.setLong(2, id); + +                if (pstmt.executeUpdate() != 1) +                    throw new ElementNotFoundException("No such registrationId exists"); +            } + +        } catch (SQLException e) { +            throw new PersistenceException(e); +        } +    } + +    protected List<Registration> list(long vehicleId) throws PersistenceException { + +        String sql = +                "SELECT * FROM Registration r " +                        + "JOIN EmployeeVersion ev ON ev.id = r.employeeId " +                        + "JOIN VehicleVersion vv ON vv.id = r.vehicleId " +                        + "WHERE r.vehicleId = ?"; + +        try (PreparedStatement stmt = jdbcConnectionManager.getConnection().prepareStatement(sql)) { + +            List<Registration> registrationList = new ArrayList<>(); +            stmt.setLong(1, vehicleId); // is vehicle version id! +            ResultSet rs = stmt.executeQuery(); +            while (rs.next()) { + +                Employee employee = +                        Employee.builder() +                                .id(rs.getLong("EmployeeVersion.id")) +                                .name(rs.getString("EmployeeVersion.name")) +                                .birthday(rs.getObject("EmployeeVersion.birthday", LocalDate.class)) +                                .educationLevel( +                                        EducationLevel.valueOf( +                                                rs.getString("EmployeeVersion.educationLevel"))) +                                .isDriver(rs.getBoolean("EmployeeVersion.isDriver")) +                                .isPilot(rs.getBoolean("EmployeeVersion.isPilot")) +                                .build(); + +                Registration registration = +                        Registration.builder() +                                .id(rs.getLong("Registration.id")) +                                .start( +                                        (rs.getObject("Registration.start", OffsetDateTime.class)) +                                                .toInstant()) +                                .end( +                                        (rs.getObject("Registration.end", OffsetDateTime.class)) +                                                .toInstant()) +                                .employee(employee) +                                .build(); + +                registrationList.add(registration); +            } + +            return registrationList; +        } catch (SQLException e) { +            throw new PersistenceException(e); +        } +    } +} 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/missioncontrol/dao/VehicleDAO.java index 5782fd9..46d1853 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/missioncontrol/dao/VehicleDAO.java @@ -1,8 +1,8 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.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 at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle;  import java.util.Set;  public interface VehicleDAO { diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java new file mode 100644 index 0000000..8cef65e --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java @@ -0,0 +1,211 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType; +import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.HashSet; +import java.util.Set; +import org.springframework.stereotype.Repository; + +@Repository +public class VehicleDatabaseDAO implements VehicleDAO { + +    private final JDBCConnectionManager jdbcConnectionManager; +    private RegistrationDatabaseDAO registrationDatabaseDao; + +    public VehicleDatabaseDAO( +            JDBCConnectionManager j, RegistrationDatabaseDAO registrationDatabaseDao) { +        jdbcConnectionManager = j; +        this.registrationDatabaseDao = registrationDatabaseDao; +    } + +    @Override +    public long add(Vehicle v) throws PersistenceException { +        String sql = +                "INSERT INTO VehicleVersion (name,hasNef,constructionType,type) VALUES (?,?,?,?)"; +        String sql2 = "INSERT INTO Vehicle (version,status) VALUES (?,?)"; +        String sql3 = "UPDATE VehicleVersion SET name=? WHERE id=?"; + +        try { +            Connection con = jdbcConnectionManager.getConnection(); +            con.setAutoCommit(false); +            String name = ""; +            long version, id; + +            try (PreparedStatement pstmt = +                    con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { +                pstmt.setString(1, name); +                pstmt.setBoolean(2, v.hasNef()); +                pstmt.setInt(3, v.constructionType().ordinal()); +                pstmt.setString(4, v.type().name()); +                pstmt.executeUpdate(); + +                try (ResultSet rs = pstmt.getGeneratedKeys()) { +                    if (!rs.next()) +                        throw new PersistenceException("Failed to insert into VehicleVersion"); + +                    version = rs.getLong(1); +                } +            } + +            try (PreparedStatement pstmt = +                    con.prepareStatement(sql2, Statement.RETURN_GENERATED_KEYS)) { +                pstmt.setLong(1, version); +                pstmt.setInt(2, Status.ABGEMELDET.ordinal()); +                pstmt.executeUpdate(); + +                try (ResultSet rs = pstmt.getGeneratedKeys()) { +                    if (!rs.next()) { +                        con.rollback(); +                        throw new PersistenceException("Failed to insert into Vehicle"); +                    } + +                    id = rs.getLong(1); +                } + +                name = v.type().name() + "-" + id; +            } + +            try (PreparedStatement pstmt = con.prepareStatement(sql3)) { +                pstmt.setString(1, name); +                pstmt.setLong(2, version); + +                if (pstmt.executeUpdate() != 1) { +                    con.rollback(); +                    throw new PersistenceException("Failed to update VehicleVersion"); +                } +            } + +            con.commit(); +            return id; +        } catch (SQLException e) { +            jdbcConnectionManager.rollbackConnection(); +            throw new PersistenceException(e); +        } +    } + +    @Override +    public void update(Vehicle v) throws ElementNotFoundException, PersistenceException { +        String sql = "SELECT version FROM Vehicle WHERE id = ?"; +        String sql2 = +                "MERGE INTO VehicleVersion(name, constructionType, type, hasNef)" +                        + " KEY(name, constructionType, type, hasNef) VALUES(?, ?, ?, ?)"; +        String sql3 = "UPDATE Vehicle SET version = ?, status = ? WHERE id = ?"; + +        long versionId; + +        try { +            Connection con = jdbcConnectionManager.getConnection(); +            con.setAutoCommit(false); +            try (PreparedStatement pstmt = con.prepareStatement(sql)) { +                pstmt.setLong(1, v.id()); + +                try (ResultSet rs = pstmt.executeQuery()) { +                    if (!rs.next()) throw new ElementNotFoundException("No such vehicleId exists"); + +                    versionId = rs.getLong(1); +                } +            } + +            try (PreparedStatement pstmt = +                    con.prepareStatement(sql2, Statement.RETURN_GENERATED_KEYS)) { +                pstmt.setString(1, v.type().name() + "-" + v.id()); +                pstmt.setString(2, v.constructionType().name()); +                pstmt.setString(3, v.type().name()); +                pstmt.setBoolean(4, v.hasNef()); +                pstmt.executeUpdate(); + +                try (ResultSet rs = pstmt.getGeneratedKeys()) { +                    if (rs.next()) { +                        // version changed, update it +                        versionId = rs.getLong(1); +                    } +                } +            } + +            try (PreparedStatement pstmt = con.prepareStatement(sql3)) { +                pstmt.setLong(1, versionId); +                pstmt.setString(2, v.status().name()); +                pstmt.setLong(3, v.id()); +                pstmt.executeUpdate(); +            } + +            con.commit(); +        } catch (SQLException e) { +            jdbcConnectionManager.rollbackConnection(); +            throw new PersistenceException(e); +        } +    } + +    @Override +    public Set<Vehicle> list() throws PersistenceException { +        Set<Vehicle> result = new HashSet<>(); + +        String sql = +                "Select * from VehicleVersion, Vehicle where VehicleVersion.id=Vehicle.version"; + +        try (PreparedStatement pstmt = +                jdbcConnectionManager.getConnection().prepareStatement(sql)) { +            pstmt.executeQuery(); +            try (ResultSet rs = pstmt.getResultSet()) { +                while (rs.next()) { +                    result.add(vehicleFromRS(rs)); +                } +            } +        } catch (SQLException e) { +            throw new PersistenceException(e); +        } +        return result; +    } + +    @Override +    public Vehicle get(long id) throws ElementNotFoundException, PersistenceException { +        String sql = +                "SELECT *" +                        + " FROM Vehicle a" +                        + " INNER JOIN VehicleVersion b" +                        + " ON version = b.id" +                        + " WHERE a.id = ?"; + +        try { +            Connection con = jdbcConnectionManager.getConnection(); +            try (PreparedStatement pstmt = con.prepareStatement(sql)) { +                pstmt.setLong(1, id); + +                try (ResultSet rs = pstmt.executeQuery()) { +                    if (!rs.first()) throw new ElementNotFoundException("No such vehicle exists"); + +                    return vehicleFromRS(rs); +                } +            } +        } catch (SQLException e) { +            throw new PersistenceException(e); +        } +    } + +    @Override +    public void remove(long id) throws ElementNotFoundException, PersistenceException { +        throw new UnsupportedOperationException(); +    } + +    private Vehicle vehicleFromRS(ResultSet rs) throws SQLException, PersistenceException { +        return Vehicle.builder() +                .id(rs.getLong("Vehicle.id")) +                .name(rs.getString("name")) +                .constructionType(ConstructionType.values()[rs.getInt("constructionType")]) +                .type(VehicleType.valueOf(rs.getString("type"))) +                .status(Status.values()[rs.getInt("status")]) +                .hasNef(rs.getBoolean("hasNef")) +                .registrations(registrationDatabaseDao.list(rs.getLong("Vehicle.version"))) +                .build(); +    } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Employee.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Employee.java index 583bf5b..f45550e 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Employee.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Employee.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto;  import com.google.auto.value.AutoValue;  import java.time.LocalDate; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/EmployeeValidator.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/EmployeeValidator.java index d7fa9aa..b03fa04 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/EmployeeValidator.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/EmployeeValidator.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto;  import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; @@ -7,15 +7,15 @@ public class EmployeeValidator {      public static boolean validate(Employee employee) throws InvalidEmployeeException {          if (employee.name() == null || employee.name().trim().length() == 0) { -            throw new InvalidEmployeeException("name not set"); +            throw new InvalidEmployeeException("Name darf nicht leer sein!");          }          if (employee.birthday() == null) { -            throw new InvalidEmployeeException("birthday not set"); +            throw new InvalidEmployeeException("Geburtsdatum darf nicht leer sein!");          }          if (employee.educationLevel() == null) { -            throw new InvalidEmployeeException("educationLevel not set"); +            throw new InvalidEmployeeException("Ausbildungsgrad darf nicht leer sein!");          }          return true; 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/missioncontrol/dto/Operation.java index 3a97dc7..e119622 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/missioncontrol/dto/Operation.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto;  import com.google.auto.value.AutoValue;  import java.time.Instant; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Registration.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Registration.java index 8551266..a12c038 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Registration.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Registration.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto;  import com.google.auto.value.AutoValue;  import java.time.Instant; 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/missioncontrol/dto/RegistrationValidator.java index 610426c..a2cb8c1 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/missioncontrol/dto/RegistrationValidator.java @@ -1,20 +1,16 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType;  import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidRegistrationException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType;  import java.util.HashMap;  import java.util.LinkedList;  import java.util.List;  import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory;  public class RegistrationValidator { -    private static final Logger LOG = LoggerFactory.getLogger(RegistrationValidator.class); -      private RegistrationValidator() {}      public static void validate(Vehicle vehicle, Set<Registration> registrations) @@ -47,11 +43,10 @@ public class RegistrationValidator {          for (Registration registration : registrations) {              total++;              if (found.put(registration.employee().id(), false) != null) { -                LOG.info("Employee with ID {} was added twice", registration.employee().id());                  throw new InvalidRegistrationException( -                        "Person with the ID: " +                        "Person mit der ID: "                                  + registration.employee().id() -                                + " was added more than once!"); +                                + " wurde mehrmals hinzugefügt!");              }              if (registration.employee().isPilot()) {                  pilotIds.add(registration.employee().id()); @@ -71,7 +66,6 @@ public class RegistrationValidator {              }          }          if (total <= 0) { -            LOG.info("No employees were added");              throw new InvalidRegistrationException("Kein Personal ausgewählt!");          }          if (vehicle.type() == VehicleType.NAH) { @@ -83,10 +77,8 @@ public class RegistrationValidator {              3-4 Personen               */              if (total < 3) { -                LOG.info("Too few employees for NAH");                  throw new InvalidRegistrationException("Zu wenig Personal für NAH!");              } else if (total > 4) { -                LOG.info("Too many employees for NAH");                  throw new InvalidRegistrationException("Zu viel Personal für NAH!");              }              for (long pilot_id : pilotIds) { @@ -96,14 +88,12 @@ public class RegistrationValidator {                      found.put(na_id, true);                      for (long nfs_id : nfsIds) {                          if (found.get(nfs_id)) continue; -                        LOG.info("Valid combination found for NAH");                          return;                      }                      found.put(na_id, false);                  }                  found.put(pilot_id, false);              } -            LOG.info("No valid combination of employees found for NAH");              throw new InvalidRegistrationException(                      "Keine gültige Kombination von Personen für NAH!");          } else if (vehicle.type() == VehicleType.NEF) { @@ -113,10 +103,8 @@ public class RegistrationValidator {              1 NA               */              if (total < 2) { -                LOG.info("Too few employees for NEF");                  throw new InvalidRegistrationException("Zu wenig Personal für NEF!");              } else if (total > 3) { -                LOG.info("Too many employees for NEF");                  throw new InvalidRegistrationException("Zu viel Personal für NEF!");              }              for (long driver_id : driverIds) { @@ -125,12 +113,10 @@ public class RegistrationValidator {                  found.put(driver_id, true);                  for (long na_id : naIds) {                      if (found.get(na_id)) continue; -                    LOG.info("Valid combinaion found for NEF");                      return;                  }                  found.put(driver_id, false);              } -            LOG.info("No valid combination of employees found for NEF");              throw new InvalidRegistrationException(                      "Keine gültige Kombination von Personen für NEF!");          } else if (vehicle.type() == VehicleType.BKTW) { @@ -139,14 +125,11 @@ public class RegistrationValidator {              1 Driver               */              if (total > 3) { -                LOG.info("Too many employees for BKTW");                  throw new InvalidRegistrationException("Zu viel Personal für BKTW!");              }              if (!driverIds.isEmpty()) { -                LOG.info("Valid combination found for BKTW");                  return;              } -            LOG.info("No driver was found for BKTW");              throw new InvalidRegistrationException("Kein Fahrer gefunden für BKTW!");          } else { // KTW or RTW, both have the same requirements              /* @@ -155,11 +138,9 @@ public class RegistrationValidator {              1 RS               */              if (total < 2) { -                LOG.info("Too few employees for {}", vehicle.type().name());                  throw new InvalidRegistrationException(                          "Zu wenig Personal für " + vehicle.type().name() + "!");              } else if (total > 4) { -                LOG.info("Too many employees for {}", vehicle.type().name());                  throw new InvalidRegistrationException(                          "Zu viel Persoanl für " + vehicle.type().name() + "!");              } @@ -167,11 +148,9 @@ public class RegistrationValidator {                  found.put(driver_id, true);                  for (long rs_id : rsIds) {                      if (found.get(rs_id)) continue; -                    LOG.info("Valid combination found for {}", vehicle.type().name());                      return;                  }              } -            LOG.info("No valid combination of employees found for {}", vehicle.type().name());              throw new InvalidRegistrationException(                      "Keine gültige Kombination von Personen für " + vehicle.type().name() + "!");          } 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/missioncontrol/dto/Vehicle.java index e81db0b..c2033f5 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/missioncontrol/dto/Vehicle.java @@ -1,4 +1,4 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto;  import com.google.auto.value.AutoValue;  import java.util.List; 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/missioncontrol/service/EmployeeService.java index f7f8e71..5beabaa 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/missioncontrol/service/EmployeeService.java @@ -1,8 +1,8 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.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 at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee;  import java.util.Set;  public interface EmployeeService { diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceImpl.java index 31b5acd..a08b03e 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/missioncontrol/service/EmployeeServiceImpl.java @@ -1,12 +1,12 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.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 at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.EmployeeDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.EmployeeValidator;  import java.util.Set;  import org.springframework.stereotype.Service; @@ -53,5 +53,7 @@ public class EmployeeServiceImpl implements EmployeeService {      }      @Override -    public void remove(long id) throws InvalidEmployeeException, ServiceException {} +    public void remove(long id) throws InvalidEmployeeException, ServiceException { +        throw new UnsupportedOperationException(); +    }  } 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/missioncontrol/service/OperationService.java index 4b7e630..42b23bb 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/missioncontrol/service/OperationService.java @@ -1,11 +1,11 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle;  import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle;  import java.util.EnumSet;  import java.util.Set;  import java.util.SortedSet; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceImpl.java index d07f46f..0c350fe 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/missioncontrol/service/OperationServiceImpl.java @@ -1,18 +1,17 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.OperationDAO; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.VehicleDAO; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.lang.invoke.MethodHandles; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.OperationDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Severity; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType;  import java.time.Instant;  import java.util.ArrayList;  import java.util.Comparator; @@ -34,7 +33,7 @@ import org.springframework.stereotype.Service;  @Service  public class OperationServiceImpl implements OperationService { -    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); +    private static final Logger LOG = LoggerFactory.getLogger(OperationServiceImpl.class);      private final OperationDAO operationDAO;      private final VehicleDAO vehicleDAO; @@ -49,19 +48,29 @@ public class OperationServiceImpl implements OperationService {      @Override      public long add(Operation o) throws InvalidOperationException, ServiceException { -        if (o.created() != null) throw new InvalidOperationException("Created must not be set"); +        if (o.created() != null) { +            throw new InvalidOperationException("Erstellungszeitpunkt darf nicht gesetzt sein"); +        } -        if (o.severity() != null) throw new InvalidOperationException("Severity must not be set"); +        if (o.severity() != null) { +            throw new InvalidOperationException("Der Schweregrad darf nicht gesetzt sein"); +        } -        if (o.id() != 0) throw new InvalidOperationException("Id must be 0"); +        if (o.id() != 0) { +            throw new InvalidOperationException("Einsatz-ID muss 0 sein"); +        }          if (o.status() != Status.ACTIVE) -            LOG.warn("Status was set but will be overridden"); // TODO: nullable instead?? +            LOG.info("Status was set but will be overridden"); // TODO: nullable instead??          try {              for (long id : (Iterable<Long>) o.vehicles().stream().map(Vehicle::id)::iterator) {                  Vehicle v = vehicleDAO.get(id);                  VehicleServiceImpl.validateVehicle(v); + +                if (v.status() != Vehicle.Status.FREI_FUNK +                        && v.status() != Vehicle.Status.FREI_WACHE) +                    throw new InvalidOperationException("Fahrzeug nicht verfügbar: " + v.status());              }              validateOperation(o); @@ -73,10 +82,10 @@ public class OperationServiceImpl implements OperationService {                              .status(Status.ACTIVE)                              .build());          } catch (PersistenceException e) { -            LOG.error("PersistenceException while adding operation: {}", e);              throw new ServiceException(e);          } catch (InvalidVehicleException e) { -            throw new InvalidOperationException("Enthaltenes Fahrzeug ist invalid", e); +            // already logged as invalid vehicle +            throw new InvalidOperationException("Enthaltenes Fahrzeug ist ungültig", e);          } catch (ElementNotFoundException e) {              throw new InvalidOperationException("Enthaltenes Fahrzeug existiert nicht", e);          } @@ -88,29 +97,37 @@ public class OperationServiceImpl implements OperationService {          Set<Vehicle> vs = new HashSet<>();          try { -            if (operationId <= 0) throw new InvalidOperationException("OperationId ist invalid"); +            if (operationId <= 0) { +                throw new InvalidOperationException("Einsatz-ID ist ungültig"); +            }              Operation o = operationDAO.get(operationId);              validateOperation(o);              if (o.opCode().trim().isEmpty() -                    || extractSeverityFromOpCode(o.opCode()) != o.severity()) -                throw new InvalidOperationException("Einsatzcode ist invalid"); +                    || extractSeverityFromOpCode(o.opCode()) != o.severity()) { +                throw new InvalidOperationException("Einsatzcode ist ungültig"); +            } -            if (o.status() != Status.ACTIVE) -                throw new InvalidOperationException("Einsatz ist inaktiv"); +            if (o.status() != Status.ACTIVE) { +                throw new InvalidOperationException("Einsatz ist ungültig"); +            } -            if (o.created() == null) -                throw new InvalidOperationException("Created darf nicht leer sein"); +            if (o.created() == null) { +                throw new InvalidOperationException("Erstellungszeitpunkt darf nicht leer sein"); +            }              for (Long id : vehicleIds) { -                if (id <= 0) throw new InvalidVehicleException("VehicleId ist invalid"); +                if (id <= 0) { +                    throw new InvalidVehicleException("Fahrzeug-ID ist ungültig"); +                }                  try {                      Vehicle v = vehicleDAO.get(id);                      VehicleServiceImpl.validateVehicle(v); -                    if (v.status() == Vehicle.Status.ABGEMELDET) -                        throw new InvalidVehicleException( -                                "Kann keine inaktiven Fahrzeuge anfordern"); +                    if (v.status() != Vehicle.Status.FREI_FUNK +                            && v.status() != Vehicle.Status.FREI_WACHE) +                        throw new InvalidOperationException( +                                "Fahrzeug nicht verfügbar: " + v.status());                      vs.add(v);                  } catch (ElementNotFoundException e) { @@ -123,9 +140,8 @@ public class OperationServiceImpl implements OperationService {              operationDAO.update(o.toBuilder().vehicles(vs).build());          } catch (ElementNotFoundException e) { -            throw new InvalidOperationException("Kein Einsatz mit dieser id existiert"); +            throw new InvalidOperationException("Kein Einsatz mit dieser ID existiert");          } catch (PersistenceException e) { -            LOG.error("PersistenceException while requesting vehicles: {}", e);              throw new ServiceException(e);          }      } @@ -139,7 +155,6 @@ public class OperationServiceImpl implements OperationService {          } catch (ElementNotFoundException e) {              throw new InvalidOperationException(e);          } catch (PersistenceException e) { -            LOG.error("PersistenceException while completing operation: {}", e);              throw new ServiceException(e);          }      } @@ -214,40 +229,45 @@ public class OperationServiceImpl implements OperationService {              return operations;          } catch (PersistenceException e) { -            LOG.error("PersistenceException while listing operations", e);              throw new ServiceException(e);          } catch (InvalidOperationException e) {              // database returned invalid values -            LOG.error("DB returned invalid operation: {}", e);              throw new ServiceException("DB returned invalid operation", e);          }      }      private static void validateOperation(Operation o) throws InvalidOperationException { -        if (o.vehicles().isEmpty()) +        if (o.vehicles().isEmpty()) {              throw new InvalidOperationException(                      "Es muss mindestens ein Fahrzeug ausgewählt werden!"); +        }          for (Vehicle v : o.vehicles()) {              try {                  VehicleServiceImpl.validateVehicle(v);              } catch (InvalidVehicleException e) { -                throw new InvalidOperationException("Fahrzeug " + v.name() + " ist invalid" + e); +                throw new InvalidOperationException("Fahrzeug " + v.name() + " ist ungültig", e);              } -            if (v.status() != Vehicle.Status.FREI_FUNK && v.status() != Vehicle.Status.FREI_WACHE) -                throw new InvalidOperationException( -                        "Fahrzeug nicht verfügbar (" + v.status() + ")"); -              // TODO: validate if NEF/RTW/NAH conditions?          }          Instant created = o.created(); -        if (created != null && created.isAfter(Instant.now())) -            throw new InvalidOperationException("Fahrzeug wurde in der Zukunft erstellt"); +        if (created != null && created.isAfter(Instant.now())) { +            throw new InvalidOperationException("Einsatz wurde in der Zukunft erstellt"); +        } -        if (o.destination().trim().isEmpty()) +        if (o.destination() == null || o.destination().trim().isEmpty()) {              throw new InvalidOperationException("Adresse darf nicht leer sein"); +        } + +        if (o.destination().length() > 100) { +            throw new InvalidOperationException("Adresse darf 100 Zeichen nicht überschreiten"); +        } + +        if (o.additionalInfo() != null && o.additionalInfo().length() > 100) { +            throw new InvalidOperationException("Anmerkung darf 100 Zeichen nicht überschreiten"); +        }      }      private static final Pattern opCodePattern = @@ -257,7 +277,9 @@ public class OperationServiceImpl implements OperationService {              throws InvalidOperationException {          Matcher m = opCodePattern.matcher(opCode); -        if (!m.matches()) throw new InvalidOperationException("Einsatzcode ist invalid"); +        if (!m.matches()) { +            throw new InvalidOperationException("Einsatzcode ist ungültig"); +        }          return Severity.valueOf(m.group(1));      } diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationService.java index b7d8eef..91577dc 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/missioncontrol/service/RegistrationService.java @@ -1,9 +1,9 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration;  import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidRegistrationException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration;  import java.util.Set;  public interface RegistrationService { diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java index 54d46e7..a6a1dfe 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/missioncontrol/service/RegistrationServiceImpl.java @@ -1,26 +1,22 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.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.exception.ElementNotFoundException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidRegistrationException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.RegistrationDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.RegistrationValidator; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle;  import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory;  import org.springframework.beans.factory.annotation.Autowired;  import org.springframework.stereotype.Service;  @Service  public class RegistrationServiceImpl implements RegistrationService { -    private static final Logger LOG = LoggerFactory.getLogger(RegistrationServiceImpl.class); -      private final RegistrationDAO registrationDAO;      private final VehicleDAO vehicleDAO; @@ -43,7 +39,6 @@ public class RegistrationServiceImpl implements RegistrationService {              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); @@ -52,6 +47,14 @@ public class RegistrationServiceImpl implements RegistrationService {      @Override      public void remove(long registrationId) throws InvalidRegistrationException, ServiceException { -        throw new UnsupportedOperationException(); +        if (registrationId <= 0) throw new InvalidRegistrationException("RegistrationId invalid"); + +        try { +            registrationDAO.remove(registrationId); +        } catch (PersistenceException e) { +            throw new ServiceException(e); +        } catch (ElementNotFoundException e) { +            throw new InvalidRegistrationException(e); +        }      }  } 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/missioncontrol/service/VehicleService.java index fe09ca1..f8e303d 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/missioncontrol/service/VehicleService.java @@ -1,9 +1,9 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; -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.InvalidVehicleException;  import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status;  import java.util.EnumSet;  import java.util.Set; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleServiceImpl.java index 61a24e5..a68720d 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/missioncontrol/service/VehicleServiceImpl.java @@ -1,13 +1,13 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; -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 at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status;  import java.util.EnumSet;  import java.util.Set;  import java.util.stream.Collectors; @@ -24,8 +24,10 @@ public class VehicleServiceImpl implements VehicleService {      }      public long add(Vehicle vehicle) throws InvalidVehicleException, ServiceException { -        if (!CollectionUtils.isEmpty(vehicle.registrations())) -            throw new InvalidVehicleException("Vehicle can't be created with registrations"); +        if (!CollectionUtils.isEmpty(vehicle.registrations())) { +            throw new InvalidVehicleException( +                    "Fahrzeug kann nicht mit Anmeldungen erstellt werden"); +        }          validateVehicle(vehicle);          try { @@ -41,7 +43,7 @@ public class VehicleServiceImpl implements VehicleService {          try {              vehiclePersistence.update(vehicle);          } catch (ElementNotFoundException e) { -            throw new ServiceException("Element not found"); +            throw new ServiceException("Element not found", e);          } catch (PersistenceException e) {              throw new ServiceException(e);          } @@ -91,7 +93,7 @@ public class VehicleServiceImpl implements VehicleService {      @Override      public Set<Vehicle> list(EnumSet<Status> statuses) throws ServiceException {          if (statuses == null) { -            throw new ServiceException("statuses may not be null"); +            throw new ServiceException("Statuses may not be null");          }          Set<Vehicle> vehicles; diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/util/JDBCConnectionManager.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/util/JDBCConnectionManager.java index 0ee3319..ea394ab 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/util/JDBCConnectionManager.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/util/JDBCConnectionManager.java @@ -47,4 +47,12 @@ public class JDBCConnectionManager {          }          connection = null;      } + +    public void rollbackConnection() { +        try { +            connection.rollback(); +        } catch (SQLException e) { +            LOG.error("Failed to rollback connection", e); +        } +    }  }  | 
