From db2341a23d865260af26ea006659d39dcc40263c Mon Sep 17 00:00:00 2001 From: peng Date: Thu, 11 Nov 2021 20:53:02 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E7=BB=93?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + config/config.json | 36 +-- pom.xml | 81 +++++ src/com/dayrain/ApplicationStarter.java | 18 -- src/com/dayrain/component/LogArea.java | 15 - src/com/dayrain/component/RequestType.java | 5 - src/com/dayrain/handle/AddServerHandler.java | 89 ------ src/com/dayrain/handle/AddUrlHandler.java | 128 -------- .../dayrain/handle/DeleteServerHandler.java | 45 --- src/com/dayrain/handle/DeleteUrlHandler.java | 57 ---- .../dayrain/handle/ExportConfigHandler.java | 46 --- .../dayrain/handle/ImportConfigHandler.java | 49 --- .../dayrain/handle/StartServerHandler.java | 56 ---- .../handle/UpdateRandomLenHandler.java | 79 ----- .../handle/UpdateServerConfigHandler.java | 78 ----- src/com/dayrain/handle/UpdateUrlHandler.java | 108 ------- src/com/dayrain/views/HomePage.java | 282 ------------------ .../com/dayrain/component/ConfigHolder.java | 16 +- .../com/dayrain/component/Configuration.java | 8 +- .../com/dayrain/component/ConsoleLog.java | 21 +- .../com/dayrain/component/RequestHandler.java | 12 +- .../com/dayrain/component/RequestType.java | 9 + .../java}/com/dayrain/component/Server.java | 33 +- .../com/dayrain/component/ServerConfig.java | 7 +- .../dayrain/component/ServerThreadHolder.java | 68 +++++ .../com/dayrain/component/ServerUrl.java | 6 +- .../com/dayrain/server/ServerThread.java | 14 + .../com/dayrain/style/BackGroundFactory.java | 15 + .../com/dayrain/style/ButtonFactory.java | 0 .../java/com/dayrain/style/CircleFactory.java | 18 ++ .../java/com/dayrain/style/FormFactory.java | 30 ++ .../java/com/dayrain/style/IconFactory.java | 10 + .../java}/com/dayrain/style/LabelFactory.java | 0 .../java/com/dayrain/style/StageFactory.java | 30 ++ .../java}/com/dayrain/utils/FileUtils.java | 4 +- .../com/dayrain/utils/ListViewHelper.java | 0 .../com/dayrain/views/ApplicationStarter.java | 32 ++ src/main/java/com/dayrain/views/HomeView.java | 85 ++++++ src/main/java/com/dayrain/views/LogArea.java | 34 +++ .../java/com/dayrain/views/MenuBarView.java | 210 +++++++++++++ .../com/dayrain/views/ServerContainer.java | 28 ++ .../java/com/dayrain/views/ServerPane.java | 239 +++++++++++++++ .../com/dayrain/views/ServerUrlListView.java | 54 ++++ .../com/dayrain/views/ServerUrlPaneView.java | 156 ++++++++++ .../java/com/dayrain/views/ViewHolder.java | 50 ++++ src/{ => main}/resources/close.png | Bin src/{ => main}/resources/config.json | 0 src/main/resources/logback.xml | 33 ++ src/{ => main}/resources/min.png | Bin src/{ => main}/resources/panda.png | Bin 50 files changed, 1286 insertions(+), 1110 deletions(-) create mode 100644 pom.xml delete mode 100644 src/com/dayrain/ApplicationStarter.java delete mode 100644 src/com/dayrain/component/LogArea.java delete mode 100644 src/com/dayrain/component/RequestType.java delete mode 100644 src/com/dayrain/handle/AddServerHandler.java delete mode 100644 src/com/dayrain/handle/AddUrlHandler.java delete mode 100644 src/com/dayrain/handle/DeleteServerHandler.java delete mode 100644 src/com/dayrain/handle/DeleteUrlHandler.java delete mode 100644 src/com/dayrain/handle/ExportConfigHandler.java delete mode 100644 src/com/dayrain/handle/ImportConfigHandler.java delete mode 100644 src/com/dayrain/handle/StartServerHandler.java delete mode 100644 src/com/dayrain/handle/UpdateRandomLenHandler.java delete mode 100644 src/com/dayrain/handle/UpdateServerConfigHandler.java delete mode 100644 src/com/dayrain/handle/UpdateUrlHandler.java delete mode 100644 src/com/dayrain/views/HomePage.java rename src/{ => main/java}/com/dayrain/component/ConfigHolder.java (60%) rename src/{ => main/java}/com/dayrain/component/Configuration.java (93%) rename src/{ => main/java}/com/dayrain/component/ConsoleLog.java (80%) rename src/{ => main/java}/com/dayrain/component/RequestHandler.java (92%) create mode 100644 src/main/java/com/dayrain/component/RequestType.java rename src/{ => main/java}/com/dayrain/component/Server.java (60%) rename src/{ => main/java}/com/dayrain/component/ServerConfig.java (94%) create mode 100644 src/main/java/com/dayrain/component/ServerThreadHolder.java rename src/{ => main/java}/com/dayrain/component/ServerUrl.java (96%) rename src/{ => main/java}/com/dayrain/server/ServerThread.java (60%) create mode 100644 src/main/java/com/dayrain/style/BackGroundFactory.java rename src/{ => main/java}/com/dayrain/style/ButtonFactory.java (100%) create mode 100644 src/main/java/com/dayrain/style/CircleFactory.java create mode 100644 src/main/java/com/dayrain/style/FormFactory.java create mode 100644 src/main/java/com/dayrain/style/IconFactory.java rename src/{ => main/java}/com/dayrain/style/LabelFactory.java (100%) create mode 100644 src/main/java/com/dayrain/style/StageFactory.java rename src/{ => main/java}/com/dayrain/utils/FileUtils.java (97%) rename src/{ => main/java}/com/dayrain/utils/ListViewHelper.java (100%) create mode 100644 src/main/java/com/dayrain/views/ApplicationStarter.java create mode 100644 src/main/java/com/dayrain/views/HomeView.java create mode 100644 src/main/java/com/dayrain/views/LogArea.java create mode 100644 src/main/java/com/dayrain/views/MenuBarView.java create mode 100644 src/main/java/com/dayrain/views/ServerContainer.java create mode 100644 src/main/java/com/dayrain/views/ServerPane.java create mode 100644 src/main/java/com/dayrain/views/ServerUrlListView.java create mode 100644 src/main/java/com/dayrain/views/ServerUrlPaneView.java create mode 100644 src/main/java/com/dayrain/views/ViewHolder.java rename src/{ => main}/resources/close.png (100%) rename src/{ => main}/resources/config.json (100%) create mode 100644 src/main/resources/logback.xml rename src/{ => main}/resources/min.png (100%) rename src/{ => main}/resources/panda.png (100%) diff --git a/.gitignore b/.gitignore index 17ed249..e2a82f7 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* *.idea + +logs diff --git a/config/config.json b/config/config.json index 05d44bd..2148a9c 100644 --- a/config/config.json +++ b/config/config.json @@ -1,40 +1,8 @@ { - "projectName" : "HTTP SERVER 模拟器", + "projectName" : "HTTP SERVER 模拟器 V1.4", "width" : 1200, "height" : 800, "stringLen" : 8, "intLen" : 8, - "serverConfigs" : [ { - "serverName" : "天津众华WMS", - "port" : 8099, - "serverUrls" : [ { - "urlName" : "入库任务完成上报", - "url" : "/wz/accept/report", - "serverName" : "天津众华WMS", - "requestType" : "POST", - "responseBody" : "{\n\t\"code\": 0,\n\t\"message\": \"success\"\n}", - "headerMap" : null - }, { - "urlName" : "出库任务完成上报", - "url" : "/wz/order/report", - "serverName" : "天津众华WMS", - "requestType" : "POST", - "responseBody" : "{\n\t\"code\": 0,\n \"message\":\"success\"\n}", - "headerMap" : null - }, { - "urlName" : "盘点结果同步", - "url" : "/wz/material/update", - "serverName" : "天津众华WMS", - "requestType" : "POST", - "responseBody" : "{\n\"code\": 0,\n\"message\": \"success\"\n}", - "headerMap" : null - }, { - "urlName" : "物资信息定时同步", - "url" : "/wz/material/infos", - "serverName" : "天津众华WMS", - "requestType" : "POST", - "responseBody" : "{\n\t\"code\": 0,\n\t\"message\": \"success\"\n}", - "headerMap" : null - } ] - } ] + "serverConfigs" : null } \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..4e11796 --- /dev/null +++ b/pom.xml @@ -0,0 +1,81 @@ + + + 4.0.0 + + com.dayrain + http-server-simulator + 1.4 + + + 8 + 8 + + + + + ch.qos.logback + logback-classic + 1.2.5 + + + + com.fasterxml.jackson.core + jackson-databind + 2.12.5 + + + + com.fasterxml.jackson.core + jackson-core + 2.12.5 + + + + com.fasterxml.jackson.core + jackson-annotations + 2.12.5 + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.1.0 + + + copy-resources + + copy-resources + + + + ${basedir}/target/extra + + + + src/resources + true + + + + + + + + + com.zenjava + javafx-maven-plugin + 8.8.3 + + dayrain + com.dayrain.views.ApplicationStarter + + + + + \ No newline at end of file diff --git a/src/com/dayrain/ApplicationStarter.java b/src/com/dayrain/ApplicationStarter.java deleted file mode 100644 index 28ba054..0000000 --- a/src/com/dayrain/ApplicationStarter.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.dayrain; - -import com.dayrain.views.HomePage; -import javafx.application.Application; -import javafx.stage.Stage; - -public class ApplicationStarter extends Application { - - public static void main(String[] args) { - - launch(args); - } - - @Override - public void start(Stage primaryStage) throws Exception { - new HomePage(primaryStage).start(); - } -} diff --git a/src/com/dayrain/component/LogArea.java b/src/com/dayrain/component/LogArea.java deleted file mode 100644 index 082ea3e..0000000 --- a/src/com/dayrain/component/LogArea.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.dayrain.component; - -import javafx.scene.control.TextArea; - -public class LogArea extends TextArea { - private String serverName; - - public String getServerName() { - return serverName; - } - - public void setServerName(String serverName) { - this.serverName = serverName; - } -} diff --git a/src/com/dayrain/component/RequestType.java b/src/com/dayrain/component/RequestType.java deleted file mode 100644 index 3ec5c36..0000000 --- a/src/com/dayrain/component/RequestType.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.dayrain.component; - -public enum RequestType { - GET, POST; -} diff --git a/src/com/dayrain/handle/AddServerHandler.java b/src/com/dayrain/handle/AddServerHandler.java deleted file mode 100644 index c0759d3..0000000 --- a/src/com/dayrain/handle/AddServerHandler.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.dayrain.handle; - -import com.dayrain.component.ConfigHolder; -import com.dayrain.component.Configuration; -import com.dayrain.component.ServerConfig; -import com.dayrain.style.ButtonFactory; -import com.dayrain.style.LabelFactory; -import com.dayrain.views.HomePage; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.geometry.Pos; -import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.TextField; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.HBox; -import javafx.stage.Modality; -import javafx.stage.Stage; - -import java.util.ArrayList; - -/** - * 添加server - * - * @author peng - * @date 2021/10/28 - */ -public class AddServerHandler implements EventHandler { - - private final Stage primaryStage; - - private final Configuration configuration; - - private final HomePage homePage; - - public AddServerHandler(Stage primaryStage, Configuration configuration, HomePage homePage) { - this.primaryStage = primaryStage; - this.configuration = configuration; - this.homePage = homePage; - } - - @Override - public void handle(ActionEvent event) { - Stage stage = new Stage(); - Label nameLabel = LabelFactory.getLabel("服务名称:"); - nameLabel.setPrefWidth(80); - TextField nameField = new TextField(); - Label portLabel = LabelFactory.getLabel("端口号:"); - TextField portField = new TextField(); - portField.setPrefWidth(80); - - HBox btnHBox = new HBox(); - Button saveButton = ButtonFactory.getButton("保存"); - btnHBox.getChildren().add(saveButton); - btnHBox.setAlignment(Pos.CENTER_RIGHT); - - GridPane gridPane = new GridPane(); - gridPane.add(nameLabel, 0, 0); - gridPane.add(nameField, 1, 0); - gridPane.add(portLabel, 0, 1); - gridPane.add(portField, 1, 1); - gridPane.add(btnHBox, 1, 3); - gridPane.setAlignment(Pos.CENTER); - gridPane.setHgap(20d); - gridPane.setVgap(10d); - - stage.setWidth(500); - stage.setHeight(400); - stage.initOwner(primaryStage); - stage.initModality(Modality.WINDOW_MODAL); - stage.setScene(new Scene(gridPane)); - stage.getIcons().addAll(primaryStage.getIcons()); - stage.show(); - - saveButton.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - String name = nameField.getText(); - String port = portField.getText(); - ServerConfig serverConfig = new ServerConfig(name, Integer.parseInt(port), new ArrayList<>()); - configuration.getServerConfigs().add(serverConfig); - homePage.refreshServerContainer(); - ConfigHolder.save(); - stage.close(); - } - }); - } -} diff --git a/src/com/dayrain/handle/AddUrlHandler.java b/src/com/dayrain/handle/AddUrlHandler.java deleted file mode 100644 index 5c27fde..0000000 --- a/src/com/dayrain/handle/AddUrlHandler.java +++ /dev/null @@ -1,128 +0,0 @@ -package com.dayrain.handle; - -import com.dayrain.component.ConfigHolder; -import com.dayrain.component.RequestType; -import com.dayrain.component.ServerConfig; -import com.dayrain.component.ServerUrl; -import com.dayrain.server.ServerThread; -import com.dayrain.style.ButtonFactory; -import com.dayrain.style.LabelFactory; -import com.dayrain.utils.ListViewHelper; -import javafx.collections.FXCollections; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.geometry.Pos; -import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.ChoiceBox; -import javafx.scene.control.Label; -import javafx.scene.control.ListView; -import javafx.scene.control.TextArea; -import javafx.scene.control.TextField; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.HBox; -import javafx.stage.Modality; -import javafx.stage.Stage; - -import java.util.HashMap; -import java.util.List; - -/** - * 添加路径 - * - * @author peng - * @date 2021/10/27 - */ -public class AddUrlHandler implements EventHandler { - - private final ServerConfig serverConfig; - - private final ListView serverUrlListView; - - private final HashMap threadMap; - - private final Stage primaryStage; - - public AddUrlHandler(ServerConfig serverConfig, ListView serverUrlListView, HashMap threadMap, Stage primaryStage) { - this.serverConfig = serverConfig; - this.serverUrlListView = serverUrlListView; - this.threadMap = threadMap; - this.primaryStage = primaryStage; - } - - @Override - public void handle(ActionEvent event) { - Stage stage = new Stage(); - Label nameLabel = LabelFactory.getLabel("接口名称:"); - nameLabel.setPrefWidth(80); - TextField nameField = new TextField(); - - Label urlLabel = LabelFactory.getLabel("接口地址:"); - TextField urlField = new TextField(); - urlField.setPrefWidth(80); - - Label methodLabel = LabelFactory.getLabel("请求方式:"); - ChoiceBox choiceBox = new ChoiceBox<>(); - choiceBox.setItems(FXCollections.observableArrayList("POST", "GET")); - choiceBox.setValue("POST"); - urlField.setPrefWidth(80); - - Label respLabel = LabelFactory.getLabel("返回结果:"); - TextArea textArea = new TextArea(); - textArea.setPrefWidth(80); - - HBox btnHBox = new HBox(); - Button saveButton = ButtonFactory.getButton("保存"); - btnHBox.getChildren().add(saveButton); - btnHBox.setAlignment(Pos.CENTER_RIGHT); - - GridPane gridPane = new GridPane(); - gridPane.add(methodLabel, 0, 0); - gridPane.add(choiceBox, 1, 0); - gridPane.add(nameLabel, 0, 1); - gridPane.add(nameField, 1, 1); - gridPane.add(urlLabel, 0, 2); - gridPane.add(urlField, 1, 2); - gridPane.add(respLabel, 0, 3); - gridPane.add(textArea, 1, 3); - gridPane.add(btnHBox, 1, 4); - gridPane.setAlignment(Pos.CENTER); - gridPane.setHgap(20d); - gridPane.setVgap(10d); - - stage.setWidth(550); - stage.setHeight(500); - stage.initOwner(primaryStage); - stage.initModality(Modality.WINDOW_MODAL); - stage.setScene(new Scene(gridPane)); - stage.getIcons().addAll(primaryStage.getIcons()); - stage.show(); - - saveButton.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - String name = nameField.getText(); - List serverUrls = serverConfig.getServerUrls(); - for (ServerUrl serverUrl : serverUrls) { - if (serverUrl.getUrlName().equals(name)) { - return; - } - } - String url = urlField.getText(); - String resp = textArea.getText(); - - String type = choiceBox.getValue(); - ServerUrl serverUrl = new ServerUrl(serverConfig.getServerName(), name, url, type.equals(RequestType.POST.name()) ? RequestType.POST : RequestType.GET, resp); - serverUrls.add(serverUrl); - ServerThread serverThread = threadMap.getOrDefault(serverConfig.getServerName(), null); - if (serverThread != null) { - serverThread.addContext(serverUrl); - } - ListViewHelper.addAndRefresh(serverUrl, serverUrlListView); - ConfigHolder.save(); - stage.close(); - } - }); - } - -} diff --git a/src/com/dayrain/handle/DeleteServerHandler.java b/src/com/dayrain/handle/DeleteServerHandler.java deleted file mode 100644 index c5a7dd4..0000000 --- a/src/com/dayrain/handle/DeleteServerHandler.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.dayrain.handle; - -import com.dayrain.component.ConfigHolder; -import com.dayrain.component.Configuration; -import com.dayrain.component.ServerConfig; -import com.dayrain.views.HomePage; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.scene.control.Alert; -import javafx.scene.control.Button; -import javafx.scene.control.ButtonType; -import javafx.scene.image.ImageView; -import javafx.stage.Stage; - -public class DeleteServerHandler implements EventHandler { - - private final ServerConfig serverConfig; - - private final Configuration configuration; - - private final HomePage homePage; - - public DeleteServerHandler(ServerConfig serverConfig, Configuration configuration, HomePage homePage) { - this.serverConfig = serverConfig; - this.configuration = configuration; - this.homePage = homePage; - } - - @Override - public void handle(ActionEvent event) { - Alert alert = new Alert(Alert.AlertType.CONFIRMATION); - - alert.setGraphic(new ImageView(homePage.getIcon())); - Stage stage = (Stage) alert.getDialogPane().getScene().getWindow(); - stage.getIcons().add(homePage.getIcon()); - alert.setHeaderText("是否确定删除该服务?"); - Button okButton = (Button) alert.getDialogPane().lookupButton(ButtonType.OK); - okButton.setOnAction(event1 -> { - configuration.getServerConfigs().remove(serverConfig); - homePage.refreshServerContainer(); - ConfigHolder.save(); - }); - alert.show(); - } -} diff --git a/src/com/dayrain/handle/DeleteUrlHandler.java b/src/com/dayrain/handle/DeleteUrlHandler.java deleted file mode 100644 index c600c1b..0000000 --- a/src/com/dayrain/handle/DeleteUrlHandler.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.dayrain.handle; - -import com.dayrain.component.ConfigHolder; -import com.dayrain.component.ServerConfig; -import com.dayrain.component.ServerUrl; -import com.dayrain.utils.ListViewHelper; -import com.dayrain.views.HomePage; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.scene.control.Alert; -import javafx.scene.control.Button; -import javafx.scene.control.ButtonType; -import javafx.scene.control.ListView; -import javafx.scene.image.ImageView; -import javafx.stage.Stage; - -import java.util.List; - -/** - * 删除路径 - * @author peng - * @date 2021/10/27 - */ -public class DeleteUrlHandler implements EventHandler { - - private final ServerConfig serverConfig; - - private final ListView serverUrlListView; - - private final ServerUrl serverUrl; - - private final HomePage homePage; - - public DeleteUrlHandler(ServerUrl serverUrl, ServerConfig serverConfig, ListView serverUrlListView, HomePage homePage) { - this.serverUrl = serverUrl; - this.serverConfig = serverConfig; - this.serverUrlListView = serverUrlListView; - this.homePage = homePage; - } - - @Override - public void handle(ActionEvent event) { - Alert alert = new Alert(Alert.AlertType.CONFIRMATION); - alert.setGraphic(new ImageView(homePage.getIcon())); - Stage stage = (Stage) alert.getDialogPane().getScene().getWindow(); - stage.getIcons().add(homePage.getIcon()); - alert.setHeaderText("是否确定删除该接口?"); - Button okButton = (Button) alert.getDialogPane().lookupButton(ButtonType.OK); - okButton.setOnAction(event1 -> { - List serverUrls = serverConfig.getServerUrls(); - serverUrls.remove(serverUrl); - ConfigHolder.save(); - ListViewHelper.deleteAndRefresh(serverUrl, serverUrlListView); - }); - alert.show(); - } -} diff --git a/src/com/dayrain/handle/ExportConfigHandler.java b/src/com/dayrain/handle/ExportConfigHandler.java deleted file mode 100644 index 18dc6ca..0000000 --- a/src/com/dayrain/handle/ExportConfigHandler.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.dayrain.handle; - -import com.dayrain.component.Configuration; -import com.dayrain.utils.FileUtils; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.stage.FileChooser; -import javafx.stage.Stage; - -import java.io.File; - -/** - * 导出配置文件 - * - * @author peng - * @date 2021/10/28 - */ -public class ExportConfigHandler implements EventHandler { - - private final Stage primaryStage; - - private final Configuration configuration; - - public ExportConfigHandler(Stage primaryStage, Configuration configuration) { - this.primaryStage = primaryStage; - this.configuration = configuration; - } - - @Override - public void handle(ActionEvent event) { - Stage stage = new Stage(); - stage.initOwner(primaryStage); - FileChooser fileChooser = new FileChooser(); - String projectName = configuration.getProjectName(); - if (projectName == null) { - projectName = ""; - } - projectName += "server"; - fileChooser.setTitle("导出配置"); - fileChooser.setInitialFileName(projectName + ".json"); - File file = fileChooser.showSaveDialog(stage); - if (file != null) { - FileUtils.saveConfig(configuration, file); - } - } -} diff --git a/src/com/dayrain/handle/ImportConfigHandler.java b/src/com/dayrain/handle/ImportConfigHandler.java deleted file mode 100644 index b30ebd8..0000000 --- a/src/com/dayrain/handle/ImportConfigHandler.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.dayrain.handle; - -import com.dayrain.component.ConfigHolder; -import com.dayrain.component.Configuration; -import com.dayrain.utils.FileUtils; -import com.dayrain.views.HomePage; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.stage.FileChooser; -import javafx.stage.Stage; - -import java.io.File; - -/** - * 导入配置文件 - * - * @author peng - * @date 2021/10/28 - */ -public class ImportConfigHandler implements EventHandler { - - private final Stage primaryStage; - - private final HomePage homePage; - - public ImportConfigHandler(Stage primaryStage, HomePage homePage) { - this.primaryStage = primaryStage; - this.homePage = homePage; - } - - @Override - public void handle(ActionEvent event) { - Stage stage = new Stage(); - stage.initOwner(primaryStage); - FileChooser fileChooser = new FileChooser(); - fileChooser.setTitle("选择一个文件"); - //过滤器 - fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("只能导入json文件", "*.json")); - File file = fileChooser.showOpenDialog(stage); - - if (file != null) { - Configuration loadConfig = FileUtils.load(file); - ConfigHolder.replace(loadConfig); - FileUtils.saveConfig(loadConfig); - homePage.replaceConfig(loadConfig); - homePage.restart(); - } - } -} diff --git a/src/com/dayrain/handle/StartServerHandler.java b/src/com/dayrain/handle/StartServerHandler.java deleted file mode 100644 index d79607f..0000000 --- a/src/com/dayrain/handle/StartServerHandler.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.dayrain.handle; - -import com.dayrain.component.Server; -import com.dayrain.component.ServerConfig; -import com.dayrain.server.ServerThread; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.scene.control.Button; -import javafx.scene.paint.Color; -import javafx.scene.shape.Circle; - -import java.util.HashMap; - -/** - * 服务启动与关闭控制器 - * - * @author peng - * @date 2021/10/27 - */ -public class StartServerHandler implements EventHandler { - - private final Button openButton; - - private final Circle statusCircle; - - private final ServerConfig serverConfig; - - private final HashMap threadMap; - - public StartServerHandler(Button openButton, Circle statusCircle, ServerConfig serverConfig, HashMap threadMap) { - this.openButton = openButton; - this.statusCircle = statusCircle; - this.serverConfig = serverConfig; - this.threadMap = threadMap; - } - - @Override - public void handle(ActionEvent event) { - String serverName = serverConfig.getServerName(); - if (threadMap.containsKey(serverName)) { - ServerThread serverThread = threadMap.get(serverName); - if (serverThread != null) { - serverThread.stopServer(); - } - threadMap.remove(serverName); - openButton.setText("开启服务"); - statusCircle.setFill(Color.RED); - } else { - ServerThread serverThread = new ServerThread(new Server(serverConfig)); - serverThread.start(); - threadMap.put(serverName, serverThread); - openButton.setText("关闭服务"); - statusCircle.setFill(Color.GREEN); - } - } -} diff --git a/src/com/dayrain/handle/UpdateRandomLenHandler.java b/src/com/dayrain/handle/UpdateRandomLenHandler.java deleted file mode 100644 index dc4825b..0000000 --- a/src/com/dayrain/handle/UpdateRandomLenHandler.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.dayrain.handle; - -import com.dayrain.component.ConfigHolder; -import com.dayrain.component.Configuration; -import com.dayrain.style.ButtonFactory; -import com.dayrain.style.LabelFactory; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.geometry.Pos; -import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.TextField; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.HBox; -import javafx.stage.Modality; -import javafx.stage.Stage; - -public class UpdateRandomLenHandler implements EventHandler { - - private final Stage primaryStage; - - public UpdateRandomLenHandler(Stage primaryStage) { - this.primaryStage = primaryStage; - } - - @Override - public void handle(ActionEvent event) { - Configuration configuration = ConfigHolder.get(); - Stage stage = new Stage(); - Label strName = LabelFactory.getLabel("随机字符长度:"); - strName.setPrefWidth(150); - TextField strField = new TextField(String.valueOf(configuration.getStringLen())); - Label intName = LabelFactory.getLabel("随机整数长度:"); - TextField intField = new TextField(String.valueOf(configuration.getIntLen())); - intField.setPrefWidth(150); - - HBox btnHBox = new HBox(); - Label saveTips1 = LabelFactory.getLabel("注: $string$代指随机字符串"); - Label saveTips2 = LabelFactory.getLabel("$int$代指随机整数"); - Button saveButton = ButtonFactory.getButton("保存"); - btnHBox.getChildren().addAll(saveButton); - btnHBox.setAlignment(Pos.CENTER_RIGHT); - btnHBox.setSpacing(20d); - - GridPane gridPane = new GridPane(); - gridPane.add(strName, 0, 0); - gridPane.add(strField, 1, 0); - gridPane.add(intName, 0, 1); - gridPane.add(intField, 1, 1); - gridPane.add(saveTips1, 0, 3); - gridPane.add(saveTips2, 1, 3); - - gridPane.add(btnHBox, 1, 4); - gridPane.setAlignment(Pos.CENTER); - gridPane.setHgap(20d); - gridPane.setVgap(10d); - - stage.setWidth(500); - stage.setHeight(400); - stage.initOwner(primaryStage); - stage.initModality(Modality.WINDOW_MODAL); - stage.setScene(new Scene(gridPane)); - stage.getIcons().addAll(primaryStage.getIcons()); - stage.show(); - - saveButton.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - String strLen = strField.getText(); - String intLen = intField.getText(); - configuration.setStringLen(Integer.parseInt(strLen)); - configuration.setIntLen(Integer.parseInt(intLen)); - ConfigHolder.save(); - stage.close(); - } - }); - } -} diff --git a/src/com/dayrain/handle/UpdateServerConfigHandler.java b/src/com/dayrain/handle/UpdateServerConfigHandler.java deleted file mode 100644 index c095e0c..0000000 --- a/src/com/dayrain/handle/UpdateServerConfigHandler.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.dayrain.handle; - -import com.dayrain.component.ConfigHolder; -import com.dayrain.component.ServerConfig; -import com.dayrain.style.ButtonFactory; -import com.dayrain.style.LabelFactory; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.geometry.Pos; -import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.TextField; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.HBox; -import javafx.stage.Modality; -import javafx.stage.Stage; - -public class UpdateServerConfigHandler implements EventHandler { - - private final ServerConfig serverConfig; - - private final Stage primaryStage; - - public UpdateServerConfigHandler(ServerConfig serverConfig, Stage primaryStage) { - this.serverConfig = serverConfig; - this.primaryStage = primaryStage; - } - - @Override - public void handle(ActionEvent event) { - Stage stage = new Stage(); - Label serverName = LabelFactory.getLabel("服务名称:"); - serverName.setPrefWidth(80); - TextField nameField = new TextField(serverConfig.getServerName()); - Label portLabel = LabelFactory.getLabel("端口:"); - TextField portField = new TextField(String.valueOf(serverConfig.getPort())); - portField.setPrefWidth(80); - - HBox btnHBox = new HBox(); - Label saveTips = LabelFactory.getLabel("重启后生效"); - Button saveButton = ButtonFactory.getButton("保存"); - btnHBox.getChildren().addAll(saveTips, saveButton); - btnHBox.setAlignment(Pos.CENTER_RIGHT); - btnHBox.setSpacing(20d); - - GridPane gridPane = new GridPane(); - gridPane.add(serverName, 0, 0); - gridPane.add(nameField, 1, 0); - gridPane.add(portLabel, 0, 1); - gridPane.add(portField, 1, 1); - - gridPane.add(btnHBox, 1, 3); - gridPane.setAlignment(Pos.CENTER); - gridPane.setHgap(20d); - gridPane.setVgap(10d); - - stage.setWidth(500); - stage.setHeight(400); - stage.initOwner(primaryStage); - stage.initModality(Modality.WINDOW_MODAL); - stage.setScene(new Scene(gridPane)); - stage.getIcons().addAll(primaryStage.getIcons()); - stage.show(); - - saveButton.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - String name = nameField.getText(); - int port = Integer.parseInt(portField.getText()); - serverConfig.setPort(port); - serverConfig.setServerName(name); - ConfigHolder.save(); - stage.close(); - } - }); - } -} diff --git a/src/com/dayrain/handle/UpdateUrlHandler.java b/src/com/dayrain/handle/UpdateUrlHandler.java deleted file mode 100644 index b1c26fc..0000000 --- a/src/com/dayrain/handle/UpdateUrlHandler.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.dayrain.handle; - -import com.dayrain.component.ConfigHolder; -import com.dayrain.component.RequestType; -import com.dayrain.component.ServerUrl; -import com.dayrain.style.ButtonFactory; -import com.dayrain.style.LabelFactory; -import com.dayrain.utils.ListViewHelper; -import javafx.collections.FXCollections; -import javafx.event.ActionEvent; -import javafx.event.EventHandler; -import javafx.geometry.Pos; -import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.ChoiceBox; -import javafx.scene.control.Label; -import javafx.scene.control.ListView; -import javafx.scene.control.TextArea; -import javafx.scene.control.TextField; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.HBox; -import javafx.stage.Modality; -import javafx.stage.Stage; - - -public class UpdateUrlHandler implements EventHandler { - - private final ListView serverUrlListView; - - private final ServerUrl serverUrl; - - private final Stage primaryStage; - - public UpdateUrlHandler(ServerUrl serverUrl, ListView serverUrlListView, Stage primaryStage) { - this.serverUrl = serverUrl; - this.serverUrlListView = serverUrlListView; - this.primaryStage = primaryStage; - } - - @Override - public void handle(ActionEvent event) { - Stage stage = new Stage(); - Label nameLabel = LabelFactory.getLabel("接口名称:"); - nameLabel.setPrefWidth(80); - TextField nameField = new TextField(serverUrl.getUrlName()); - Label urlLabel = LabelFactory.getLabel("接口地址:"); - TextField urlField = new TextField(serverUrl.getUrl()); - urlField.setEditable(false); - urlField.setPrefWidth(80); - - Label methodLabel = LabelFactory.getLabel("请求方式:"); - ChoiceBox choiceBox = new ChoiceBox<>(); - choiceBox.setItems(FXCollections.observableArrayList("POST", "GET")); - choiceBox.setValue("POST"); - urlField.setPrefWidth(80); - - Label respLabel = LabelFactory.getLabel("返回结果:"); - TextArea textArea = new TextArea(serverUrl.getResponseBody()); - textArea.setPrefWidth(80); - - HBox btnHBox = new HBox(); - - Button saveButton = ButtonFactory.getButton("保存"); - btnHBox.getChildren().addAll(saveButton); - btnHBox.setAlignment(Pos.CENTER_RIGHT); - btnHBox.setSpacing(20d); - - GridPane gridPane = new GridPane(); - gridPane.add(methodLabel, 0, 0); - gridPane.add(choiceBox, 1, 0); - gridPane.add(nameLabel, 0, 1); - gridPane.add(nameField, 1, 1); - gridPane.add(urlLabel, 0, 2); - gridPane.add(urlField, 1, 2); - gridPane.add(respLabel, 0, 3); - gridPane.add(textArea, 1, 3); - gridPane.add(btnHBox, 1, 4); - gridPane.setAlignment(Pos.CENTER); - gridPane.setHgap(20d); - gridPane.setVgap(10d); - - stage.setWidth(550); - stage.setHeight(450); - stage.initOwner(primaryStage); - stage.initModality(Modality.WINDOW_MODAL); - stage.setScene(new Scene(gridPane)); - stage.getIcons().addAll(primaryStage.getIcons()); - stage.show(); - - saveButton.setOnAction(new EventHandler() { - @Override - public void handle(ActionEvent event) { - String name = nameField.getText(); - String url = urlField.getText(); - String resp = textArea.getText(); - String type = choiceBox.getValue(); - serverUrl.setUrlName(name); - serverUrl.setUrl(url); - serverUrl.setResponseBody(resp); - serverUrl.setRequestType(type.equals(RequestType.POST.name()) ? RequestType.POST : RequestType.GET); - - ListViewHelper.refresh(serverUrlListView); - ConfigHolder.save(); - stage.close(); - } - }); - } -} diff --git a/src/com/dayrain/views/HomePage.java b/src/com/dayrain/views/HomePage.java deleted file mode 100644 index c6a9254..0000000 --- a/src/com/dayrain/views/HomePage.java +++ /dev/null @@ -1,282 +0,0 @@ -package com.dayrain.views; - -import com.dayrain.component.ConfigHolder; -import com.dayrain.component.Configuration; -import com.dayrain.component.ConsoleLog; -import com.dayrain.component.LogArea; -import com.dayrain.component.ServerConfig; -import com.dayrain.component.ServerUrl; -import com.dayrain.handle.AddServerHandler; -import com.dayrain.handle.AddUrlHandler; -import com.dayrain.handle.DeleteServerHandler; -import com.dayrain.handle.DeleteUrlHandler; -import com.dayrain.handle.ExportConfigHandler; -import com.dayrain.handle.ImportConfigHandler; -import com.dayrain.handle.StartServerHandler; -import com.dayrain.handle.UpdateRandomLenHandler; -import com.dayrain.handle.UpdateServerConfigHandler; -import com.dayrain.handle.UpdateUrlHandler; -import com.dayrain.server.ServerThread; -import com.dayrain.style.ButtonFactory; -import com.dayrain.style.LabelFactory; -import javafx.beans.binding.Bindings; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.geometry.Insets; -import javafx.geometry.Pos; -import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.ListCell; -import javafx.scene.control.ListView; -import javafx.scene.control.Menu; -import javafx.scene.control.MenuBar; -import javafx.scene.control.MenuItem; -import javafx.scene.control.TitledPane; -import javafx.scene.image.Image; -import javafx.scene.layout.Background; -import javafx.scene.layout.BackgroundFill; -import javafx.scene.layout.BorderPane; -import javafx.scene.layout.CornerRadii; -import javafx.scene.layout.HBox; -import javafx.scene.layout.VBox; -import javafx.scene.paint.Color; -import javafx.scene.shape.Circle; -import javafx.scene.text.Font; -import javafx.stage.Stage; -import javafx.util.Callback; - -import java.awt.*; -import java.io.IOException; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public class HomePage { - - private Stage primaryStage; - - private Configuration configuration = ConfigHolder.init(); - - private HashMap threadMap = new HashMap<>(); - - private VBox serverContainer; - - private LogArea logArea; - - public HomePage(Stage primaryStage) { - this.primaryStage = primaryStage; - } - - public void start() { - - BorderPane borderPane = new BorderPane(); - - //菜单栏 - MenuBar menuBar = new MenuBar(); - Menu menu1 = new Menu("文件"); - MenuItem menuItem1 = new MenuItem("新建"); - MenuItem menuItem2 = new MenuItem("导入"); - MenuItem menuItem3 = new MenuItem("导出"); - menu1.getItems().addAll(menuItem1, menuItem2, menuItem3); - Menu menu2 = new Menu("设置"); - MenuItem menuItem21 = new MenuItem("随机值长度"); - menu2.getItems().add(menuItem21); - Menu menu3 = new Menu("帮助"); - MenuItem menuItem31 = new MenuItem("说明书"); - menuItem31.setOnAction(event -> { - try { - Desktop.getDesktop().browse(new URI("https://blog.csdn.net/qq_37855749/article/details/121030800")); - } catch (IOException | URISyntaxException e) { - e.printStackTrace(); - } - }); - MenuItem menuItem32 = new MenuItem("源码地址"); - menuItem32.setOnAction(event -> { - try { - Desktop.getDesktop().browse(new URI("https://github.com/DayRain/http-server-simulator")); - } catch (IOException | URISyntaxException e) { - e.printStackTrace(); - } - }); - menu3.getItems().addAll(menuItem31, menuItem32); - menuBar.getMenus().addAll(menu1, menu2, menu3); - borderPane.setTop(menuBar); - - //渲染服务列表 - this.serverContainer = new VBox(); - refreshServerContainer(); - - menuItem1.setOnAction(new AddServerHandler(primaryStage, configuration, this)); - menuItem2.setOnAction(new ImportConfigHandler(primaryStage, this)); - menuItem3.setOnAction(new ExportConfigHandler(primaryStage, configuration)); - menuItem21.setOnAction(new UpdateRandomLenHandler(primaryStage)); - borderPane.setLeft(serverContainer); - - //日志 - logArea = new LogArea(); - logArea.setEditable(false); - logArea.setFont(Font.font("Microsoft YaHei", 20)); - logArea.setPrefWidth(582); - logArea.setPrefHeight(600); - - ConsoleLog.setTextArea(logArea); - - borderPane.setRight(logArea); - - menuBar.setBackground(getBackGround()); - - Scene scene = new Scene(borderPane); - primaryStage.setTitle(configuration.getProjectName()); - primaryStage.setScene(scene); - primaryStage.setWidth(configuration.getWidth()); - primaryStage.setHeight(configuration.getHeight()); - primaryStage.getIcons().add(getIcon()); - primaryStage.show(); - primaryStage.setOnCloseRequest(event -> { - ConfigHolder.save(); - if(threadMap.size() > 0) { - for (String serverName : threadMap.keySet()) { - ServerThread serverThread = threadMap.get(serverName); - serverThread.stopServer(); - } - } - }); - } - - public void drawServerPanel(VBox serverContainer, ServerConfig serverConfig, Stage primaryStage) { - - VBox vBox = new VBox(); - HBox headBox = new HBox(); - Button editButton = ButtonFactory.getButton("修改配置"); - Button openButton = ButtonFactory.getButton("开启服务"); - Button deleteButton = ButtonFactory.getButton("删除服务"); - Button addButton = ButtonFactory.getButton("添加接口"); - Circle statusCircle = new Circle(); - statusCircle.setRadius(10); - statusCircle.setFill(Color.RED); - //设置服务启动与关闭 - openButton.setOnAction(new StartServerHandler(openButton, statusCircle, serverConfig, threadMap)); - editButton.setOnAction(new UpdateServerConfigHandler(serverConfig, primaryStage)); - deleteButton.setOnAction(new DeleteServerHandler(serverConfig, configuration, this)); - headBox.getChildren().addAll(openButton, editButton, deleteButton, addButton, statusCircle); - HBox.setMargin(statusCircle, new Insets(0, 0, 0, 30)); - headBox.setSpacing(20d); - headBox.setAlignment(Pos.CENTER); - //添加url - ListView serverUrlListView = drawUrlPanel(serverConfig.getServerUrls(), serverConfig); - addButton.setOnAction(new AddUrlHandler(serverConfig, serverUrlListView, threadMap, primaryStage)); - vBox.getChildren().addAll(headBox, serverUrlListView); - - vBox.setSpacing(10d); - VBox.setMargin(headBox, new Insets(10, 0, 0, 0)); - vBox.setPadding(Insets.EMPTY); - TitledPane titledPane = new TitledPane(serverConfig.getServerName(), vBox); - titledPane.setFont(Font.font("Microsoft YaHei", 18)); - titledPane.setPrefWidth(600d); - titledPane.setExpanded(false); - titledPane.setBackground(getBackGround()); - titledPane.setOnMouseClicked(event -> { - if (!serverConfig.getServerName().equals(logArea.getServerName())) { - ConsoleLog.resetTextArea(serverConfig.getServerName()); - } - }); - - HBox hBox = new HBox(); - hBox.setPrefHeight(60d); - titledPane.setGraphic(hBox); - - serverContainer.getChildren().add(titledPane); - } - - public ListView drawUrlPanel(List serverUrls, ServerConfig serverConfig) { - ObservableList urlList = FXCollections.observableArrayList(serverUrls); - ListView serverListViews = new ListView<>(urlList); - - serverListViews.setCellFactory(new Callback, ListCell>() { - @Override - public ListCell call(ListView param) { - return new ListCell() { - @Override - protected void updateItem(ServerUrl item, boolean empty) { - super.updateItem(item, empty); - - if (empty || item == null) { - setText(null); - setGraphic(null); - } else { - BorderPane urlPane = new BorderPane(); - - HBox labelBox = new HBox(); - Label nameLabel = LabelFactory.getLabel(item.getUrlName()); - nameLabel.setPrefWidth(150d); - Label urlLabel = LabelFactory.getLabel(item.getUrl()); - labelBox.getChildren().addAll(nameLabel, urlLabel); - labelBox.setAlignment(Pos.CENTER_LEFT); - - HBox btnBox = new HBox(); - Button configButton = ButtonFactory.getButton("配置"); - Button deleteButton = ButtonFactory.getButton("删除"); - btnBox.setSpacing(10d); - btnBox.getChildren().addAll(configButton, deleteButton); - HBox.setMargin(deleteButton, new Insets(0, 5, 0, 0)); - - deleteButton.setOnAction(new DeleteUrlHandler(item, serverConfig, serverListViews, HomePage.this)); - configButton.setOnAction(new UpdateUrlHandler(item, serverListViews, primaryStage)); - - urlPane.setLeft(labelBox); - urlPane.setRight(btnBox); - this.setGraphic(urlPane); - - } - } - }; - } - }); - - serverListViews.prefHeightProperty().bind(Bindings.size(urlList).multiply(60)); - serverListViews.setFocusTraversable(false); - - return serverListViews; - } - - public void refreshServerContainer() { - serverContainer.getChildren().removeAll(serverContainer.getChildren()); - List serverConfigs = configuration.getServerConfigs(); - if (serverConfigs == null || serverConfigs.size() == 0) { - serverConfigs = new ArrayList<>(); - configuration.setServerConfigs(serverConfigs); - } - - for (ServerConfig serverConfig : serverConfigs) { - drawServerPanel(serverContainer, serverConfig, primaryStage); - } - } - - public void restart() { - cleanUp(); - start(); - } - - public void cleanUp() { - for (String name : threadMap.keySet()) { - threadMap.get(name).stopServer(); - } - } - - public void replaceConfig(Configuration configuration) { - this.configuration = configuration; - } - - public Image getIcon() { - return new Image("resources/panda.png"); - } - - public Background getBackGround() { - BackgroundFill backgroundFill = new BackgroundFill(Color.GRAY, new CornerRadii(1), - new Insets(0.0, 0.0, 0.0, 0.0)); - return new Background(backgroundFill); - } -} diff --git a/src/com/dayrain/component/ConfigHolder.java b/src/main/java/com/dayrain/component/ConfigHolder.java similarity index 60% rename from src/com/dayrain/component/ConfigHolder.java rename to src/main/java/com/dayrain/component/ConfigHolder.java index 0d94d11..a6f38b5 100644 --- a/src/com/dayrain/component/ConfigHolder.java +++ b/src/main/java/com/dayrain/component/ConfigHolder.java @@ -1,8 +1,13 @@ package com.dayrain.component; import com.dayrain.utils.FileUtils; - +/** + * 配置类句柄 + * @author peng + * @date 2021/11/8 + */ public class ConfigHolder { + private static Configuration configuration; private ConfigHolder() { @@ -13,15 +18,18 @@ public class ConfigHolder { return configuration; } - public static void save() { + public synchronized static void save() { FileUtils.saveConfig(configuration); } - public static Configuration get() { + public synchronized static Configuration get() { + if(configuration == null) { + init(); + } return configuration; } - public static void replace(Configuration config) { + public synchronized static void replace(Configuration config) { configuration = config; } } diff --git a/src/com/dayrain/component/Configuration.java b/src/main/java/com/dayrain/component/Configuration.java similarity index 93% rename from src/com/dayrain/component/Configuration.java rename to src/main/java/com/dayrain/component/Configuration.java index b3bc209..68c4cba 100644 --- a/src/com/dayrain/component/Configuration.java +++ b/src/main/java/com/dayrain/component/Configuration.java @@ -1,10 +1,14 @@ package com.dayrain.component; import java.util.List; - +/** + * 配置文件 + * @author peng + * @date 2021/11/8 + */ public class Configuration { - private String projectName = "HTTP SERVER 模拟器"; + private String projectName = "HTTP SERVER 模拟器 V1.4"; private int width; diff --git a/src/com/dayrain/component/ConsoleLog.java b/src/main/java/com/dayrain/component/ConsoleLog.java similarity index 80% rename from src/com/dayrain/component/ConsoleLog.java rename to src/main/java/com/dayrain/component/ConsoleLog.java index 086e23d..11b1eda 100644 --- a/src/com/dayrain/component/ConsoleLog.java +++ b/src/main/java/com/dayrain/component/ConsoleLog.java @@ -1,9 +1,15 @@ package com.dayrain.component; +import com.dayrain.views.LogArea; + import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; - +/** + * 请求日志打印 + * @author peng + * @date 2021/11/8 + */ public class ConsoleLog { private static final HashMap logs = new HashMap<>(); @@ -12,11 +18,11 @@ public class ConsoleLog { private static LogArea logArea; - public static void setTextArea(LogArea area) { + public static void initTextArea(LogArea area) { logArea = area; } - public static void log(ServerUrl serverUrl, String params, String resp) { + public synchronized static void log(ServerUrl serverUrl, String params, String resp) { String log = logs.getOrDefault(serverUrl.getServerName(), null); if (log == null || NO_REQUEST.equals(log)) { log = ""; @@ -36,19 +42,26 @@ public class ConsoleLog { stringBuilder.append("\n\n"); log += stringBuilder.toString(); + + if(log.length() > 5000) { + log = log.substring(log.length() - 5000); + System.out.println(log.length()); + } + logs.put(serverUrl.getServerName(), log); if (serverUrl.getServerName().equals(logArea.getServerName())) { if (NO_REQUEST.equals(logArea.getText())) { logArea.setText(log); } else { + logArea.setText(""); logArea.appendText(log); } logArea.setScrollTop(Double.MAX_VALUE); } } - public static void resetTextArea(String serverName) { + public synchronized static void resetTextArea(String serverName) { if (!logs.containsKey(serverName)) { logs.put(serverName, NO_REQUEST); } diff --git a/src/com/dayrain/component/RequestHandler.java b/src/main/java/com/dayrain/component/RequestHandler.java similarity index 92% rename from src/com/dayrain/component/RequestHandler.java rename to src/main/java/com/dayrain/component/RequestHandler.java index 22129c9..29aea55 100644 --- a/src/com/dayrain/component/RequestHandler.java +++ b/src/main/java/com/dayrain/component/RequestHandler.java @@ -8,10 +8,15 @@ import java.io.IOException; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.util.UUID; - +/** + * 请求处理 + * @author peng + * @date 2021/11/8 + */ public class RequestHandler implements HttpHandler { private static final String STRING_PATTERN = "$string$"; + private static final String INT_PATTERN = "$int$"; private final ServerUrl serverUrl; @@ -21,7 +26,7 @@ public class RequestHandler implements HttpHandler { } @Override - public void handle(HttpExchange exchange) throws IOException { + public void handle(HttpExchange exchange) { RequestType requestType = serverUrl.getRequestType(); String param = null; if (RequestType.GET.equals(requestType)) { @@ -49,7 +54,8 @@ public class RequestHandler implements HttpHandler { private void response(HttpExchange exchange, String jsonBody) { try { - exchange.sendResponseHeaders(200, jsonBody.length()); + byte[] bytes = jsonBody.getBytes(StandardCharsets.UTF_8); + exchange.sendResponseHeaders(200, bytes.length); exchange.setAttribute("Content-Type", "application/json; charset=utf-8"); OutputStream outputStream = exchange.getResponseBody(); outputStream.write(jsonBody.getBytes(StandardCharsets.UTF_8)); diff --git a/src/main/java/com/dayrain/component/RequestType.java b/src/main/java/com/dayrain/component/RequestType.java new file mode 100644 index 0000000..f42cae0 --- /dev/null +++ b/src/main/java/com/dayrain/component/RequestType.java @@ -0,0 +1,9 @@ +package com.dayrain.component; +/** + * 请求方式 + * @author peng + * @date 2021/11/8 + */ +public enum RequestType { + GET, POST +} diff --git a/src/com/dayrain/component/Server.java b/src/main/java/com/dayrain/component/Server.java similarity index 60% rename from src/com/dayrain/component/Server.java rename to src/main/java/com/dayrain/component/Server.java index 621c92a..d3a27c5 100644 --- a/src/com/dayrain/component/Server.java +++ b/src/main/java/com/dayrain/component/Server.java @@ -1,19 +1,23 @@ package com.dayrain.component; import com.sun.net.httpserver.HttpServer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.InetSocketAddress; import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; /** * 服务 - * * @author peng * @date 2021/10/25 */ public class Server implements Runnable { + private static final Logger logger = LoggerFactory.getLogger(Server.class); + private final ServerConfig serverConfig; private HttpServer httpServer; @@ -25,6 +29,11 @@ public class Server implements Runnable { @Override public void run() { + start(); + System.out.println("【" + serverConfig.getServerName() + "】服务已开启..."); + } + + public synchronized void start() { try { this.httpServer = HttpServer.create(new InetSocketAddress(serverConfig.getPort()), 0); httpServer.setExecutor(Executors.newCachedThreadPool()); @@ -32,20 +41,36 @@ public class Server implements Runnable { addContext(serverUrl); } httpServer.start(); - System.out.println("【" + serverConfig.getServerName() + "】服务已开启..."); + } catch (IOException e) { e.printStackTrace(); + logger.error(e.getMessage()); } + } - public void stop() { + public synchronized void stop() { if (httpServer != null) { System.out.println("【" + serverConfig.getServerName() + "】服务已关闭..."); httpServer.stop(0); } } - public void addContext(ServerUrl serverUrl) { + public synchronized void restart() { + stop(); + try { + TimeUnit.SECONDS.sleep(2); + } catch (InterruptedException e) { + e.printStackTrace(); + } + start(); + } + + public synchronized void addContext(ServerUrl serverUrl) { httpServer.createContext(serverUrl.getUrl(), new RequestHandler(serverUrl)); } + + public void removeContext(String url) { + httpServer.removeContext(url); + } } diff --git a/src/com/dayrain/component/ServerConfig.java b/src/main/java/com/dayrain/component/ServerConfig.java similarity index 94% rename from src/com/dayrain/component/ServerConfig.java rename to src/main/java/com/dayrain/component/ServerConfig.java index 8cac664..ad12629 100644 --- a/src/com/dayrain/component/ServerConfig.java +++ b/src/main/java/com/dayrain/component/ServerConfig.java @@ -1,7 +1,11 @@ package com.dayrain.component; import java.util.List; - +/** + * 服务配置 + * @author peng + * @date 2021/11/8 + */ public class ServerConfig { /** * 服务名 @@ -48,4 +52,5 @@ public class ServerConfig { public void setServerUrls(List serverUrls) { this.serverUrls = serverUrls; } + } diff --git a/src/main/java/com/dayrain/component/ServerThreadHolder.java b/src/main/java/com/dayrain/component/ServerThreadHolder.java new file mode 100644 index 0000000..bd8f251 --- /dev/null +++ b/src/main/java/com/dayrain/component/ServerThreadHolder.java @@ -0,0 +1,68 @@ +package com.dayrain.component; + +import com.dayrain.server.ServerThread; + +import java.util.HashMap; + +/** + * 正在运行的 server 线程组 + * @author peng + * @date 2021/11/8 + */ +public class ServerThreadHolder { + + private static final HashMap threadMap = new HashMap<>(); + + /** + * 停止所有线程 + */ + public synchronized static void stopAll() { + if(threadMap.size() > 0) { + for (String serverName : threadMap.keySet()) { + ServerThread serverThread = threadMap.get(serverName); + serverThread.stopServer(); + } + } + } + + public synchronized static void add(String serverName, ServerThread serverThread) { + if(!threadMap.containsKey(serverName)) { + serverThread.start(); + threadMap.put(serverName, serverThread); + } + } + + public synchronized static void remove(String serverName) { + if(contains(serverName)) { + threadMap.get(serverName).stopServer(); + threadMap.remove(serverName); + } + } + + public synchronized static boolean contains(String key) { + return threadMap.containsKey(key); + } + + public synchronized static void addUrl(ServerUrl serverUrl) { + if(serverUrl == null || !contains(serverUrl.getServerName())) { + return; + } + + ServerThread serverThread = threadMap.get(serverUrl.getServerName()); + serverThread.addContext(serverUrl); + } + + public synchronized static void restart(String serverName) { + if(contains(serverName)) { + ServerThread serverThread = threadMap.get(serverName); + serverThread.restartServer(); + } + } + + public static void replaceUrl(String beforeName, String beforeUrl, ServerUrl serverUrl) { + if(contains(beforeName)) { + ServerThread serverThread = threadMap.get(beforeName); + serverThread.replaceUrl(beforeUrl, serverUrl); + } + } +} diff --git a/src/com/dayrain/component/ServerUrl.java b/src/main/java/com/dayrain/component/ServerUrl.java similarity index 96% rename from src/com/dayrain/component/ServerUrl.java rename to src/main/java/com/dayrain/component/ServerUrl.java index 49fbb6c..e1b3ac7 100644 --- a/src/com/dayrain/component/ServerUrl.java +++ b/src/main/java/com/dayrain/component/ServerUrl.java @@ -1,7 +1,11 @@ package com.dayrain.component; import java.util.Map; - +/** + * 请求路径 + * @author peng + * @date 2021/11/8 + */ public class ServerUrl { /** diff --git a/src/com/dayrain/server/ServerThread.java b/src/main/java/com/dayrain/server/ServerThread.java similarity index 60% rename from src/com/dayrain/server/ServerThread.java rename to src/main/java/com/dayrain/server/ServerThread.java index c75a853..66ac3a8 100644 --- a/src/com/dayrain/server/ServerThread.java +++ b/src/main/java/com/dayrain/server/ServerThread.java @@ -4,6 +4,7 @@ import com.dayrain.component.Server; import com.dayrain.component.ServerUrl; public class ServerThread extends Thread { + private final Server server; public ServerThread(Server server) { @@ -15,7 +16,20 @@ public class ServerThread extends Thread { server.stop(); } + public void restartServer() { + server.restart(); + } + public void addContext(ServerUrl serverUrl) { server.addContext(serverUrl); } + + public void removeContext(String url) { + server.removeContext(url); + } + + public void replaceUrl(String beforeUrl, ServerUrl serverUrl) { + removeContext(beforeUrl); + addContext(serverUrl); + } } diff --git a/src/main/java/com/dayrain/style/BackGroundFactory.java b/src/main/java/com/dayrain/style/BackGroundFactory.java new file mode 100644 index 0000000..6d2ef21 --- /dev/null +++ b/src/main/java/com/dayrain/style/BackGroundFactory.java @@ -0,0 +1,15 @@ +package com.dayrain.style; + +import javafx.geometry.Insets; +import javafx.scene.layout.Background; +import javafx.scene.layout.BackgroundFill; +import javafx.scene.layout.CornerRadii; +import javafx.scene.paint.Color; + +public class BackGroundFactory { + public static Background getBackGround() { + BackgroundFill backgroundFill = new BackgroundFill(Color.GRAY, new CornerRadii(1), + new Insets(0.0, 0.0, 0.0, 0.0)); + return new Background(backgroundFill); + } +} diff --git a/src/com/dayrain/style/ButtonFactory.java b/src/main/java/com/dayrain/style/ButtonFactory.java similarity index 100% rename from src/com/dayrain/style/ButtonFactory.java rename to src/main/java/com/dayrain/style/ButtonFactory.java diff --git a/src/main/java/com/dayrain/style/CircleFactory.java b/src/main/java/com/dayrain/style/CircleFactory.java new file mode 100644 index 0000000..54170f2 --- /dev/null +++ b/src/main/java/com/dayrain/style/CircleFactory.java @@ -0,0 +1,18 @@ +package com.dayrain.style; + +import javafx.scene.paint.Color; +import javafx.scene.shape.Circle; +/** + * 圆 + * @author peng + * @date 2021/11/11 + */ +public class CircleFactory { + + public static Circle getLightCircle(Color color) { + Circle circle = new Circle(); + circle.setRadius(10); + circle.setFill(color); + return circle; + } +} diff --git a/src/main/java/com/dayrain/style/FormFactory.java b/src/main/java/com/dayrain/style/FormFactory.java new file mode 100644 index 0000000..753b0e9 --- /dev/null +++ b/src/main/java/com/dayrain/style/FormFactory.java @@ -0,0 +1,30 @@ +package com.dayrain.style; + +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.Control; +import javafx.scene.control.Label; +import javafx.scene.layout.HBox; + +public class FormFactory { + + public static HBox getLine(Label label, Control control, double labelWidth, double nodeWidth, double maxWidth) { + HBox hBox = new HBox(); + label.setPrefWidth(labelWidth); + control.setPrefWidth(nodeWidth); + hBox.getChildren().addAll(label, control); + hBox.setAlignment(Pos.CENTER_LEFT); + hBox.setMaxWidth(maxWidth); + return hBox; + } + + public static HBox getButtonLine(Button button, double labelWidth, double width) { + HBox hBox = new HBox(); + Label label = LabelFactory.getLabel(""); + label.setPrefWidth(labelWidth); + hBox.getChildren().addAll(label, button); + hBox.setAlignment(Pos.CENTER_RIGHT); + hBox.setMaxWidth(width); + return hBox; + } +} diff --git a/src/main/java/com/dayrain/style/IconFactory.java b/src/main/java/com/dayrain/style/IconFactory.java new file mode 100644 index 0000000..11166cc --- /dev/null +++ b/src/main/java/com/dayrain/style/IconFactory.java @@ -0,0 +1,10 @@ +package com.dayrain.style; + +import javafx.scene.image.Image; + +public class IconFactory { + + public static Image getIcon() { + return new Image("panda.png"); + } +} diff --git a/src/com/dayrain/style/LabelFactory.java b/src/main/java/com/dayrain/style/LabelFactory.java similarity index 100% rename from src/com/dayrain/style/LabelFactory.java rename to src/main/java/com/dayrain/style/LabelFactory.java diff --git a/src/main/java/com/dayrain/style/StageFactory.java b/src/main/java/com/dayrain/style/StageFactory.java new file mode 100644 index 0000000..d31cdf8 --- /dev/null +++ b/src/main/java/com/dayrain/style/StageFactory.java @@ -0,0 +1,30 @@ +package com.dayrain.style; + +import com.dayrain.views.ViewHolder; +import javafx.scene.Scene; +import javafx.stage.Modality; +import javafx.stage.Stage; +/** + * 窗口 + * @author peng + * @date 2021/11/11 + */ +public class StageFactory { + + /** + * 获取标准弹窗 + * @author peng + * @date 2021/11/11 + */ + public static Stage getPopStage(String name, Scene scene) { + Stage stage = new Stage(); + stage.setTitle(name); + stage.setWidth(700); + stage.setHeight(500); + stage.initOwner(ViewHolder.getPrimaryStage()); + stage.initModality(Modality.WINDOW_MODAL); + stage.getIcons().addAll(IconFactory.getIcon()); + stage.setScene(scene); + return stage; + } +} diff --git a/src/com/dayrain/utils/FileUtils.java b/src/main/java/com/dayrain/utils/FileUtils.java similarity index 97% rename from src/com/dayrain/utils/FileUtils.java rename to src/main/java/com/dayrain/utils/FileUtils.java index ae92a58..64768b0 100644 --- a/src/com/dayrain/utils/FileUtils.java +++ b/src/main/java/com/dayrain/utils/FileUtils.java @@ -56,7 +56,7 @@ public class FileUtils { while ((buf = bufferedReader.readLine()) != null) { configStr.append(buf); } - return "".equals(configStr.toString()) ? new Configuration(1200, 800, 8, 8) : new ObjectMapper().readValue(configStr.toString(), Configuration.class); + return "".equals(configStr.toString()) ? new Configuration(1400, 800, 8, 8) : new ObjectMapper().readValue(configStr.toString(), Configuration.class); } catch (IOException e) { e.printStackTrace(); } finally { @@ -75,7 +75,7 @@ public class FileUtils { public static String getFromInputStream(InputStream inputStream) { try { byte[] buf = new byte[4096]; - int len = 0; + int len; StringBuilder stringBuilder = new StringBuilder(); while ((len = inputStream.read(buf)) != -1) { stringBuilder.append(new String(buf, 0, len)); diff --git a/src/com/dayrain/utils/ListViewHelper.java b/src/main/java/com/dayrain/utils/ListViewHelper.java similarity index 100% rename from src/com/dayrain/utils/ListViewHelper.java rename to src/main/java/com/dayrain/utils/ListViewHelper.java diff --git a/src/main/java/com/dayrain/views/ApplicationStarter.java b/src/main/java/com/dayrain/views/ApplicationStarter.java new file mode 100644 index 0000000..cbb4eb1 --- /dev/null +++ b/src/main/java/com/dayrain/views/ApplicationStarter.java @@ -0,0 +1,32 @@ +package com.dayrain.views; + +import com.dayrain.component.ConfigHolder; +import javafx.application.Application; +import javafx.stage.Stage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +/** + * 启动入口 + * @author peng + * @date 2021/11/11 + */ +public class ApplicationStarter extends Application { + + private static final Logger logger = LoggerFactory.getLogger(ApplicationStarter.class); + + public static void main(String[] args) { + launch(args); + } + + @Override + public void start(Stage primaryStage) { + try { + ConfigHolder.init(); + ViewHolder.setPrimaryStage(primaryStage); + new HomeView().start(); + }catch (Exception e) { + e.printStackTrace(); + logger.error(e.getMessage()); + } + } +} diff --git a/src/main/java/com/dayrain/views/HomeView.java b/src/main/java/com/dayrain/views/HomeView.java new file mode 100644 index 0000000..25ec748 --- /dev/null +++ b/src/main/java/com/dayrain/views/HomeView.java @@ -0,0 +1,85 @@ +package com.dayrain.views; + +import com.dayrain.component.ConfigHolder; +import com.dayrain.component.ConsoleLog; +import com.dayrain.component.ServerConfig; +import com.dayrain.component.ServerThreadHolder; +import com.dayrain.style.IconFactory; +import javafx.application.Platform; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.scene.Scene; +import javafx.scene.control.SplitPane; +import javafx.scene.layout.VBox; +import javafx.stage.Stage; +import java.util.ArrayList; +import java.util.List; +/** + * 主页 + * @author peng + * @date 2021/11/11 + */ +public class HomeView { + + private final Stage primaryStage; + + public HomeView() { + this.primaryStage = ViewHolder.getPrimaryStage(); + } + /** + * 启动程序 + */ + public void start() { + VBox vBox = new VBox(); + + //菜单栏 + MenuBarView menuBar = new MenuBarView(); + SplitPane splitPane = new SplitPane(); + //日志 + LogArea logArea = new LogArea(); + ConsoleLog.initTextArea(logArea); + ViewHolder.setLogArea(logArea); + + //server + ServerContainer serverContainer = initServer(); + ViewHolder.setServerContainer(serverContainer); + splitPane.getItems().addAll(serverContainer, logArea); + splitPane.setDividerPositions(0.55f, 0.45f); + vBox.getChildren().addAll(menuBar, splitPane); + + primaryStage.setTitle(ConfigHolder.get().getProjectName()); + primaryStage.setScene(new Scene(vBox)); + primaryStage.setWidth(ConfigHolder.get().getWidth()); + primaryStage.setHeight(ConfigHolder.get().getHeight()); + primaryStage.getIcons().add(IconFactory.getIcon()); + + primaryStage.show(); + primaryStage.setOnCloseRequest(event -> { + ConfigHolder.save(); + ServerThreadHolder.stopAll(); + Platform.exit(); + }); + } + + /** + * 初始化服务列表 + * @return 服务的容器 + */ + private ServerContainer initServer() { + List serverConfigs = ConfigHolder.get().getServerConfigs(); + ListserverPanes = new ArrayList<>(); + if(serverConfigs != null) { + for (ServerConfig serverConfig : serverConfigs) { + ServerPane serverPane = new ServerPane(serverConfig); + serverPanes.add(serverPane); + } + } + return new ServerContainer(serverPanes); + } + + public void restart() { + //停止所有线程 + ServerThreadHolder.stopAll(); + start(); + } +} diff --git a/src/main/java/com/dayrain/views/LogArea.java b/src/main/java/com/dayrain/views/LogArea.java new file mode 100644 index 0000000..1087bb8 --- /dev/null +++ b/src/main/java/com/dayrain/views/LogArea.java @@ -0,0 +1,34 @@ +package com.dayrain.views; + +import com.dayrain.component.ConfigHolder; +import javafx.scene.control.TextArea; +import javafx.scene.text.Font; + +/** + * 打印日志的组件 + * 每个服务都有各自的组件 + * @author peng + * @date 2021/11/8 + */ +public class LogArea extends TextArea { + private String serverName; + + public LogArea() { + createView(); + } + + public void createView() { + this.setEditable(false); + this.setFont(Font.font("Microsoft YaHei", 16)); + this.setPrefWidth(582); + this.setPrefHeight(ConfigHolder.get().getHeight()); + } + + public String getServerName() { + return serverName; + } + + public void setServerName(String serverName) { + this.serverName = serverName; + } +} diff --git a/src/main/java/com/dayrain/views/MenuBarView.java b/src/main/java/com/dayrain/views/MenuBarView.java new file mode 100644 index 0000000..20e616a --- /dev/null +++ b/src/main/java/com/dayrain/views/MenuBarView.java @@ -0,0 +1,210 @@ +package com.dayrain.views; + +import com.dayrain.component.ConfigHolder; +import com.dayrain.component.Configuration; +import com.dayrain.component.ServerConfig; +import com.dayrain.style.BackGroundFactory; +import com.dayrain.style.ButtonFactory; +import com.dayrain.style.LabelFactory; +import com.dayrain.style.StageFactory; +import com.dayrain.utils.FileUtils; +import javafx.event.ActionEvent; +import javafx.geometry.Pos; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.Menu; +import javafx.scene.control.MenuBar; +import javafx.scene.control.MenuItem; +import javafx.scene.control.TextField; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.stage.FileChooser; +import javafx.stage.Stage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.awt.Desktop; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; + +/** + * 菜单栏 + * @author peng + * @date 2021/11/11 + */ +public class MenuBarView extends MenuBar { + + private static final Logger logger = LoggerFactory.getLogger(MenuBarView.class); + + private final Menu menu1 = new Menu("文件"); + private final Menu menu2 = new Menu("设置"); + private final Menu menu3 = new Menu("帮助"); + + public MenuBarView() { + creatView(); + } + + private void creatView() { + MenuItem menuItem11 = new MenuItem("新建"); + MenuItem menuItem12 = new MenuItem("导入"); + MenuItem menuItem13 = new MenuItem("导出"); + menu1.getItems().addAll(menuItem11, menuItem12, menuItem13); + menuItem11.setOnAction(this::addServer); + menuItem12.setOnAction(this::importConfig); + menuItem13.setOnAction(this::exportConfig); + + MenuItem menuItem21 = new MenuItem("随机值长度"); + menu2.getItems().addAll(menuItem21); + menuItem21.setOnAction(this::updateRandomLength); + + MenuItem menuItem31 = new MenuItem("说明书"); + MenuItem menuItem32 = new MenuItem("源码地址"); + menu3.getItems().addAll(menuItem31, menuItem32); + menuItem31.setOnAction(this::linkIntroduce); + menuItem32.setOnAction(this::linkGithub); + + this.setBackground(BackGroundFactory.getBackGround()); + + this.getMenus().addAll(menu1, menu2, menu3); + } + + public void updateRandomLength(ActionEvent evt) { + Configuration configuration = ConfigHolder.get(); + Label strName = LabelFactory.getLabel("随机字符长度:"); + strName.setPrefWidth(150); + TextField strField = new TextField(String.valueOf(configuration.getStringLen())); + Label intName = LabelFactory.getLabel("随机整数长度:"); + javafx.scene.control.TextField intField = new TextField(String.valueOf(configuration.getIntLen())); + intField.setPrefWidth(150); + + HBox btnHBox = new HBox(); + Label saveTips1 = LabelFactory.getLabel("注: $string$代指随机字符串"); + Label saveTips2 = LabelFactory.getLabel("$int$代指随机整数"); + Button saveButton = ButtonFactory.getButton("保存"); + btnHBox.getChildren().addAll(saveButton); + btnHBox.setAlignment(Pos.CENTER_RIGHT); + btnHBox.setSpacing(20d); + + GridPane gridPane = new GridPane(); + gridPane.add(strName, 0, 0); + gridPane.add(strField, 1, 0); + gridPane.add(intName, 0, 1); + gridPane.add(intField, 1, 1); + gridPane.add(saveTips1, 0, 3); + gridPane.add(saveTips2, 1, 3); + + gridPane.add(btnHBox, 1, 4); + gridPane.setAlignment(Pos.CENTER); + gridPane.setHgap(20d); + gridPane.setVgap(10d); + + Stage stage = StageFactory.getPopStage("更改随机值配置", new Scene(gridPane)); + stage.show(); + + saveButton.setOnAction(event -> { + String strLen = strField.getText(); + String intLen = intField.getText(); + configuration.setStringLen(Integer.parseInt(strLen)); + configuration.setIntLen(Integer.parseInt(intLen)); + ConfigHolder.save(); + stage.close(); + }); + } + + public void exportConfig(ActionEvent evt) { + Stage stage = new Stage(); + stage.initOwner(ViewHolder.getPrimaryStage()); + FileChooser fileChooser = new FileChooser(); + String projectName = ConfigHolder.get().getProjectName(); + if (projectName == null) { + projectName = ""; + } + projectName += "server"; + fileChooser.setTitle("导出配置"); + fileChooser.setInitialFileName(projectName + ".json"); + File file = fileChooser.showSaveDialog(stage); + if (file != null) { + FileUtils.saveConfig(ConfigHolder.get(), file); + } + } + + private void importConfig(ActionEvent evt) { + Stage stage = new Stage(); + stage.initOwner(ViewHolder.getPrimaryStage()); + FileChooser fileChooser = new FileChooser(); + fileChooser.setTitle("选择一个文件"); + //过滤器 + fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("只能导入json文件", "*.json")); + File file = fileChooser.showOpenDialog(stage); + + if (file != null) { + Configuration loadConfig = FileUtils.load(file); + ConfigHolder.replace(loadConfig); + FileUtils.saveConfig(loadConfig); + ConfigHolder.replace(loadConfig); + ViewHolder.getHomeView().restart(); + } + } + + /** + * 添加服务 + */ + private void addServer(ActionEvent evt) { + Label nameLabel = LabelFactory.getLabel("服务名称:"); + nameLabel.setPrefWidth(80); + javafx.scene.control.TextField nameField = new javafx.scene.control.TextField(); + javafx.scene.control.Label portLabel = LabelFactory.getLabel("端口号:"); + javafx.scene.control.TextField portField = new javafx.scene.control.TextField(); + portField.setPrefWidth(80); + + HBox btnHBox = new HBox(); + Button saveButton = ButtonFactory.getButton("保存"); + btnHBox.getChildren().add(saveButton); + btnHBox.setAlignment(Pos.CENTER_RIGHT); + + GridPane gridPane = new GridPane(); + gridPane.add(nameLabel, 0, 0); + gridPane.add(nameField, 1, 0); + gridPane.add(portLabel, 0, 1); + gridPane.add(portField, 1, 1); + gridPane.add(btnHBox, 1, 3); + gridPane.setAlignment(Pos.CENTER); + gridPane.setHgap(20d); + gridPane.setVgap(10d); + + Stage stage = StageFactory.getPopStage("添加服务", new Scene(gridPane)); + stage.show(); + + saveButton.setOnAction(event -> { + String name = nameField.getText(); + String port = portField.getText(); + ServerConfig serverConfig = new ServerConfig(name, Integer.parseInt(port), new ArrayList<>()); + ConfigHolder.get().getServerConfigs().add(serverConfig); + ViewHolder.getServerContainer().refresh(); + ConfigHolder.save(); + stage.close(); + }); + } + + private void linkGithub(ActionEvent evt) { + try { + Desktop.getDesktop().browse(new URI("https://github.com/DayRain/http-server-simulator")); + } catch (IOException | URISyntaxException e) { + logger.error("跳转到github时发生了错误: {}", e.getMessage()); + e.printStackTrace(); + } + } + + private void linkIntroduce(ActionEvent evt){ + try { + Desktop.getDesktop().browse(new URI("https://blog.csdn.net/qq_37855749/article/details/121030800")); + } catch (IOException | URISyntaxException e) { + logger.error("跳转到csdn时发生了错误: {}", e.getMessage()); + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/dayrain/views/ServerContainer.java b/src/main/java/com/dayrain/views/ServerContainer.java new file mode 100644 index 0000000..07d2bf6 --- /dev/null +++ b/src/main/java/com/dayrain/views/ServerContainer.java @@ -0,0 +1,28 @@ +package com.dayrain.views; + +import javafx.scene.layout.VBox; + +import java.util.List; +/** + * server容器 + * @author peng + * @date 2021/11/11 + */ +public class ServerContainer extends VBox { + + private List serverPanes; + + public ServerContainer(List serverPanes) { + this.serverPanes = serverPanes; + createView(); + } + + public void createView() { + getChildren().addAll(serverPanes); + } + + public void refresh() { + getChildren().removeAll(); + getChildren().addAll(serverPanes); + } +} diff --git a/src/main/java/com/dayrain/views/ServerPane.java b/src/main/java/com/dayrain/views/ServerPane.java new file mode 100644 index 0000000..abe0876 --- /dev/null +++ b/src/main/java/com/dayrain/views/ServerPane.java @@ -0,0 +1,239 @@ +package com.dayrain.views; + +import com.dayrain.component.ConfigHolder; +import com.dayrain.component.ConsoleLog; +import com.dayrain.component.RequestType; +import com.dayrain.component.Server; +import com.dayrain.component.ServerConfig; + +import com.dayrain.component.ServerThreadHolder; +import com.dayrain.component.ServerUrl; +import com.dayrain.server.ServerThread; +import com.dayrain.style.BackGroundFactory; +import com.dayrain.style.ButtonFactory; + +import com.dayrain.style.CircleFactory; +import com.dayrain.style.FormFactory; +import com.dayrain.style.IconFactory; +import com.dayrain.style.LabelFactory; +import com.dayrain.style.StageFactory; +import com.dayrain.utils.ListViewHelper; + +import javafx.collections.FXCollections; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; +import javafx.scene.control.ChoiceBox; +import javafx.scene.control.Label; +import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; +import javafx.scene.control.TitledPane; +import javafx.scene.image.ImageView; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; +import javafx.scene.paint.Color; +import javafx.scene.shape.Circle; +import javafx.scene.text.Font; +import javafx.stage.Modality; +import javafx.stage.Stage; + +import java.util.List; + +/** + * server容器 + * @author peng + * @date 2021/11/11 + */ +public class ServerPane extends TitledPane { + + private final ServerConfig serverConfig; + + private ServerUrlListView serverUrlListView; + + private final Circle statusCircle; + private final Button editButton; + private final Button openButton; + private final Button deleteButton; + private final Button addButton; + + public ServerPane(ServerConfig serverConfig) { + this.serverConfig = serverConfig; + this.statusCircle = CircleFactory.getLightCircle(ServerThreadHolder.contains(serverConfig.getServerName()) ? Color.GREEN : Color.RED); + this.editButton = ButtonFactory.getButton("修改配置"); + this.openButton = ButtonFactory.getButton("开启服务"); + this.deleteButton = ButtonFactory.getButton("删除服务"); + this.addButton = ButtonFactory.getButton("添加接口"); + createView(); + } + + public void createView() { + VBox vBox = new VBox(); + HBox headBox = new HBox(); + //设置服务启动与关闭 + openButton.setOnAction(this::startServer); + editButton.setOnAction(this::updateServer); + deleteButton.setOnAction(this::deleteSever); + headBox.getChildren().addAll(openButton, editButton, deleteButton, addButton, statusCircle); + HBox.setMargin(statusCircle, new Insets(0, 0, 0, 30)); + headBox.setSpacing(20d); + headBox.setAlignment(Pos.CENTER); + + //添加url + this.serverUrlListView = new ServerUrlListView(serverConfig); + addButton.setOnAction(this::addUrl); + vBox.getChildren().addAll(headBox, serverUrlListView); + + vBox.setSpacing(10d); + VBox.setMargin(headBox, new Insets(10, 0, 0, 0)); + vBox.setPadding(Insets.EMPTY); + setText(serverConfig.getServerName()); + this.setContent(vBox); + this.setFont(Font.font("Microsoft YaHei", 18)); + this.setPrefWidth(600d); + this.setExpanded(false); + this.setBackground(BackGroundFactory.getBackGround()); + this.setOnMouseClicked(event -> { + if (!serverConfig.getServerName().equals(ViewHolder.getLogArea().getServerName())) { + ConsoleLog.resetTextArea(serverConfig.getServerName()); + } + }); + + HBox hBox = new HBox(); + hBox.setPrefHeight(60d); + this.setGraphic(hBox); + } + + /** + * 启动服务 + */ + private void startServer(ActionEvent evt) { + String serverName = serverConfig.getServerName(); + if (ServerThreadHolder.contains(serverName)) { + ServerThreadHolder.remove(serverName); + openButton.setText("开启服务"); + statusCircle.setFill(Color.RED); + } else { + ServerThreadHolder.add(serverName, new ServerThread(new Server(serverConfig))); + openButton.setText("关闭服务"); + statusCircle.setFill(Color.GREEN); + } + } + + /** + * 更新服务 + */ + private void updateServer(ActionEvent evt) { + Label serverName = LabelFactory.getLabel("服务名称:"); + serverName.setPrefWidth(80); + TextField nameField = new TextField(serverConfig.getServerName()); + Label portLabel = LabelFactory.getLabel("端口:"); + TextField portField = new TextField(String.valueOf(serverConfig.getPort())); + portField.setPrefWidth(80); + + HBox btnHBox = new HBox(); + Label saveTips = LabelFactory.getLabel("重启后生效"); + Button saveButton = ButtonFactory.getButton("保存"); + btnHBox.getChildren().addAll(saveTips, saveButton); + btnHBox.setAlignment(Pos.CENTER_RIGHT); + btnHBox.setSpacing(20d); + + GridPane gridPane = new GridPane(); + gridPane.add(serverName, 0, 0); + gridPane.add(nameField, 1, 0); + gridPane.add(portLabel, 0, 1); + gridPane.add(portField, 1, 1); + + gridPane.add(btnHBox, 1, 3); + gridPane.setAlignment(Pos.CENTER); + gridPane.setHgap(20d); + gridPane.setVgap(10d); + + Stage stage = StageFactory.getPopStage("更新服务配置", new Scene(gridPane)); + stage.show(); + + saveButton.setOnAction(event -> { + String name = nameField.getText(); + int port = Integer.parseInt(portField.getText()); + serverConfig.setPort(port); + serverConfig.setServerName(name); + ConfigHolder.save(); + stage.close(); + }); + } + + /** + * 删除服务 + */ + private void deleteSever(ActionEvent evt) { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + alert.setGraphic(new ImageView(IconFactory.getIcon())); + Stage stage = (Stage) alert.getDialogPane().getScene().getWindow(); + stage.getIcons().add(IconFactory.getIcon()); + alert.setHeaderText("是否确定删除该服务?"); + Button okButton = (Button) alert.getDialogPane().lookupButton(ButtonType.OK); + okButton.setOnAction(event1 -> { + ConfigHolder.get().getServerConfigs().remove(serverConfig); + ViewHolder.getServerContainer().refresh(); + ConfigHolder.save(); + }); + alert.show(); + } + + private void addUrl(ActionEvent evt) { + VBox vBox = new VBox(); + + Label nameLabel = LabelFactory.getLabel("接口名称:"); + TextField nameField = new TextField(); + HBox hBox1 = FormFactory.getLine(nameLabel, nameField, 120, 300, 500); + + Label urlLabel = LabelFactory.getLabel("接口地址:"); + TextField urlField = new TextField(); + HBox hBox2 = FormFactory.getLine(urlLabel, urlField, 120, 300, 500); + + Label typeLabel = LabelFactory.getLabel("请求方式:"); + ChoiceBox choiceBox = new ChoiceBox<>(); + choiceBox.setItems(FXCollections.observableArrayList("POST", "GET")); + choiceBox.setValue("POST"); + HBox hBox3 = FormFactory.getLine(typeLabel, choiceBox, 120, 70, 500); + + Label respLabel = LabelFactory.getLabel("返回结果:"); + TextArea textArea = new TextArea(); + HBox hBox4 = FormFactory.getLine(respLabel, textArea, 120, 300, 500); + + Button saveButton = ButtonFactory.getButton("保存"); + HBox hBox5 = FormFactory.getButtonLine(saveButton, 120, 500); + + vBox.getChildren().addAll(hBox1, hBox2, hBox3, hBox4, hBox5); + vBox.setSpacing(20d); + vBox.setAlignment(Pos.CENTER); + + Stage stage = StageFactory.getPopStage("新增接口信息", new Scene(vBox)); + stage.show(); + + saveButton.setOnAction(event1 -> { + String name = nameField.getText(); + List serverUrls = serverConfig.getServerUrls(); + for (ServerUrl serverUrl : serverUrls) { + if (serverUrl.getUrlName().equals(name)) { + return; + } + } + String url = urlField.getText(); + String resp = textArea.getText(); + + String type = choiceBox.getValue(); + ServerUrl serverUrl = new ServerUrl(serverConfig.getServerName(), name, url, type.equals(RequestType.POST.name()) ? RequestType.POST : RequestType.GET, resp); + serverUrls.add(serverUrl); + ServerThreadHolder.addUrl(serverUrl); + ListViewHelper.addAndRefresh(serverUrl, serverUrlListView); + ConfigHolder.save(); + stage.close(); + }); + } +} diff --git a/src/main/java/com/dayrain/views/ServerUrlListView.java b/src/main/java/com/dayrain/views/ServerUrlListView.java new file mode 100644 index 0000000..17810e7 --- /dev/null +++ b/src/main/java/com/dayrain/views/ServerUrlListView.java @@ -0,0 +1,54 @@ +package com.dayrain.views; + +import com.dayrain.component.ServerConfig; +import com.dayrain.component.ServerUrl; +import javafx.beans.binding.Bindings; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.stage.Stage; +import javafx.util.Callback; + +/** + * server 列表 + * @author peng + * @date 2021/11/11 + */ +public class ServerUrlListView extends ListView { + + private ServerConfig serverConfig; + + public ServerUrlListView(ServerConfig serverConfig) { + this.serverConfig = serverConfig; + createView(); + } + + private void createView() { + ObservableList urlList = FXCollections.observableArrayList(serverConfig.getServerUrls()); + setItems(urlList); + this.setCellFactory(new Callback, ListCell>() { + @Override + public ListCell call(ListView param) { + return new ListCell() { + @Override + protected void updateItem(ServerUrl item, boolean empty) { + super.updateItem(item, empty); + + if (empty || item == null) { + setText(null); + setGraphic(null); + } else { + ServerUrlPaneView urlPane = new ServerUrlPaneView(item, serverConfig, ServerUrlListView.this); + this.setGraphic(urlPane); + } + } + }; + } + }); + + this.prefHeightProperty().bind(Bindings.size(urlList).multiply(60)); + this.setFocusTraversable(false); + } + +} diff --git a/src/main/java/com/dayrain/views/ServerUrlPaneView.java b/src/main/java/com/dayrain/views/ServerUrlPaneView.java new file mode 100644 index 0000000..28b48e3 --- /dev/null +++ b/src/main/java/com/dayrain/views/ServerUrlPaneView.java @@ -0,0 +1,156 @@ +package com.dayrain.views; + +import com.dayrain.component.ConfigHolder; +import com.dayrain.component.RequestType; +import com.dayrain.component.ServerConfig; +import com.dayrain.component.ServerThreadHolder; +import com.dayrain.component.ServerUrl; +import com.dayrain.style.ButtonFactory; +import com.dayrain.style.FormFactory; +import com.dayrain.style.IconFactory; +import com.dayrain.style.LabelFactory; +import com.dayrain.style.StageFactory; +import com.dayrain.utils.ListViewHelper; +import javafx.collections.FXCollections; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.geometry.Insets; +import javafx.geometry.Pos; +import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.ButtonType; +import javafx.scene.control.ChoiceBox; +import javafx.scene.control.Label; +import javafx.scene.control.ListView; +import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; +import javafx.scene.image.ImageView; +import javafx.scene.layout.BorderPane; +import javafx.scene.layout.HBox; +import javafx.scene.layout.VBox; +import javafx.stage.Stage; + +import java.util.List; + +/** + * url面板 + * @author peng + * @date 2021/11/11 + */ +public class ServerUrlPaneView extends BorderPane { + private final ServerUrl serverUrl; + private final ServerConfig serverConfig; + private final ListView serverListViews; + + public ServerUrlPaneView(ServerUrl serverUrl, ServerConfig serverConfig, ListView serverListViews) { + this.serverUrl = serverUrl; + this.serverConfig = serverConfig; + this.serverListViews = serverListViews; + createView(); + } + + public void createView() { + HBox labelBox = new HBox(); + Label nameLabel = LabelFactory.getLabel(serverUrl.getUrlName()); + nameLabel.setPrefWidth(180d); + nameLabel.setMaxWidth(180d); + + + Label typeLabel = LabelFactory.getLabel(serverUrl.getRequestType().name()); + typeLabel.setPrefWidth(65d); + + Label urlLabel = LabelFactory.getLabel(serverUrl.getUrl()); + urlLabel.setMaxWidth(220d); + labelBox.getChildren().addAll(nameLabel, typeLabel, urlLabel); + labelBox.setAlignment(Pos.CENTER_LEFT); + + HBox btnBox = new HBox(); + Button configButton = ButtonFactory.getButton("配置"); + Button deleteButton = ButtonFactory.getButton("删除"); + btnBox.setSpacing(10d); + btnBox.getChildren().addAll(configButton, deleteButton); + HBox.setMargin(deleteButton, new Insets(0, 5, 0, 0)); + + deleteButton.setOnAction(this::deleteUrl); + configButton.setOnAction(this::updateUrl); + + this.setLeft(labelBox); + this.setRight(btnBox); + } + + + private void deleteUrl(ActionEvent event) { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + alert.setGraphic(new ImageView(IconFactory.getIcon())); + Stage stage = (Stage) alert.getDialogPane().getScene().getWindow(); + stage.getIcons().add(IconFactory.getIcon()); + alert.setHeaderText("是否确定删除该接口?"); + Button okButton = (Button) alert.getDialogPane().lookupButton(ButtonType.OK); + okButton.setOnAction(event1 -> { + List serverUrls = serverConfig.getServerUrls(); + serverUrls.remove(serverUrl); + ConfigHolder.save(); + ListViewHelper.deleteAndRefresh(serverUrl, serverListViews); + }); + alert.show(); + } + + private void updateUrl(ActionEvent event) { + VBox vBox = new VBox(); + + Label nameLabel = LabelFactory.getLabel("接口名称:"); + TextField nameField = new TextField(serverUrl.getUrlName()); + HBox hBox1 = FormFactory.getLine(nameLabel, nameField, 120, 300, 500); + + Label urlLabel = LabelFactory.getLabel("接口地址:"); + TextField urlField = new TextField(serverUrl.getUrl()); + HBox hBox2 = FormFactory.getLine(urlLabel, urlField, 120, 300, 500); + + Label typeLabel = LabelFactory.getLabel("请求方式:"); + ChoiceBox choiceBox = new ChoiceBox<>(); + choiceBox.setItems(FXCollections.observableArrayList("POST", "GET")); + choiceBox.setValue(serverUrl.getRequestType().name()); + HBox hBox3 = FormFactory.getLine(typeLabel, choiceBox, 120, 70, 500); + + Label respLabel = LabelFactory.getLabel("返回结果:"); + TextArea textArea = new TextArea(serverUrl.getResponseBody()); + HBox hBox4 = FormFactory.getLine(respLabel, textArea, 120, 300, 500); + + Button saveButton = ButtonFactory.getButton("保存"); + HBox hBox5 = FormFactory.getButtonLine(saveButton, 120, 500); + + vBox.getChildren().addAll(hBox1, hBox2, hBox3, hBox4, hBox5); + vBox.setSpacing(20d); + vBox.setAlignment(Pos.CENTER); + + Stage stage = StageFactory.getPopStage("更新接口信息", new Scene(vBox)); + stage.show(); + + + saveButton.setOnAction(event1 -> { + String name = nameField.getText(); + String url = urlField.getText(); + String resp = textArea.getText(); + String type = choiceBox.getValue(); + if(url == null) { + return; + } + + if(!url.startsWith("/")) { + url = "/" + url; + } + String beforeUrl = serverUrl.getUrl(); + serverUrl.setUrlName(name); + serverUrl.setUrl(url); + serverUrl.setResponseBody(resp); + serverUrl.setRequestType(type.equals(RequestType.POST.name()) ? RequestType.POST : RequestType.GET); + ListViewHelper.refresh(serverListViews); + ConfigHolder.save(); + + ServerThreadHolder.replaceUrl(serverUrl.getServerName(), beforeUrl, serverUrl); + stage.close(); + }); + } + +} diff --git a/src/main/java/com/dayrain/views/ViewHolder.java b/src/main/java/com/dayrain/views/ViewHolder.java new file mode 100644 index 0000000..b8d7b55 --- /dev/null +++ b/src/main/java/com/dayrain/views/ViewHolder.java @@ -0,0 +1,50 @@ +package com.dayrain.views; + +import javafx.stage.Stage; +/** + * 主要视图的句柄 + * @author peng + * @date 2021/11/11 + */ +public class ViewHolder { + + private static Stage primaryStage; + + private static LogArea logArea; + + private static ServerContainer serverContainer; + + private static HomeView homeView; + + static void setPrimaryStage(Stage primaryStage) { + ViewHolder.primaryStage = primaryStage; + } + + public static Stage getPrimaryStage() { + return primaryStage; + } + + static void setLogArea(LogArea logArea) { + ViewHolder.logArea = logArea; + } + + public static LogArea getLogArea() { + return logArea; + } + + public static ServerContainer getServerContainer() { + return serverContainer; + } + + static void setServerContainer(ServerContainer serverContainer) { + ViewHolder.serverContainer = serverContainer; + } + + static void setHomePage(HomeView homeView) { + ViewHolder.homeView = homeView; + } + + public static HomeView getHomeView() { + return ViewHolder.homeView; + } +} diff --git a/src/resources/close.png b/src/main/resources/close.png similarity index 100% rename from src/resources/close.png rename to src/main/resources/close.png diff --git a/src/resources/config.json b/src/main/resources/config.json similarity index 100% rename from src/resources/config.json rename to src/main/resources/config.json diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..d135fa5 --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,33 @@ + + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + + + + + ${LOG_HOME}/error.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + + + ERROR + ACCEPT + DENY + + + + + + + + \ No newline at end of file diff --git a/src/resources/min.png b/src/main/resources/min.png similarity index 100% rename from src/resources/min.png rename to src/main/resources/min.png diff --git a/src/resources/panda.png b/src/main/resources/panda.png similarity index 100% rename from src/resources/panda.png rename to src/main/resources/panda.png