diff --git a/.gitignore b/.gitignore index f0ded7c..2532936 100644 --- a/.gitignore +++ b/.gitignore @@ -72,3 +72,5 @@ crashlytics-build.properties .gradle/ build/ + +/client/config.json \ No newline at end of file diff --git a/client/app/build.gradle.kts b/client/app/build.gradle.kts index 9661289..3a8a5d6 100644 --- a/client/app/build.gradle.kts +++ b/client/app/build.gradle.kts @@ -5,15 +5,19 @@ plugins { } javafx { - version = "11" + version = "11.0.2" modules( "javafx.controls", "javafx.fxml" ) } +tasks.withType { + options.encoding = "UTF-8" +} + application { - mainClassName = "client.MainApplication" + mainClassName = "main.MainApplication" } repositories { @@ -27,7 +31,7 @@ dependencies { val jar by tasks.getting(Jar::class) { manifest { - attributes["Main-Class"] = "client.Launcher" + attributes["Main-Class"] = "main.Launcher" } from({ configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) } diff --git a/client/app/src/main/java/customUI/Button.java b/client/app/src/main/java/customUI/Button.java deleted file mode 100644 index 3d4d4bf..0000000 --- a/client/app/src/main/java/customUI/Button.java +++ /dev/null @@ -1,8 +0,0 @@ -package customUI; - -public class Button extends javafx.scene.control.Button { - - public void setTextValue(String text){ - super.setText(Converter.CONVERT_STR(text)); - } -} diff --git a/client/app/src/main/java/customUI/Converter.java b/client/app/src/main/java/customUI/Converter.java deleted file mode 100644 index bf0c895..0000000 --- a/client/app/src/main/java/customUI/Converter.java +++ /dev/null @@ -1,21 +0,0 @@ -package customUI; - -public class Converter { - /* - Ä, ä \u00c4, \u00e4 - Ö, ö \u00d6, \u00f6 - Ü, ü \u00dc, \u00fc - ß \u00df - */ - @SuppressWarnings("all") - public static String CONVERT_STR(String str){ - return str - .replace("ä", "\u00e4") - .replace("Ä", "\u00c4") - .replace("ö", "\u00f6") - .replace("Ö", "\u00d6") - .replace("ü", "\u00fc") - .replace("Ü", "\u00dc") - .replace("ß", "\u00df"); - } -} diff --git a/client/app/src/main/java/customUI/Label.java b/client/app/src/main/java/customUI/Label.java deleted file mode 100644 index 8ba0ce2..0000000 --- a/client/app/src/main/java/customUI/Label.java +++ /dev/null @@ -1,15 +0,0 @@ -package customUI; - -public class Label extends javafx.scene.control.Label { - public Label(String content){ - super(Converter.CONVERT_STR(content)); - } - - public Label(){ - super(); - } - - public void setTextValue(String text){ - super.setText(Converter.CONVERT_STR(text)); - } -} diff --git a/client/app/src/main/java/main/CreateEventController.java b/client/app/src/main/java/main/CreateEventController.java index 1c61cbf..ed86f69 100644 --- a/client/app/src/main/java/main/CreateEventController.java +++ b/client/app/src/main/java/main/CreateEventController.java @@ -1,6 +1,7 @@ package main; import com.jfoenix.controls.*; +import helper.HttpRequestException; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.Node; @@ -9,8 +10,8 @@ import javafx.scene.layout.GridPane; import javafx.stage.Stage; import javafx.util.StringConverter; import javafx.util.converter.LocalTimeStringConverter; -import res.DataController; -import res.Event; +import container.DataController; +import container.Event; import java.time.LocalTime; import java.time.format.FormatStyle; @@ -43,7 +44,6 @@ public class CreateEventController { @FXML public void initialize() { - StringConverter defaultConverter = new LocalTimeStringConverter(FormatStyle.SHORT, Locale.GERMANY); timeStart.set24HourView(true); timeStart.setConverter(defaultConverter); @@ -60,29 +60,35 @@ public class CreateEventController { throw new IllegalArgumentException("Bitte w\u00e4hle ein Datum aus"); } + System.out.println(datePickerDate.getValue()); + Event event = new Event( textName.getText(), ComboBoxPriotity.getSelectionModel().getSelectedIndex(), toggleBtnIsFullDay.isSelected(), toggleBtnIsPrivate.isSelected(), - timeStart.getValue().toString(), - timeEnd.getValue().toString(), + timeStart.getValue(), + timeEnd.getValue(), datePickerDate.getValue().atStartOfDay(), (int) DataController.USER_ID ); System.out.println(event.getAsUrlParam()); - DataController dataController = new DataController(); - dataController.createEvent(event); + sendHttpRequest(event); Stage stage = (Stage) ((Node) actionEvent.getSource()).getScene().getWindow(); stage.close(); - } catch (RuntimeException e) { + } catch (Exception e) { labelError.setText(e.getMessage()); } } + protected void sendHttpRequest(Event event) throws HttpRequestException { + DataController dataController = new DataController(); + dataController.createEvent(event); + } + @FXML protected void abortBtnClick(ActionEvent event) { Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); diff --git a/client/app/src/main/java/main/EditEventController.java b/client/app/src/main/java/main/EditEventController.java new file mode 100644 index 0000000..cce82d9 --- /dev/null +++ b/client/app/src/main/java/main/EditEventController.java @@ -0,0 +1,30 @@ +package main; + +import helper.HttpRequestException; +import container.DataController; +import container.Event; + +public class EditEventController extends CreateEventController{ + + private Event currentEvent; + + public Event getCurrentEvent() { + return currentEvent; + } + + public void setCurrentEvent(Event currentEvent) { + this.currentEvent = currentEvent; + + textName.setText(currentEvent.getName()); + datePickerDate.setValue(currentEvent.getDate().toLocalDate()); + ComboBoxPriotity.getSelectionModel().select(currentEvent.getPriority()); + + //timeEnd.setValue(currentEvent.getEnd()); + } + + @Override + protected void sendHttpRequest(Event event) throws HttpRequestException { + DataController dataController = new DataController(); + dataController.editEvent(currentEvent, event); + } +} diff --git a/client/app/src/main/java/main/MainApplication.java b/client/app/src/main/java/main/MainApplication.java index e0cbbdd..4e514f0 100644 --- a/client/app/src/main/java/main/MainApplication.java +++ b/client/app/src/main/java/main/MainApplication.java @@ -1,10 +1,13 @@ package main; +import config.Config; +import config.ConfigLoader; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.stage.Stage; -import res.DataController; +import container.DataController; +import container.HttpRequest; import java.io.IOException; import java.util.Objects; @@ -12,28 +15,56 @@ import java.util.Objects; public class MainApplication extends Application { @Override public void start(Stage stage) throws IOException { + Config config = ConfigLoader.load(); + if(config == null){ + config = new Config(false, -1, ""); + } + System.out.println("Ignore 'Illegal reflective access operation'-Warning. See https://github.com/sshahine/JFoenix/issues/1170"); + + if( + !config.isSaveLogin() + || !new DataController().loginWithToken(config.getId(), config.getToken()) + ){ + // Load login-scene + loadLoginScene(); + } + + if (DataController.USER_ID >= 0) { + if(config.isSaveLogin()){ + config.setId(DataController.USER_ID); + config.setToken(HttpRequest.TOKEN); + ConfigLoader.save(config); + } + // Load main-scene + loadMainScene(stage); + + System.out.println("Logged in..."); + } + } + + private void loadMainScene(Stage stage) throws IOException { FXMLLoader fxmlLoader = new FXMLLoader(MainApplication.class.getResource("main-view.fxml")); Scene scene = new Scene(fxmlLoader.load(), 1200, 700); scene.getStylesheets().add(Objects.requireNonNull( - - MainApplication.class.getResource("main-view.css")).toExternalForm()); + MainApplication.class.getResource("main-view.css")).toExternalForm() + ); stage.setTitle("SharePlaner"); stage.setScene(scene); + stage.show(); + } + private void loadLoginScene() throws IOException { FXMLLoader fxmlLoaderLogin = new FXMLLoader(MainApplication.class.getResource("../users/login.fxml")); Scene sceneLogin = new Scene(fxmlLoaderLogin.load(), 650, 500); sceneLogin.getStylesheets().add(Objects.requireNonNull( - MainApplication.class.getResource("../users/login.css")).toExternalForm()); + MainApplication.class.getResource("../users/login.css")).toExternalForm() + ); Stage stageLogin = new Stage(); stageLogin.setTitle("Anmelden"); stageLogin.setScene(sceneLogin); stageLogin.showAndWait(); - - if (DataController.USER_ID >= 0) { - stage.show(); - } } public static void main(String[] args) { diff --git a/client/app/src/main/java/main/MainController.java b/client/app/src/main/java/main/MainController.java index 983b955..e823492 100644 --- a/client/app/src/main/java/main/MainController.java +++ b/client/app/src/main/java/main/MainController.java @@ -1,19 +1,27 @@ package main; +import config.Config; +import config.ConfigLoader; +import ui.DayPane; +import ui.SvgBtnCreator; +import helper.HttpRequestException; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.geometry.Pos; +import javafx.scene.Group; +import javafx.scene.Node; import javafx.scene.Scene; -import customUI.Button; -import customUI.Label; -import javafx.scene.control.ScrollPane; +import javafx.scene.control.*; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.stage.Modality; import javafx.stage.Stage; -import res.DataController; -import res.Event; +import container.DataController; +import container.Event; + +import javafx.event.ActionEvent; +import container.HttpRequest; import java.io.IOException; import java.time.Duration; @@ -24,6 +32,12 @@ import java.util.Objects; public class MainController { + @FXML + public VBox leftNav; + @FXML + public GridPane mainGridPane; + @FXML + public HBox buttonBox; @FXML private GridPane calendarGrid; @@ -46,8 +60,9 @@ public class MainController { public void initialize() { createWeek(); setDates(); - updateEvents(); + createBtns(); + leftNav.setSpacing(40); } private void updateEvents() { @@ -56,10 +71,14 @@ public class MainController { } DataController dataController = new DataController(); - ArrayList eventList = dataController.getAllVisibleEvents(); + try { + ArrayList eventList = dataController.getAllVisibleEvents(weekStartDateTime, weekStartDateTime.plusDays(7)); - for (Event event : eventList) { - addEvent(event); + for (Event event : eventList) { + addEvent(event); + } + } catch (HttpRequestException e) { + e.printStackTrace(); } } @@ -105,30 +124,39 @@ public class MainController { updateEvents(); } + protected void onSettingBtnClick(){ + try{ + FXMLLoader fxmlLoader = new FXMLLoader( + MainApplication.class.getResource("option-view.fxml")); + Scene scene = new Scene(fxmlLoader.load(), 650, 650); + scene.getStylesheets().add(Objects.requireNonNull( + MainApplication.class.getResource("option-view.css")).toExternalForm()); + Stage stage = new Stage(); + stage.setTitle("Einstellungen"); + stage.setScene(scene); + stage.initModality(Modality.APPLICATION_MODAL); + stage.setResizable(false); + stage.showAndWait(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + protected void onLogoutBtnClick(ActionEvent event){ + ConfigLoader.save(new Config()); + DataController.USER_ID = -1; + HttpRequest.TOKEN = ""; + Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); + stage.close(); + } + private void createWeek() { for (int i = 0; i < 7; i++) { - Label label = new Label(); - label.setTextValue(dayNames[i]); - label.setMaxHeight(Double.MAX_VALUE); - label.setMaxWidth(Double.MAX_VALUE); - label.getStyleClass().add("labelDays"); - dayLabel[i] = label; - calendarGrid.add(label, i, 0); - - ScrollPane scrollPane = new ScrollPane(); - - VBox vBox = new VBox(); - vBox.getStyleClass().add("vBoxDays"); - vBox.setSpacing(10); - dayVBoxes[i] = vBox; - scrollPane.setContent(vBox); - - scrollPane.setFitToWidth(true); - scrollPane.setFitToHeight(true); - scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED); - scrollPane.getStyleClass().add("scrollDays"); - - calendarGrid.add(scrollPane, i, 1); + DayPane dayPane = new DayPane(dayNames[i]); + this.dayLabel[i] = dayPane.getDayLabel(); + calendarGrid.add(dayPane.getDayLabel(), i, 0); + dayVBoxes[i] = dayPane.getDayVBox(); + calendarGrid.add(dayPane.getScrollPane(), i, 1); } } @@ -139,15 +167,32 @@ public class MainController { HBox btnHBox = new HBox(); btnHBox.setAlignment(Pos.BOTTOM_RIGHT); - Button deleteBtn = new Button(); - deleteBtn.setTextValue(" X "); + + Group svgDel = new Group( + SvgBtnCreator.createPath("M0 0h24v24H0z", "transparent", "transparent"), + SvgBtnCreator.createPath("M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z", + "white", "gray") + ); + Button deleteBtn = SvgBtnCreator.createBtn(svgDel, 24, "", "Löschen des Termins"); + + deleteBtn.getStyleClass().add("deleteEventBtn"); deleteBtn.setOnAction(e -> { DataController dataController = new DataController(); - dataController.deleteEvent(event.getId()); + try { + dataController.deleteEvent(event.getOwnerId(), event.getId(), event.getDate()); + } catch (HttpRequestException ex) { + ex.printStackTrace(); + } updateEvents(); }); - Button editBtn = new Button(); - editBtn.setTextValue("edit"); + + Group svgEdit = new Group( + SvgBtnCreator.createPath("M0 0h24v24H0z", "transparent", "transparent"), + SvgBtnCreator.createPath("M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z", + "white", "gray") + ); + Button editBtn = SvgBtnCreator.createBtn(svgEdit, 24, "", "Bearbeiten des Termins"); + editBtn.getStyleClass().add("editEventBtn"); editBtn.setOnAction(event1 -> { try { FXMLLoader fxmlLoader = new FXMLLoader( @@ -160,7 +205,10 @@ public class MainController { stage.setScene(scene); stage.initModality(Modality.APPLICATION_MODAL); stage.setResizable(false); + EditEventController editEventController = fxmlLoader.getController(); + editEventController.setCurrentEvent(event); stage.showAndWait(); + updateEvents(); } catch (IOException e) { e.printStackTrace(); } @@ -170,6 +218,7 @@ public class MainController { vBox.getChildren().add(btnHBox); Label nameLabel = new Label(event.getName()); + nameLabel.setWrapText(true); vBox.getChildren().add(nameLabel); if (event.getStart() != null || event.getEnd() != null) { @@ -182,11 +231,12 @@ public class MainController { Label typeLabel = new Label("Wer: " + event.getOwnerName()); vBox.getChildren().add(typeLabel); - Label prioLabel = new Label("Priorit\u00e4t: " + event.getPriority()); + Label prioLabel = new Label("Priorität: " + event.getPriority()); vBox.getChildren().add(prioLabel); if (event.isFullDay()) { Label fullDayLabel = new Label("Dieser Termin bockiert den ganzen Tag!"); + fullDayLabel.setWrapText(true); vBox.getChildren().add(fullDayLabel); } @@ -220,10 +270,75 @@ public class MainController { weekStartDateTime = now.plusDays(weekOffset * 7L - dayOfWeek + 1); for (int i = 0; i < 7; i++) { - dayLabel[i].setTextValue(dayFormatter.format(weekStartDateTime.plusDays(i))); + dayLabel[i].setText(dayFormatter.format(weekStartDateTime.plusDays(i))); } LabelMonth.setText(dateFormatter.format(weekStartDateTime)); } + + private void createBtns(){ + Group svgAdd = new Group( + SvgBtnCreator.createPath("M0 0h24v24H0z", "transparent", "transparent"), + SvgBtnCreator.createPath("M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z", + "white", "gray") + ); + Button addBtn = SvgBtnCreator.createBtn(svgAdd, 40, "main-btn", "Erstellt einen neuen Termin"); + addBtn.setOnAction(e -> onAddBtnClick()); + addBtn.getStyleClass().add("main-btn"); + leftNav.getChildren().add(addBtn); + + Group svgSettings = new Group( + SvgBtnCreator.createPath("M0 0h24v24H0V0z", "transparent", "transparent"), + SvgBtnCreator.createPath("M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z", + "white", "gray") + ); + Button settingsBtn = SvgBtnCreator.createBtn(svgSettings, 40, "main-btn", "Öffnet die Einstellungen"); + settingsBtn.setOnAction(e -> onSettingBtnClick()); + settingsBtn.getStyleClass().add("main-btn"); + leftNav.getChildren().add(settingsBtn); + + Group svgLogout = new Group( + SvgBtnCreator.createPath("M0 0h24v24H0z", "transparent", "transparent"), + SvgBtnCreator.createPath("M17 7l-1.41 1.41L18.17 11H8v2h10.17l-2.58 2.58L17 17l5-5zM4 5h8V3H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8v-2H4V5z", + "white", "gray") + ); + Button logoutBtn = SvgBtnCreator.createBtn(svgLogout, 40, "main-btn", "Abmelden"); + logoutBtn.setOnAction(this::onLogoutBtnClick); + logoutBtn.getStyleClass().add("main-btn"); + leftNav.getChildren().add(logoutBtn); + + Group svgBack = new Group( + SvgBtnCreator.createPath("M0 0h24v24H0z", "transparent", "transparent"), + SvgBtnCreator.createPath("M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z", + "white", "lightgray") + ); + Button backBtn = SvgBtnCreator.createBtn(svgBack, 40, "navBtn", "Zeigt die vorherige Woche"); + backBtn.setOnAction(e -> onBackClick()); + backBtn.getStyleClass().add("navBtn"); + GridPane.setColumnIndex(backBtn, 1); + buttonBox.getChildren().add(backBtn); + + Group svgToday = new Group( + SvgBtnCreator.createPath("M0 0h24v24H0z", "transparent", "transparent"), + SvgBtnCreator.createPath("M20 3h-1V1h-2v2H7V1H5v2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 18H4V8h16v13z", + "white", "lightgray") + ); + Button todayBtn = SvgBtnCreator.createBtn(svgToday, 40, "navBtn", "Zeigt die aktuelle Woche"); + todayBtn.setOnAction(e -> onTodayClick()); + todayBtn.getStyleClass().add("navBtn"); + GridPane.setColumnIndex(todayBtn, 2); + buttonBox.getChildren().add(todayBtn); + + Group svgNext = new Group( + SvgBtnCreator.createPath("M0 0h24v24H0z", "transparent", "transparent"), + SvgBtnCreator.createPath("M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z", + "white", "lightgray") + ); + Button nextBtn = SvgBtnCreator.createBtn(svgNext, 40, "navBtn", "Zeigt die nächste Woche"); + nextBtn.setOnAction(e -> onNextClick()); + nextBtn.getStyleClass().add("navBtn"); + GridPane.setColumnIndex(nextBtn, 3); + buttonBox.getChildren().add(nextBtn); + } } \ No newline at end of file diff --git a/client/app/src/main/java/main/OptionController.java b/client/app/src/main/java/main/OptionController.java new file mode 100644 index 0000000..9d85042 --- /dev/null +++ b/client/app/src/main/java/main/OptionController.java @@ -0,0 +1,158 @@ +package main; + +import com.jfoenix.controls.*; +import config.Config; +import config.ConfigLoader; +import container.HttpRequest; +import helper.HttpRequestException; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Node; +import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.ButtonType; +import javafx.scene.control.Label; +import javafx.scene.layout.GridPane; +import javafx.stage.Modality; +import javafx.stage.Stage; +import container.DataController; +import container.User; +import users.EditUserController; + +import java.awt.*; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Consumer; + +public class OptionController { + + @FXML + public JFXButton updateUserBtn; + @FXML + public JFXButton deleteUserBtn; + @FXML + public JFXButton createUserBtn; + @FXML + public JFXToggleButton saveLoginTBtn; + @FXML + public Label labelError; + @FXML + public GridPane mainGrid; + + private JFXComboBox comboBox; + private DataController dataController; + private List users; + private Config config; + + @FXML + public void initialize(){ + dataController = new DataController(); + try{ + users = dataController.getAllUser(); + } catch (HttpRequestException e){ + users = new ArrayList<>(); + } + + ObservableList observableUserList = FXCollections.observableArrayList(); + for (User user: users) { + observableUserList.add(user.getLogin()); + } + comboBox = new JFXComboBox<>(observableUserList); + comboBox.getStyleClass().add("comboBox"); + mainGrid.add(comboBox, 2,2); + + config = ConfigLoader.load(); + if(config == null){ + config = new Config(false, -1, ""); + } + saveLoginTBtn.setSelected(config.isSaveLogin()); + } + + public void onBackBtnClick(ActionEvent actionEvent) { + Stage stage = (Stage) ((Node) actionEvent.getSource()).getScene().getWindow(); + stage.close(); + } + + public void onCreateBtnClick(ActionEvent actionEvent) { + loadUserScene(actionEvent, "User erstellen", "../users/create-user.fxml", null); + } + + public void onUpdateBtnClick(ActionEvent actionEvent) { + int editIndex = comboBox.getSelectionModel().getSelectedIndex(); + + if(editIndex < 0 || editIndex >= users.size()) return; + + FXMLLoader fxmlLoader = loadUserScene( + actionEvent, + "User bearbeiten", + "../users/edit-user.fxml", + this::setUserAtController + ); + } + + public void onDeleteBtnClick(ActionEvent actionEvent) { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "Wirklich löschen?"); + Optional result = alert.showAndWait(); + if(result.isPresent() && result.get() == ButtonType.OK){ + int removeIndex = comboBox.getSelectionModel().getSelectedIndex(); + try { + dataController.deleteUser(users.get(removeIndex)); + } catch (HttpRequestException e) { + Alert alert1 = new Alert(Alert.AlertType.ERROR, e.getMessage()); + alert1.showAndWait(); + return; + } + comboBox.getItems().remove(removeIndex); + users.remove(removeIndex); + } + } + + private FXMLLoader loadUserScene(ActionEvent actionEvent, String title, String fxml, Consumer method) { + FXMLLoader fxmlLoader = new FXMLLoader( + MainApplication.class.getResource(fxml)); + try { + Scene scene = new Scene(fxmlLoader.load(), 800, 650); + scene.getStylesheets().add(Objects.requireNonNull( + MainApplication.class.getResource("../users/create-user.css")).toExternalForm()); + Stage stage = new Stage(); + stage.setTitle(title); + stage.setScene(scene); + stage.initModality(Modality.APPLICATION_MODAL); + stage.setResizable(false); + + if(method != null)method.accept(fxmlLoader); + + stage.showAndWait(); + Stage stageOld = (Stage) ((Node) actionEvent.getSource()).getScene().getWindow(); + stageOld.close(); + } catch (IOException e) { + e.printStackTrace(); + e.printStackTrace(); + } + return fxmlLoader; + } + + private void setUserAtController(FXMLLoader fxmlLoader){ + int editIndex = comboBox.getSelectionModel().getSelectedIndex(); + EditUserController editUserController = fxmlLoader.getController(); + editUserController.setCurrentUser(users.get(editIndex)); + } + + public void toggledBtn(ActionEvent actionEvent) { + config.setSaveLogin(saveLoginTBtn.isSelected()); + if(config.isSaveLogin()){ + config.setId(DataController.USER_ID); + config.setToken(HttpRequest.TOKEN); + } else { + config.setId(-1); + config.setToken(""); + } + ConfigLoader.save(config); + } +} diff --git a/client/app/src/main/java/ui/DayPane.java b/client/app/src/main/java/ui/DayPane.java new file mode 100644 index 0000000..d1aa3c8 --- /dev/null +++ b/client/app/src/main/java/ui/DayPane.java @@ -0,0 +1,44 @@ +package ui; + +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.layout.VBox; + +public class DayPane { + + private Label dayLabel; + private VBox dayVBox; + private ScrollPane scrollPane; + + public DayPane(String name) { + dayLabel = new Label(); + dayLabel.setText(name); + dayLabel.setMaxHeight(Double.MAX_VALUE); + dayLabel.setMaxWidth(Double.MAX_VALUE); + dayLabel.getStyleClass().add("labelDays"); + + scrollPane = new ScrollPane(); + + dayVBox = new VBox(); + dayVBox.getStyleClass().add("vBoxDays"); + dayVBox.setSpacing(10); + scrollPane.setContent(dayVBox); + + scrollPane.setFitToWidth(true); + scrollPane.setFitToHeight(true); + scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED); + scrollPane.getStyleClass().add("scrollDays"); + } + + public Label getDayLabel() { + return dayLabel; + } + + public VBox getDayVBox() { + return dayVBox; + } + + public ScrollPane getScrollPane() { + return scrollPane; + } +} diff --git a/client/app/src/main/java/ui/SvgBtnCreator.java b/client/app/src/main/java/ui/SvgBtnCreator.java new file mode 100644 index 0000000..fc72cc8 --- /dev/null +++ b/client/app/src/main/java/ui/SvgBtnCreator.java @@ -0,0 +1,66 @@ +package ui; + +import javafx.geometry.Bounds; +import javafx.scene.Group; +import javafx.scene.control.*; +import javafx.scene.shape.SVGPath; + +public class SvgBtnCreator { + + public static Button createBtn(Group group, int svgSize) { + Button btn = new Button(); + + Bounds boundsDel = group.getBoundsInParent(); + double scaleDel = Math.min(svgSize / boundsDel.getWidth(), svgSize / boundsDel.getHeight()); + group.setScaleX(scaleDel); + group.setScaleY(scaleDel); + btn.setGraphic(group); + btn.setMaxSize(svgSize, svgSize); + btn.setMinSize(svgSize, svgSize); + btn.setContentDisplay(ContentDisplay.GRAPHIC_ONLY); + + return btn; + } + + public static Button createBtn(Group group, int svgSize, String styleClass) { + Button btn = new Button(); + + Bounds boundsDel = group.getBoundsInParent(); + double scaleDel = Math.min(svgSize / boundsDel.getWidth(), svgSize / boundsDel.getHeight()); + group.setScaleX(scaleDel); + group.setScaleY(scaleDel); + btn.setGraphic(group); + btn.setMaxSize(svgSize, svgSize); + btn.setMinSize(svgSize, svgSize); + btn.getStyleClass().add(styleClass); + + return btn; + } + + public static Button createBtn(Group group, int svgSize, String styleClass, String toolTip) { + Button btn = new Button(); + + Bounds boundsDel = group.getBoundsInParent(); + double scaleDel = Math.min(svgSize / boundsDel.getWidth(), svgSize / boundsDel.getHeight()); + group.setScaleX(scaleDel); + group.setScaleY(scaleDel); + btn.setGraphic(group); + btn.setMaxSize(svgSize, svgSize); + btn.setMinSize(svgSize, svgSize); + btn.setContentDisplay(ContentDisplay.GRAPHIC_ONLY); + btn.getStyleClass().add(styleClass); + Tooltip tooltip = new Tooltip(toolTip); + btn.setTooltip(tooltip); + + return btn; + } + + public static SVGPath createPath(String d, String fill, String hoverFill) { + SVGPath path = new SVGPath(); + path.getStyleClass().add("svg"); + path.setContent(d); + path.setStyle("-fill:" + fill + ";-hover-fill:"+hoverFill+';'); + return path; + } + +} diff --git a/client/app/src/main/java/users/CreateUserController.java b/client/app/src/main/java/users/CreateUserController.java index e40cc43..82f795d 100644 --- a/client/app/src/main/java/users/CreateUserController.java +++ b/client/app/src/main/java/users/CreateUserController.java @@ -1,20 +1,24 @@ package users; +import helper.HttpRequestException; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.Node; import javafx.scene.control.Label; +import javafx.scene.control.PasswordField; import javafx.scene.control.TextField; import javafx.scene.control.ToggleButton; import javafx.stage.Stage; +import container.DataController; +import container.User; import java.util.Objects; public class CreateUserController { public TextField textName; - public TextField textPassword; - public TextField textPasswordSecond; + public PasswordField textPassword; + public PasswordField textPasswordSecond; public ToggleButton checkButtonIsAdmin; public TextField textLogin; public TextField textForename; @@ -38,15 +42,38 @@ public class CreateUserController { labelError.setText("Bitte Passwort eingeben!"); return; } + if (textPassword.getText().trim().length() < 8) { + labelError.setText("Das Passwort muss mindestens 8 Zeichen lang sein!"); + return; + } if (!Objects.equals(textPassword.getText(), textPasswordSecond.getText())){ labelError.setText("Passwörter stimmen nicht überein!"); return; } + User user = new User(); + user.setLogin(textLogin.getText().trim()); + user.setForename(textForename.getText().trim()); + user.setName(textName.getText().trim()); + user.setPassword(textPassword.getText().trim()); + user.setAdmin(checkButtonIsAdmin.isSelected()); + + try { + sendHttpRequest(user); + } catch (HttpRequestException e) { + labelError.setText(e.getMessage()); + return; + } + Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); stage.close(); } + protected void sendHttpRequest(User user) throws HttpRequestException { + DataController dataController = new DataController(); + dataController.createUser(user); + } + @FXML protected void abortBtnClick(ActionEvent event) { Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); diff --git a/client/app/src/main/java/users/EditUserController.java b/client/app/src/main/java/users/EditUserController.java index f6d45af..fa021e4 100644 --- a/client/app/src/main/java/users/EditUserController.java +++ b/client/app/src/main/java/users/EditUserController.java @@ -1,28 +1,33 @@ package users; +import container.DataController; +import container.User; +import helper.HttpRequestException; import javafx.event.ActionEvent; -import javafx.fxml.FXML; import javafx.scene.Node; -import javafx.scene.control.Label; -import javafx.scene.control.TextField; -import javafx.scene.control.ToggleButton; -import javafx.scene.paint.Paint; +import javafx.scene.control.Alert; import javafx.stage.Stage; + import java.util.Objects; -public class EditUserController { +public class EditUserController extends CreateUserController{ + private User currentUser; - public TextField textName; - public TextField textPassword; - public TextField textPasswordSecond; - public ToggleButton checkButtonIsAdmin; - public TextField textLogin; - public TextField textForename; - public Label labelError; + public User getCurrentUser() { + return currentUser; + } - @FXML - public void saveUser(ActionEvent event) { - labelError.setTextFill(Paint.valueOf("Red")); + public void setCurrentUser(User currentUser) { + this.currentUser = currentUser; + + textForename.setText(currentUser.getForename()); + textName.setText(currentUser.getName()); + textLogin.setText(currentUser.getLogin()); + checkButtonIsAdmin.setSelected(currentUser.isAdmin()); + } + + @Override + protected void createUser(ActionEvent event){ if (textLogin.getText().trim().isEmpty()){ labelError.setText("Bitte Login Namen angeben"); return; @@ -35,22 +40,53 @@ public class EditUserController { labelError.setText("Bitte Nachnamen eingeben!"); return; } - if (textPassword.getText().trim().isEmpty()) { - labelError.setText("Bitte Passwort eingeben!"); + + User user = new User(); + + if(!textPassword.getText().trim().isEmpty() || !textPasswordSecond.getText().trim().isEmpty()){ + if (textPassword.getText().trim().isEmpty()) { + labelError.setText("Bitte Passwort eingeben!"); + return; + } + if (textPassword.getText().trim().length() < 8) { + labelError.setText("Das Passwort muss mindestens 8 Zeichen lang sein!"); + return; + } + if (!Objects.equals(textPassword.getText(), textPasswordSecond.getText())){ + labelError.setText("Passwörter stimmen nicht überein!"); + return; + } + user.setPassword(textPassword.getText().trim()); + } + + user.setUserId(currentUser.getUserId()); + user.setLogin(textLogin.getText().trim()); + user.setForename(textForename.getText().trim()); + user.setName(textName.getText().trim()); + user.setAdmin(checkButtonIsAdmin.isSelected()); + + try { + sendHttpRequest(user); + } catch (HttpRequestException e) { + labelError.setText(e.getMessage()); return; } - if (!Objects.equals(textPassword.getText(), textPasswordSecond.getText())){ - labelError.setText("Passwörter stimmen nicht überein!"); - return; + + if(currentUser.getUserId() == DataController.USER_ID){ + Alert alert = new Alert( + Alert.AlertType.WARNING, + "Bitte starte das Programm neu um die Änderungen anzuwenden." + ); + alert.showAndWait(); } Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); stage.close(); } - @FXML - public void abortBtnClick(ActionEvent event) { - Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); - stage.close(); + @Override + protected void sendHttpRequest(User user) throws HttpRequestException { + DataController dataController = new DataController(); + dataController.editUser(user); } } diff --git a/client/app/src/main/java/users/LoginController.java b/client/app/src/main/java/users/LoginController.java index 3bce950..37da4be 100644 --- a/client/app/src/main/java/users/LoginController.java +++ b/client/app/src/main/java/users/LoginController.java @@ -6,7 +6,7 @@ import javafx.fxml.FXML; import javafx.scene.Node; import javafx.scene.control.Label; import javafx.stage.Stage; -import res.DataController; +import container.DataController; public class LoginController { @FXML diff --git a/client/app/src/main/resources/main/edit-event.fxml b/client/app/src/main/resources/main/edit-event.fxml index 9180344..939dddb 100644 --- a/client/app/src/main/resources/main/edit-event.fxml +++ b/client/app/src/main/resources/main/edit-event.fxml @@ -8,7 +8,7 @@ + fx:controller="main.EditEventController"> diff --git a/client/app/src/main/resources/main/main-view.css b/client/app/src/main/resources/main/main-view.css index 684f7b7..56d1402 100644 --- a/client/app/src/main/resources/main/main-view.css +++ b/client/app/src/main/resources/main/main-view.css @@ -63,16 +63,58 @@ Label{ } .main-btn{ - -fx-background-color: #ffffff; - -fx-text-fill: -fx-main-text-color; - -fx-background-radius: 5em; - -fx-min-width: 40px; - -fx-min-height: 40px; - -fx-max-width: 40px; - -fx-max-height: 40px; + -fx-background-color: transparent; + -fx-border-color: transparent; +} + +.main-btn .svg { + -fx-fill: -fill; +} + +.main-btn:hover .svg { + -fx-fill: -hover-fill; +} + +.buttonBox{ + -fx-background-color: #77859E; } .navBtn{ - -fx-background-color: white; + -fx-background-color: transparent; + -fx-border-color: transparent; +} + +.navBtn .svg { + -fx-fill: -fill; +} + +.navBtn:hover .svg { + -fx-fill: -hover-fill; +} + +.editEventBtn{ + -fx-background-color: transparent; + -fx-border-color: transparent; +} + +.editEventBtn .svg { + -fx-fill: -fill; +} + +.editEventBtn:hover .svg { + -fx-fill: -hover-fill; +} + +.deleteEventBtn{ + -fx-background-color: transparent; + -fx-border-color: transparent; +} + +.deleteEventBtn .svg { + -fx-fill: -fill; +} + +.deleteEventBtn:hover .svg { + -fx-fill: -hover-fill; } diff --git a/client/app/src/main/resources/main/main-view.fxml b/client/app/src/main/resources/main/main-view.fxml index 758226a..8f2d3f8 100644 --- a/client/app/src/main/resources/main/main-view.fxml +++ b/client/app/src/main/resources/main/main-view.fxml @@ -4,7 +4,6 @@ - @@ -15,22 +14,13 @@ - - - ADD - - - ADD - - - ADD - - + @@ -49,9 +39,8 @@ - zurück - heute - weiter + + diff --git a/client/app/src/main/resources/main/option-view.css b/client/app/src/main/resources/main/option-view.css new file mode 100644 index 0000000..291a5d3 --- /dev/null +++ b/client/app/src/main/resources/main/option-view.css @@ -0,0 +1,58 @@ +GridPane{ + -fx-background-color: #3E415F; + -fx-padding: 20px; + -fx-font-size: 20px; + -fx-font-family: Segoe UI; + + -fx-border-insets: 1; + -fx-border-color: #B0B0B0; + -fx-border-style: solid; + -fx-border-width: 2; + -fx-effect: dropshadow(three-pass-box, rgba(100, 100, 100, 1), 24, 0.5, 0, 0); +} + +Label{ + -fx-text-fill: white; + -fx-max-width: 200px; + -fx-min-width: 200px; +} + +.mainLabel{ + -fx-background-color: #8D99AE; + -fx-padding: 10px; + -fx-max-width: 200px; + -fx-min-width: 200px; + -fx-font-weight: bold; + -fx-alignment: center; +} + +.mainButton{ + -fx-font-weight: bold; + -fx-background-color: white; +} + +JFXButton{ + -fx-background-color: white; +} + +#labelError{ + -fx-font-weight: bold; + -fx-max-width: 1000px; + -fx-text-fill: #ff5555; + -fx-padding: 16px; + -fx-min-height: 140px; + -fx-max-height: 400px; + -fx-wrap-text: true; + -fx-font-size: 16px; +} + +.comboBox{ + -fx-background-color: white; + -fx-max-width: 200px; + -fx-min-width: 200px; +} + +.userBtn{ + -fx-max-width: 200px; + -fx-min-width: 200px; +} \ No newline at end of file diff --git a/client/app/src/main/resources/main/option-view.fxml b/client/app/src/main/resources/main/option-view.fxml new file mode 100644 index 0000000..13e2edd --- /dev/null +++ b/client/app/src/main/resources/main/option-view.fxml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + User bearbeiten + User löschen + User anlegen + + + + + diff --git a/client/app/src/main/resources/users/create-user.fxml b/client/app/src/main/resources/users/create-user.fxml index 3a40ebd..ec367cc 100644 --- a/client/app/src/main/resources/users/create-user.fxml +++ b/client/app/src/main/resources/users/create-user.fxml @@ -3,6 +3,7 @@ + @@ -37,19 +38,19 @@ - - + + - + - diff --git a/client/app/src/main/resources/users/edit-user.fxml b/client/app/src/main/resources/users/edit-user.fxml index b3a78ce..7ee0071 100644 --- a/client/app/src/main/resources/users/edit-user.fxml +++ b/client/app/src/main/resources/users/edit-user.fxml @@ -3,6 +3,7 @@ + @@ -24,7 +25,7 @@ - + @@ -37,19 +38,20 @@ - - + + - + - + diff --git a/client/data/build.gradle.kts b/client/data/build.gradle.kts index 5b07f24..790eeb5 100644 --- a/client/data/build.gradle.kts +++ b/client/data/build.gradle.kts @@ -2,9 +2,14 @@ plugins { java } +tasks.withType { + options.encoding = "UTF-8" +} + dependencies { val jacksonVersion = "2.13.0" implementation("com.fasterxml.jackson.core:jackson-databind:$jacksonVersion") implementation("com.fasterxml.jackson.core:jackson-core:$jacksonVersion") implementation("com.fasterxml.jackson.core:jackson-annotations:$jacksonVersion") + implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jacksonVersion") } diff --git a/client/data/src/main/java/config/Config.java b/client/data/src/main/java/config/Config.java new file mode 100644 index 0000000..07e8b2f --- /dev/null +++ b/client/data/src/main/java/config/Config.java @@ -0,0 +1,41 @@ +package config; + +public class Config { + private boolean saveLogin; + private long id; + private String token; + + public Config(){ + + } + + public Config(boolean saveLogin, long id, String token) { + this.saveLogin = saveLogin; + this.id = id; + this.token = token; + } + + public boolean isSaveLogin() { + return saveLogin; + } + + public void setSaveLogin(boolean saveLogin) { + this.saveLogin = saveLogin; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } +} diff --git a/client/data/src/main/java/config/ConfigLoader.java b/client/data/src/main/java/config/ConfigLoader.java new file mode 100644 index 0000000..ca1989e --- /dev/null +++ b/client/data/src/main/java/config/ConfigLoader.java @@ -0,0 +1,39 @@ +package config; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class ConfigLoader { + + public static Config load(){ + try { + String jsonString = Files.readString(Paths.get("config.json")); + + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.findAndRegisterModules(); + return objectMapper.readValue(jsonString, Config.class); + } catch (IOException e) { + System.out.println("config.json missing"); + Config config = new Config(false, -1, ""); + save(config); + return config; + } + } + + public static void save(Config config){ + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.findAndRegisterModules(); + + try { + Files.writeString(Paths.get( + "config.json"), + objectMapper.writeValueAsString(config) + ); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/client/data/src/main/java/container/DataController.java b/client/data/src/main/java/container/DataController.java new file mode 100644 index 0000000..c60f909 --- /dev/null +++ b/client/data/src/main/java/container/DataController.java @@ -0,0 +1,219 @@ +package container; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import helper.HttpRequestException; +import helper.Tuple; + +import java.time.LocalDateTime; +import java.util.*; + +public class DataController { + + public static long USER_ID = -1; + + private static final String ALL_EVENTS_ENDPOINT = "http://localhost:8080/event/all"; + private static final String ADD_EVENT_ENDPOINT = "http://localhost:8080/event/add"; + private static final String DELETE_EVENT_ENDPOINT = "http://localhost:8080/event/del"; + private static final String EDIT_EVENT_ENDPOINT = "http://localhost:8080/event/edit"; + + private static final String ALL_USER_ENDPOINT = "http://localhost:8080/user/all"; + private static final String ADD_USER_ENDPOINT = "http://localhost:8080/user/add"; + private static final String DELETE_USER_ENDPOINT = "http://localhost:8080/user/del"; + private static final String EDIT_USER_ENDPOINT = "http://localhost:8080/user/edit"; + + private static final String LOGIN_ENDPOINT = "http://localhost:8080/user/login"; + private static final String LOGIN_WITH_TOKEN_ENDPOINT = "http://localhost:8080/user/login-with-token"; + private static final String HEADER_TEST_ENDPOINT = "http://localhost:8080/vpr/header-test"; + + private final HttpRequest httpRequest; + + public DataController() { + httpRequest = new HttpRequest(); + } + + public boolean login(String username, String password) { + try { + Tuple response = httpRequest.sendPostRequest( + LOGIN_ENDPOINT, + "login=" + username + + "&password=" + password, + false + ); + String[] data = response.getValue().split("\\s+"); + + USER_ID = Long.parseLong(data[1]); + HttpRequest.TOKEN = data[0]; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + return USER_ID >= 0; + } + + public boolean loginWithToken(long userId, String token) { + try { + HttpRequest.TOKEN = token; + Tuple response = httpRequest.sendPostRequest( + LOGIN_WITH_TOKEN_ENDPOINT, + "userId=" + userId, + true + ); + + System.out.println(response.getKey() + " " + response.getValue()); + + if (response.getKey() != 200) return false; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + USER_ID = userId; + HttpRequest.TOKEN = token; + return USER_ID >= 0; + } + + /********* + * Event * + *********/ + public void createEvent(Event event) throws HttpRequestException { + sendBasicHttpRequest( + ADD_EVENT_ENDPOINT, + event.getAsUrlParam(), + true + ); + } + + public void deleteEvent(int userId, int eventId, LocalDateTime date) throws HttpRequestException { + sendBasicHttpRequest( + DELETE_EVENT_ENDPOINT, + "userId=" + userId + "&eventId=" + eventId + "&date=" + date.toLocalDate(), + true + ); + } + + public void editEvent(Event oldEvent, Event event) throws HttpRequestException { + sendBasicHttpRequest( + EDIT_EVENT_ENDPOINT, + "eventId=" + oldEvent.getId() + + "&userId=" + oldEvent.getOwnerId() + + "&date=" + oldEvent.getDate().toLocalDate() + + "&newDate=" + event.getDate().toLocalDate() + + "&newName=" + event.getName() + + "&newStart=" + event.getStart() + + "&newEnd=" + event.getEnd() + + "&newPriority=" + event.getPriority() + + "&newIsFullDay=" + event.isFullDay() + + "&newIsPrivate=" + event.isPrivate(), + true + ); + } + + public ArrayList getAllVisibleEvents(LocalDateTime startDate, LocalDateTime endDate) throws HttpRequestException { + try { + Tuple response = httpRequest.sendPostRequest( + ALL_EVENTS_ENDPOINT, + "userId=" + USER_ID + "&startDate=" + startDate.toLocalDate() + "&endDate=" + endDate.toLocalDate(), + true + ); + if (response.getKey() != 200) { + throw new HttpRequestException(response); + } + String jsonResponse = response.getValue(); + System.out.println(jsonResponse); + + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.findAndRegisterModules(); + return (ArrayList) objectMapper.readValue(jsonResponse, new TypeReference>() { + }); + + } catch (HttpRequestException e) { + throw e; + } catch (Exception e) { + throw new HttpRequestException("Es konnte keine Verbindung mit dem Server hergestellt werden.", 600); + } + } + + /******** + * User * + ********/ + + public List getAllUser() throws HttpRequestException { + String userJSON = sendBasicHttpRequest( + ALL_USER_ENDPOINT, + "", + true + ); + + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.findAndRegisterModules(); + try { + List list = objectMapper.readValue(userJSON, new TypeReference<>() { + }); + + for(User u : list){ + System.out.println(u); + } + return list; + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + return new ArrayList<>(); + } + + public void createUser(User user) throws HttpRequestException { + sendBasicHttpRequest( + ADD_USER_ENDPOINT, + "name=" + user.getName() + + "&forename=" + user.getForename() + + "&login=" + user.getLogin() + + "&password=" + user.getPassword() + + "&isAdmin=" + user.isAdmin(), + true + ); + } + + public void deleteUser(User user) throws HttpRequestException { + sendBasicHttpRequest( + DELETE_USER_ENDPOINT, + "userId=" + user.getUserId(), + true + ); + } + + public void editUser(User user) throws HttpRequestException { + String urlParam = "userId=" + user.getUserId() + + "&name=" + user.getName() + + "&forename=" + user.getForename() + + "&login=" + user.getLogin() + + "&isAdmin=" + user.isAdmin() + + (user.getPassword() == null ? "" : "&password=" + user.getPassword()); + + System.out.println(urlParam); + sendBasicHttpRequest( + EDIT_USER_ENDPOINT, + urlParam, + true + ); + } + + private String sendBasicHttpRequest(String urlString, String urlParameters, boolean sendAuth) throws HttpRequestException { + try { + Tuple response = httpRequest.sendPostRequest( + urlString, + urlParameters, + sendAuth + ); + if (response.getKey() != 200) { + throw new HttpRequestException(response); + } + + return response.getValue(); + } catch (HttpRequestException e) { + throw e; + } catch (Exception e) { + throw new HttpRequestException("Es konnte keine Verbindung mit dem Server hergestellt werden.", 600); + } + } +} \ No newline at end of file diff --git a/client/data/src/main/java/res/Event.java b/client/data/src/main/java/container/Event.java similarity index 56% rename from client/data/src/main/java/res/Event.java rename to client/data/src/main/java/container/Event.java index 90e9d41..35c1d35 100644 --- a/client/data/src/main/java/res/Event.java +++ b/client/data/src/main/java/container/Event.java @@ -1,16 +1,11 @@ -package res; +package container; -import com.sun.jdi.event.StepEvent; - -import java.nio.charset.StandardCharsets; import java.time.Duration; -import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.format.DateTimeFormatter; -import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; public class Event { @@ -27,80 +22,32 @@ public class Event { private int ownerId; private String ownerName; - /* - Constructor for SELECT: - e.id AS eid, - e.name AS ename, - e.start, - e.end, - e.priority, - e.is_full_day, - - ue.date, - - u.id AS uid, - u.forename, - u.name AS uname - */ - - public Event(ArrayList arr) { - id = (int) arr.get(0); - name = (String) arr.get(1); - start = (String) arr.get(2); - end = (String) arr.get(3); - priority = (int) arr.get(4); - isFullDay = (Boolean) arr.get(5); //((String)arr.get(5)).equals("true"); - - - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); - date = LocalDateTime.parse(arr.get(6) + " 00:00", formatter); - - ownerId = (int) arr.get(7); - ownerName = arr.get(8) + " " + arr.get(9); - } + public Event() {} public Event(String name, int priority, boolean isFullDay, boolean isPrivate, - String start, - String end, + LocalTime start, + LocalTime end, LocalDateTime date, int ownerId - ) throws IllegalArgumentException{ - if(name.length() < 3){ - throw new IllegalArgumentException("Der Name muss eine L\u00e4nge von 3 haben."); + ) throws IllegalArgumentException { + + System.out.println("Create Event"); + if (name.length() < 3) { + throw new IllegalArgumentException("Der Name muss eine Länge von 3 haben."); } - Pattern pattern = Pattern.compile("[A-Za-z\u00e4\u00f6\u00fc\u00c4\u00d6\u00dc\u00df0-9 =!?+*/$.:,;_<>()-]*"); + Pattern pattern = Pattern.compile("[A-Za-zäöüÄÖÜß0-9 =!?+*/$.:,;_<>()-]*"); Matcher matcher = pattern.matcher(name); - if(!matcher.matches()){ - System.out.println(name); - - byte[] bytes = name.getBytes(StandardCharsets.UTF_16); - - String utf8EncodedString = new String(bytes, StandardCharsets.UTF_16); - System.out.println(utf8EncodedString); - - for (char c : (name).toCharArray()) { - System.out.print(c + " " + (int)c + ", "); - } - System.out.println(); - for (char c : (name).toCharArray()) { - System.out.print(c + " " + (int)c + ", "); - } - System.out.println(); - for (char c : ("TäöüÄÖÜ").toCharArray()) { - System.out.print(c + " " + (int)c + ", "); - } - System.out.println(); - - throw new IllegalArgumentException("Der Name darf nur aus Zahlen, Buchstaben und folgenden Sonderzeichen bestehen: \u00e4\u00f6\u00fc \u00c4\u00d6\u00dc \u00df =!?+*/$.:,;_ <>()-"); + if (!matcher.matches()) { + throw new IllegalArgumentException("Der Name darf nur aus Zahlen, Buchstaben und folgenden Sonderzeichen bestehen: äöü ÄÖÜ ß =!?+*/$.:,;_ <>()-"); } - if(priority < 0){ - throw new IllegalArgumentException("Bitte eine Priorit\u00e4t w\u00e4hlen."); + if (priority < 0) { + throw new IllegalArgumentException("Bitte eine Priorität wählen."); } LocalDateTime today = LocalDateTime.now().toLocalDate().atStartOfDay(); - if(Duration.between(today, date).isNegative()){ + if (Duration.between(today, date).isNegative()) { throw new IllegalArgumentException("Das Datum muss in der Zukunft liegen."); } @@ -108,8 +55,8 @@ public class Event { this.priority = priority; this.isFullDay = isFullDay; this.isPrivate = isPrivate; - this.start = start; - this.end = end; + if (start != null) this.start = start.toString(); + if (start != null) this.end = end.toString(); this.date = date; this.ownerId = ownerId; } @@ -127,7 +74,7 @@ public class Event { } public void setName(String name) { - this.name = convertToASCII(name); + this.name = name; } public int getPriority() { @@ -174,8 +121,9 @@ public class Event { return date; } - public void setDate(LocalDateTime date) { - this.date = date; + public void setDate(String date) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); + this.date = LocalDateTime.parse(date + " 00:00", formatter); } public int getOwnerId() { @@ -209,13 +157,8 @@ public class Event { "&name=" + getName() + "&start=" + getStart() + "&end=" + getEnd() + - "&prority=" + getPriority() + + "&priority=" + getPriority() + "&isFullDay=" + isFullDay() + "&isPrivate=" + isPrivate(); } - - private String convertToASCII(String s){ - byte[] germanBytes = s.getBytes(); - return new String(germanBytes, StandardCharsets.US_ASCII); - } } diff --git a/client/data/src/main/java/container/HttpRequest.java b/client/data/src/main/java/container/HttpRequest.java new file mode 100644 index 0000000..8ddf2d2 --- /dev/null +++ b/client/data/src/main/java/container/HttpRequest.java @@ -0,0 +1,77 @@ +package container; + +import helper.Tuple; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; + +public class HttpRequest { + public static String TOKEN = ""; + + public Tuple sendPostRequest(String urlString, String urlParameters, boolean sendAuth) throws Exception { + byte[] postData = urlParameters.getBytes(StandardCharsets.UTF_8); + int postDataLength = postData.length; + + URL url = new URL(urlString); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + + connection.setDoOutput(true); + connection.setInstanceFollowRedirects(false); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + connection.setRequestProperty("charset", "utf-8"); + connection.setRequestProperty("Content-Length", Integer.toString(postDataLength)); + connection.setUseCaches(false); + + if(sendAuth){ + connection.setRequestProperty("Accept", "application/json"); + connection.setRequestProperty("Authorization", "Bearer " + TOKEN); + } + + try (DataOutputStream writer = new DataOutputStream(connection.getOutputStream())) { + writer.write(postData); + } + + return getHttpTuple(connection); + } + + public Tuple sendGetRequest(String urlString) throws Exception { + URL url = new URL(urlString); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + + int status = connection.getResponseCode(); + + return getHttpTuple(connection); + } + + private Tuple getHttpTuple(HttpURLConnection connection) throws IOException { + int status = connection.getResponseCode(); + String inputLine; + StringBuilder content = new StringBuilder(); + BufferedReader in; + + if (status == 200) { + in = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)); + } else { + in = new BufferedReader(new InputStreamReader(connection.getErrorStream(), StandardCharsets.UTF_8)); + } + + while ((inputLine = in.readLine()) != null) { + content.append(inputLine); + } + in.close(); + + connection.disconnect(); + + return new Tuple<>(status, content.toString()); + } +} diff --git a/client/data/src/main/java/container/User.java b/client/data/src/main/java/container/User.java new file mode 100644 index 0000000..37e5d27 --- /dev/null +++ b/client/data/src/main/java/container/User.java @@ -0,0 +1,75 @@ +package container; + +public class User { + + private int userId; + private String login; + private String forename; + private String name; + private String password; + private boolean isAdmin; + + public User(){} + + + + public int getUserId() { + return userId; + } + + public void setUserId(int userId) { + this.userId = userId; + } + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login; + } + + public String getForename() { + return forename; + } + + public void setForename(String forename) { + this.forename = forename; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isAdmin() { + return isAdmin; + } + + public void setAdmin(boolean admin) { + isAdmin = admin; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + @Override + public String toString() { + return "User{" + + "userId=" + userId + + ", login='" + login + '\'' + + ", forename='" + forename + '\'' + + ", name='" + name + '\'' + + ", password='" + password + '\'' + + ", isAdmin=" + isAdmin + + '}'; + } +} diff --git a/client/data/src/main/java/helper/HttpRequestException.java b/client/data/src/main/java/helper/HttpRequestException.java new file mode 100644 index 0000000..972dd3f --- /dev/null +++ b/client/data/src/main/java/helper/HttpRequestException.java @@ -0,0 +1,23 @@ +package helper; + +public class HttpRequestException extends Exception{ + private int status; + + public HttpRequestException(String message, int status) { + super(message); + this.status = status; + } + + public HttpRequestException(Tuple response) { + super(response.getValue()); + this.status = response.getKey(); + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } +} diff --git a/client/data/src/main/java/helper/Tuple.java b/client/data/src/main/java/helper/Tuple.java new file mode 100644 index 0000000..e342ad6 --- /dev/null +++ b/client/data/src/main/java/helper/Tuple.java @@ -0,0 +1,27 @@ +package helper; + +public class Tuple { + public final X key; + public final Y value; + + public Tuple(X key, Y value) { + this.key = key; + this.value = value; + } + + public X getKey() { + return key; + } + + public Y getValue() { + return value; + } + + @Override + public String toString() { + return "Tuple{" + + "key=" + key + + ", value=" + value + + '}'; + } +} diff --git a/client/data/src/main/java/res/DataController.java b/client/data/src/main/java/res/DataController.java deleted file mode 100644 index 1ac15b5..0000000 --- a/client/data/src/main/java/res/DataController.java +++ /dev/null @@ -1,115 +0,0 @@ -package res; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -import java.io.BufferedReader; -import java.io.DataOutputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.*; - -public class DataController { - - public static long USER_ID = -1; - - private static final String ALL_EVENTS_ENDPOINT = "http://localhost:8080/event/all"; - private static final String ADD_EVENT_ENDPOINT = "http://localhost:8080/event/add"; - private static final String DELETE_EVENT_ENDPOINT = "http://localhost:8080/event/del"; - - private static final String LOGIN_ENDPOINT = "http://localhost:8080/user/login"; - private static final String ALL_USERS_ENDPOINT = "http://localhost:8080/user/all"; - - private final HttpRequest httpRequest; - - public DataController() { - httpRequest = new HttpRequest(); - } - - public boolean login(String username, String password) { - try { - USER_ID = Long.parseLong(httpRequest.sendPostRequest( - LOGIN_ENDPOINT, - "login=" + username - + "&password=" + password, - false - )); - } catch (Exception e) { - e.printStackTrace(); - return false; - } - return USER_ID >= 0; - } - - public void createEvent(Event event) { - try { - System.out.println(httpRequest.sendPostRequest(ADD_EVENT_ENDPOINT, event.getAsUrlParam(), true)); - } catch (Exception e) { - throw new RuntimeException("Es konnte keine Verbindung mit dem Server hergestellt werden."); - } - } - - public void deleteEvent(int eventId) { - try { - System.out.println(httpRequest.sendPostRequest(DELETE_EVENT_ENDPOINT, "eventId=" + eventId, true)); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public ArrayList getAllVisibleEvents() { - ArrayList eventList = new ArrayList<>(); - - try { - String jsonResponse = httpRequest.sendPostRequest(ALL_EVENTS_ENDPOINT, "userId=" + USER_ID, true); - System.out.println(jsonResponse); - - ObjectMapper objectMapper = new ObjectMapper(); - //String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }"; - - for (Object obj : objectMapper.readValue(jsonResponse, Object[].class)) { - ArrayList list = new ArrayList<>(); - if (obj.getClass().isArray()) { - list = (ArrayList) Arrays.asList((Object[]) obj); - } else if (obj instanceof Collection) { - list = new ArrayList<>((Collection) obj); - } - eventList.add(new Event(list)); - - } - } catch (Exception e) { - e.printStackTrace(); - } - - return eventList; - } - - public Event[] getAllEvents() { - Event[] eventList = null; - - try { - String jsonResponse = httpRequest.sendGetRequest("http://localhost:8080/vpr/all-events-test"); - eventList = parseJsonToEventList(jsonResponse); - for (Event e : eventList) { - System.out.println(e); - } - } catch (Exception e) { - e.printStackTrace(); - } - - return eventList; - } - - private Event[] parseJsonToEventList(String jsonString) throws JsonProcessingException { - ArrayList eventList; - - // Parse JSON - ObjectMapper objectMapper = new ObjectMapper(); - //String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }"; - - return objectMapper.readValue(jsonString, Event[].class); - } -} \ No newline at end of file diff --git a/client/data/src/main/java/res/HttpRequest.java b/client/data/src/main/java/res/HttpRequest.java deleted file mode 100644 index 398f157..0000000 --- a/client/data/src/main/java/res/HttpRequest.java +++ /dev/null @@ -1,95 +0,0 @@ -package res; - -import java.io.BufferedReader; -import java.io.DataOutputStream; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; - -public class HttpRequest { - public String sendPostRequest(String urlString, String urlParameters, boolean sendAuth) throws Exception { - byte[] postData = urlParameters.getBytes(StandardCharsets.UTF_8); - int postDataLength = postData.length; - - /* - URL url = new URL("http://test.de:8080/event/add"); - HttpURLConnection http = (HttpURLConnection)url.openConnection(); - http.setRequestMethod("POST"); - http.setDoOutput(true); - http.setRequestProperty("Accept", "application/json"); - http.setRequestProperty("Authorization", "Bearer {token}"); - http.setRequestProperty("Content-Type", ""); - http.setRequestProperty("Content-Length", "0"); - - System.out.println(http.getResponseCode() + " " + http.getResponseMessage()); - http.disconnect(); - */ - URL url = new URL(urlString); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - - con.setDoOutput(true); - con.setInstanceFollowRedirects(false); - con.setRequestMethod("POST"); - con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - con.setRequestProperty("charset", "utf-8"); - con.setRequestProperty("Content-Length", Integer.toString(postDataLength)); - con.setUseCaches(false); - - if(sendAuth){ - con.setRequestProperty("Accept", "application/json"); - con.setRequestProperty("Authorization", "Bearer {token}"); - } - - try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) { - wr.write(postData); - } - - int status = con.getResponseCode(); - if (status == 200) { - BufferedReader in = new BufferedReader( - new InputStreamReader(con.getInputStream())); - String inputLine; - StringBuilder content = new StringBuilder(); - while ((inputLine = in.readLine()) != null) { - content.append(inputLine); - } - in.close(); - - con.disconnect(); - return content.toString(); - } else { - con.disconnect(); - throw new Exception("Status: " + status); - } - } - - public String sendGetRequest(String urlString) throws Exception { - URL url = new URL(urlString); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("GET"); - - con.setConnectTimeout(5000); - con.setReadTimeout(5000); - - int status = con.getResponseCode(); - if (status == 200) { - BufferedReader in = new BufferedReader( - new InputStreamReader(con.getInputStream())); - String inputLine; - StringBuilder content = new StringBuilder(); - while ((inputLine = in.readLine()) != null) { - content.append(inputLine); - } - in.close(); - - con.disconnect(); - return content.toString(); - - } else { - con.disconnect(); - throw new Exception("Status: " + status); - } - } -}