Added application state saving

This commit is contained in:
Rohit Awate 2018-02-15 00:05:30 +05:30
parent 81710e9d15
commit b3ffa5ecd4
11 changed files with 168 additions and 21 deletions

1
.gitignore vendored
View file

@ -7,3 +7,4 @@ src/main/java/META-INF/
dependency-reduced-pom.xml
history.sqlite
themes/
/config/restaurant.state

View file

@ -17,7 +17,6 @@
package com.rohitawate.restaurant.homewindow;
import com.rohitawate.restaurant.models.requests.DataDispatchRequest;
import com.rohitawate.restaurant.models.requests.RestaurantRequest;
import com.rohitawate.restaurant.util.themes.ThemeManager;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
@ -76,7 +75,7 @@ public class BodyTabController implements Initializable {
/**
* Returns a RestaurantRequest object initialized with the request body.
*/
public RestaurantRequest getBasicRequest(String requestType) {
public DataDispatchRequest getBasicRequest(String requestType) {
DataDispatchRequest request = new DataDispatchRequest(requestType);
if (rawTab.isSelected()) {

View file

@ -21,6 +21,7 @@ import com.rohitawate.restaurant.exceptions.UnreliableResponseException;
import com.rohitawate.restaurant.models.requests.DELETERequest;
import com.rohitawate.restaurant.models.requests.DataDispatchRequest;
import com.rohitawate.restaurant.models.requests.GETRequest;
import com.rohitawate.restaurant.models.requests.RestaurantRequest;
import com.rohitawate.restaurant.models.responses.RestaurantResponse;
import com.rohitawate.restaurant.requestsmanager.DELETERequestManager;
import com.rohitawate.restaurant.requestsmanager.DataDispatchRequestManager;
@ -47,6 +48,7 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
public class DashboardController implements Initializable {
@ -81,7 +83,7 @@ public class DashboardController implements Initializable {
@Override
public void initialize(URL url, ResourceBundle rb) {
applySettings();
applyDashboardSettings();
try {
// Loading the headers tab
@ -110,7 +112,7 @@ public class DashboardController implements Initializable {
paramsControllers = new ArrayList<>();
appendedParams = new ArrayList<>();
addParam(); // Adds a blank param field
addParamField(); // Adds a blank param field
snackBar = new JFXSnackbar(dashboard);
bodyTab.disableProperty().bind(Bindings.and(httpMethodBox.valueProperty().isNotEqualTo("POST"),
@ -121,7 +123,7 @@ public class DashboardController implements Initializable {
}
@FXML
private void sendAction() {
private void sendRequest() {
promptLayer.setVisible(false);
if (responseBox.getChildren().size() == 2) {
responseBox.getChildren().remove(0);
@ -148,7 +150,7 @@ public class DashboardController implements Initializable {
}
GETRequest getRequest = new GETRequest(addressField.getText());
getRequest.addHeaders(headerTabController.getHeaders());
getRequest.setHeaders(headerTabController.getHeaders());
requestManager.setRequest(getRequest);
cancelButton.setOnAction(e -> requestManager.cancel());
requestManager.setOnRunning(e -> {
@ -200,7 +202,7 @@ public class DashboardController implements Initializable {
DataDispatchRequest dataDispatchRequest =
(DataDispatchRequest) bodyTabController.getBasicRequest(httpMethodBox.getValue());
dataDispatchRequest.setTarget(addressField.getText());
dataDispatchRequest.addHeaders(headerTabController.getHeaders());
dataDispatchRequest.setHeaders(headerTabController.getHeaders());
requestManager.setRequest(dataDispatchRequest);
cancelButton.setOnAction(e -> requestManager.cancel());
@ -250,7 +252,7 @@ public class DashboardController implements Initializable {
}
DELETERequest deleteRequest = new DELETERequest(addressField.getText());
deleteRequest.addHeaders(headerTabController.getHeaders());
deleteRequest.setHeaders(headerTabController.getHeaders());
requestManager.setRequest(deleteRequest);
cancelButton.setOnAction(e -> requestManager.cancel());
requestManager.setOnRunning(e -> {
@ -312,7 +314,7 @@ public class DashboardController implements Initializable {
responseSize.setText(Integer.toString(response.getSize()) + " B");
}
private void applySettings() {
private void applyDashboardSettings() {
String responseAreaCSS = "-fx-font-family: " + Settings.responseAreaFont + ";" +
"-fx-font-size: " + Settings.responseAreaFontSize;
responseArea.setStyle(responseAreaCSS);
@ -342,7 +344,7 @@ public class DashboardController implements Initializable {
}
@FXML
private void addParam() {
private void addParamField() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/StringKeyValueField.fxml"));
Parent headerField = loader.load();
@ -357,4 +359,35 @@ public class DashboardController implements Initializable {
public StringProperty getAddressProperty() {
return addressField.textProperty();
}
// Returns the current state of the Dashboard
public RestaurantRequest getState() {
try {
switch (httpMethodBox.getValue()) {
case "GET":
GETRequest getRequest = new GETRequest(addressField.getText());
getRequest.setHeaders(headerTabController.getHeaders());
return getRequest;
case "POST":
case "PUT":
DataDispatchRequest dataDispatchRequest = bodyTabController.getBasicRequest(httpMethodBox.getValue());
dataDispatchRequest.setHeaders(headerTabController.getHeaders());
return dataDispatchRequest;
case "DELETE":
DELETERequest deleteRequest = new DELETERequest(addressField.getText());
deleteRequest.setHeaders(headerTabController.getHeaders());
return deleteRequest;
}
} catch (MalformedURLException MURLE) {
System.out.println("Dashboard state was saved with a malformed URL.");
}
return null;
}
public void setState(RestaurantRequest request) {
addressField.setText(request.getTarget().toString());
for (Map.Entry entry : request.getHeaders().entrySet())
headerTabController.addHeader(entry.getKey().toString(), entry.getValue().toString());
}
}

View file

@ -43,12 +43,29 @@ public class HeaderTabController implements Initializable {
}
@FXML
private void addHeader() {
public void addHeader(String key, String value) {
/*
Re-uses previous field if it is empty,
else loads a new one.
*/
if (controllers.size() > 0) {
StringKeyValueFieldController previousController = controllers.get(controllers.size() - 1);
if (previousController.isKeyFieldEmtpy() &&
previousController.isValueFieldEmpty()) {
previousController.setKeyField(key);
previousController.setValueField(value);
return;
}
}
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/StringKeyValueField.fxml"));
Parent headerField = loader.load();
ThemeManager.setTheme(headerField);
StringKeyValueFieldController controller = loader.getController();
controller.setKeyField(key);
controller.setValueField(value);
controllers.add(controller);
headersBox.getChildren().add(headerField);
} catch (IOException e) {
@ -56,6 +73,10 @@ public class HeaderTabController implements Initializable {
}
}
public void addHeader() {
addHeader("", "");
}
public HashMap<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<>();
for (StringKeyValueFieldController controller : controllers) {

View file

@ -16,6 +16,7 @@
package com.rohitawate.restaurant.homewindow;
import com.rohitawate.restaurant.models.requests.RestaurantRequest;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.fxml.FXML;
@ -28,9 +29,12 @@ import javafx.scene.control.TabPane;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.stage.Stage;
import java.io.IOException;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
public class HomeWindowController implements Initializable {
@ -38,25 +42,35 @@ public class HomeWindowController implements Initializable {
private TabPane homeWindowTabPane;
private KeyCombination newTab = new KeyCodeCombination(KeyCode.T, KeyCombination.CONTROL_DOWN);
private List<DashboardController> controllers;
@Override
public void initialize(URL location, ResourceBundle resources) {
addTab();
controllers = new ArrayList<>();
recoverState();
Platform.runLater(() -> {
Scene thisScene = homeWindowTabPane.getScene();
thisScene.setOnKeyPressed(e -> {
if (newTab.match(e))
addTab();
});
Stage thisStage = (Stage) thisScene.getWindow();
thisStage.setOnCloseRequest(e -> saveState());
});
}
private void addTab() {
addTab(null);
}
private void addTab(RestaurantRequest request) {
try {
Tab newTab = new Tab();
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/Dashboard.fxml"));
Parent dashboard = loader.load();
DashboardController controller = loader.getController();
if (request != null)
controller.setState(request);
newTab.setContent(dashboard);
newTab.textProperty().bind(Bindings
.when(controller.getAddressProperty().isNotEmpty())
@ -65,10 +79,61 @@ public class HomeWindowController implements Initializable {
newTab.setOnCloseRequest(e -> {
if (homeWindowTabPane.getTabs().size() == 1)
addTab();
controllers.remove(controller);
});
homeWindowTabPane.getTabs().add(newTab);
controllers.add(controller);
} catch (IOException e) {
e.printStackTrace();
}
}
private void saveState() {
List<RestaurantRequest> states = new ArrayList<>();
// Get the states of all the tabs
for (DashboardController controller : controllers)
states.add(controller.getState());
try {
File configFolder = new File("config/");
if (!configFolder.exists())
configFolder.mkdir();
OutputStream fileStream = new FileOutputStream("config/restaurant.state");
ObjectOutputStream objectStream = new ObjectOutputStream(fileStream);
objectStream.writeObject(states);
objectStream.close();
System.out.println("Application state saved successfully.");
} catch (IOException e) {
System.out.println("Failed to save the application's state:");
e.printStackTrace();
}
}
private void recoverState() {
try {
InputStream fileStream = new FileInputStream("config/restaurant.state");
ObjectInputStream objectStream = new ObjectInputStream(fileStream);
System.out.print("Application state file found. Recovering state... ");
List<RestaurantRequest> states = (List<RestaurantRequest>) objectStream.readObject();
if (states.size() > 0) {
for (RestaurantRequest request : states)
addTab(request);
} else {
addTab();
}
} catch (FileNotFoundException e) {
System.out.print("Application state file not found. Loading default state... ");
addTab();
} catch (IOException | ClassNotFoundException e) {
System.out.print("Application state file is possibly corrupted. Could not recover the state.\nLoading default state... ");
addTab();
} finally {
System.out.println("Successful");
}
}
}

View file

@ -72,4 +72,20 @@ public class StringKeyValueFieldController implements Initializable {
public boolean isChecked() {
return checkBox.isSelected();
}
public void setKeyField(String key) {
keyField.setText(key);
}
public void setValueField(String value) {
valueField.setText(value);
}
public boolean isKeyFieldEmtpy() {
return keyField.getText().isEmpty();
}
public boolean isValueFieldEmpty() {
return valueField.getText().isEmpty();
}
}

View file

@ -16,11 +16,12 @@
package com.rohitawate.restaurant.models.requests;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
public abstract class RestaurantRequest {
public abstract class RestaurantRequest implements Serializable {
URL target;
private HashMap<String, String> headers;
@ -43,7 +44,7 @@ public abstract class RestaurantRequest {
headers.put(key, value);
}
public void addHeaders(HashMap<String, String> headers) {
public void setHeaders(HashMap<String, String> headers) {
this.headers = headers;
}

View file

@ -24,6 +24,7 @@ import com.rohitawate.restaurant.models.requests.GETRequest;
import com.rohitawate.restaurant.models.requests.RestaurantRequest;
import com.rohitawate.restaurant.util.json.JSONUtils;
import java.io.File;
import java.io.InputStream;
import java.sql.*;
import java.time.LocalDate;
@ -36,7 +37,11 @@ public class HistoryManager {
public HistoryManager() {
try {
conn = DriverManager.getConnection("jdbc:sqlite:history.sqlite");
File configFolder = new File("config/");
if (!configFolder.exists())
configFolder.mkdir();
conn = DriverManager.getConnection("jdbc:sqlite:config/history.sqlite");
// Read all queries from Queries.json
InputStream queriesFile = getClass().getResourceAsStream("/sql/Queries.json");

View file

@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.rohitawate.restaurant.util.json.JSONUtils;
import java.io.File;
import java.io.FileNotFoundException;
/**
* Loads up custom values into Settings from settings.json.
@ -36,7 +37,12 @@ public class SettingsLoader implements Runnable {
@Override
public void run() {
try {
File settingsFile = new File("settings.json");
File settingsFile = new File("config/settings.json");
if (settingsFile.exists())
System.out.print("Settings file found. Loading settings... ");
else
throw new FileNotFoundException();
ObjectMapper mapper = new ObjectMapper();
JsonNode nodes = mapper.readTree(settingsFile);
@ -54,9 +60,9 @@ public class SettingsLoader implements Runnable {
Settings.theme = JSONUtils.trimString(nodes.get("theme").toString());
} catch (Exception E) {
System.out.println("Settings file not found. Loading default values...");
System.out.print("Settings file not found. Loading default values... ");
} finally {
System.out.println("Settings loaded.");
System.out.println("Successful");
}
}
}

View file

@ -51,7 +51,7 @@
<Insets right="20.0" />
</HBox.margin>
</ComboBox>
<JFXButton fx:id="sendButton" buttonType="RAISED" defaultButton="true" onAction="#sendAction"
<JFXButton fx:id="sendButton" buttonType="RAISED" defaultButton="true" onAction="#sendRequest"
prefHeight="39.0" prefWidth="100.0" text=" SEND" textFill="WHITE" HBox.hgrow="ALWAYS">
<padding>
<Insets bottom="5.0" left="15.0" right="15.0" top="5.0" />
@ -91,7 +91,7 @@
<Insets/>
</VBox.margin>
<children>
<JFXButton fx:id="newParamButton" onAction="#addParam"
<JFXButton fx:id="newParamButton" onAction="#addParamField"
text=" NEW PARAM" textFill="WHITE"
HBox.hgrow="ALWAYS">
<graphic>