Created new class DashboardState to better abstract the application state and added recovery of POST/PUT requests' body

This commit is contained in:
Rohit Awate 2018-02-15 12:16:23 +05:30
parent b3ffa5ecd4
commit a97a6c633c
11 changed files with 244 additions and 77 deletions

View file

@ -1,9 +0,0 @@
{
"responseAreaFont": "Liberation Mono",
"responseAreaFontSize": "18",
"connectionTimeOutEnable": "false",
"connectionTimeOut": "10000",
"connectionReadTimeOutEnable": "false",
"connectionReadTimeOut": "30000",
"theme": null
}

View file

@ -16,22 +16,21 @@
package com.rohitawate.restaurant.homewindow; package com.rohitawate.restaurant.homewindow;
import com.rohitawate.restaurant.models.DashboardState;
import com.rohitawate.restaurant.models.requests.DataDispatchRequest; import com.rohitawate.restaurant.models.requests.DataDispatchRequest;
import com.rohitawate.restaurant.util.themes.ThemeManager; import com.rohitawate.restaurant.util.themes.ThemeManager;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.control.ComboBox; import javafx.scene.control.*;
import javafx.scene.control.Tab;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import javafx.stage.Window; import javafx.stage.Window;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.Map;
import java.util.ResourceBundle; import java.util.ResourceBundle;
/* /*
@ -40,6 +39,8 @@ import java.util.ResourceBundle;
URL encoded and Form tabs have special FXMLs. URL encoded and Form tabs have special FXMLs.
*/ */
public class BodyTabController implements Initializable { public class BodyTabController implements Initializable {
@FXML
private TabPane bodyTabPane;
@FXML @FXML
private ComboBox<String> rawInputTypeBox; private ComboBox<String> rawInputTypeBox;
@FXML @FXML
@ -101,7 +102,6 @@ public class BodyTabController implements Initializable {
} else if (formTab.isSelected()) { } else if (formTab.isSelected()) {
request.setStringTuples(formDataTabController.getStringTuples()); request.setStringTuples(formDataTabController.getStringTuples());
request.setFileTuples(formDataTabController.getFileTuples()); request.setFileTuples(formDataTabController.getFileTuples());
request.setContentType(MediaType.MULTIPART_FORM_DATA); request.setContentType(MediaType.MULTIPART_FORM_DATA);
} else if (binaryTab.isSelected()) { } else if (binaryTab.isSelected()) {
request.setBody(filePathField.getText()); request.setBody(filePathField.getText());
@ -126,4 +126,48 @@ public class BodyTabController implements Initializable {
} }
filePathField.setText(filePath); filePathField.setText(filePath);
} }
public void setState(DashboardState dashboardState) {
switch (dashboardState.getContentType()) {
case MediaType.TEXT_PLAIN:
rawInputArea.setText(dashboardState.getBody());
rawInputTypeBox.getSelectionModel().select("PLAIN TEXT");
bodyTabPane.getSelectionModel().select(rawTab);
break;
case MediaType.APPLICATION_JSON:
rawInputArea.setText(dashboardState.getBody());
rawInputTypeBox.getSelectionModel().select("JSON");
bodyTabPane.getSelectionModel().select(rawTab);
break;
case MediaType.APPLICATION_XML:
rawInputArea.setText(dashboardState.getBody());
rawInputTypeBox.getSelectionModel().select("XML");
bodyTabPane.getSelectionModel().select(rawTab);
break;
case MediaType.TEXT_HTML:
rawInputArea.setText(dashboardState.getBody());
rawInputTypeBox.getSelectionModel().select("HTML");
bodyTabPane.getSelectionModel().select(rawTab);
break;
case MediaType.MULTIPART_FORM_DATA:
// For file tuples
for (Map.Entry entry : dashboardState.getFileTuples().entrySet())
formDataTabController.addFileField(entry.getKey().toString(), entry.getValue().toString());
// For string tuples
for (Map.Entry entry : dashboardState.getStringTuples().entrySet())
formDataTabController.addStringField(entry.getKey().toString(), entry.getValue().toString());
bodyTabPane.getSelectionModel().select(formTab);
break;
case MediaType.APPLICATION_OCTET_STREAM:
filePathField.setText(dashboardState.getBody());
bodyTabPane.getSelectionModel().select(binaryTab);
break;
case MediaType.APPLICATION_FORM_URLENCODED:
for (Map.Entry entry : dashboardState.getStringTuples().entrySet())
urlTabController.addField(entry.getKey().toString(), entry.getValue().toString());
bodyTabPane.getSelectionModel().select(urlTab);
break;
}
}
} }

View file

@ -18,10 +18,10 @@ package com.rohitawate.restaurant.homewindow;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXSnackbar; import com.jfoenix.controls.JFXSnackbar;
import com.rohitawate.restaurant.exceptions.UnreliableResponseException; import com.rohitawate.restaurant.exceptions.UnreliableResponseException;
import com.rohitawate.restaurant.models.DashboardState;
import com.rohitawate.restaurant.models.requests.DELETERequest; import com.rohitawate.restaurant.models.requests.DELETERequest;
import com.rohitawate.restaurant.models.requests.DataDispatchRequest; import com.rohitawate.restaurant.models.requests.DataDispatchRequest;
import com.rohitawate.restaurant.models.requests.GETRequest; 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.models.responses.RestaurantResponse;
import com.rohitawate.restaurant.requestsmanager.DELETERequestManager; import com.rohitawate.restaurant.requestsmanager.DELETERequestManager;
import com.rohitawate.restaurant.requestsmanager.DataDispatchRequestManager; import com.rohitawate.restaurant.requestsmanager.DataDispatchRequestManager;
@ -46,10 +46,7 @@ import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
public class DashboardController implements Initializable { public class DashboardController implements Initializable {
@FXML @FXML
@ -103,13 +100,13 @@ public class DashboardController implements Initializable {
IOE.printStackTrace(); IOE.printStackTrace();
} }
// Select GET by default
httpMethodBox.getSelectionModel().select("GET");
responseBox.getChildren().remove(0); responseBox.getChildren().remove(0);
promptLayer.setVisible(true); promptLayer.setVisible(true);
httpMethodBox.getItems().addAll(httpMethods); httpMethodBox.getItems().addAll(httpMethods);
// Selects GET by default
httpMethodBox.getSelectionModel().select(0);
paramsControllers = new ArrayList<>(); paramsControllers = new ArrayList<>();
appendedParams = new ArrayList<>(); appendedParams = new ArrayList<>();
addParamField(); // Adds a blank param field addParamField(); // Adds a blank param field
@ -200,7 +197,7 @@ public class DashboardController implements Initializable {
} }
DataDispatchRequest dataDispatchRequest = DataDispatchRequest dataDispatchRequest =
(DataDispatchRequest) bodyTabController.getBasicRequest(httpMethodBox.getValue()); bodyTabController.getBasicRequest(httpMethodBox.getValue());
dataDispatchRequest.setTarget(addressField.getText()); dataDispatchRequest.setTarget(addressField.getText());
dataDispatchRequest.setHeaders(headerTabController.getHeaders()); dataDispatchRequest.setHeaders(headerTabController.getHeaders());
@ -343,12 +340,43 @@ public class DashboardController implements Initializable {
} }
} }
private HashMap<String, String> getParams() {
HashMap<String, String> params = new HashMap<>();
for (StringKeyValueFieldController controller : paramsControllers)
params.put(controller.getHeader().getKey(), controller.getHeader().getValue());
return params;
}
@FXML @FXML
private void addParamField() { private void addParamField() {
addParamField("", "");
}
// Adds a new URL-parameter field
private void addParamField(String key, String value) {
/*
Re-uses previous field if it is empty,
else loads a new one.
*/
if (paramsControllers.size() > 0) {
StringKeyValueFieldController previousController = paramsControllers.get(paramsControllers.size() - 1);
if (previousController.isKeyFieldEmtpy() &&
previousController.isValueFieldEmpty()) {
previousController.setKeyField(key);
previousController.setValueField(value);
return;
}
}
try { try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/StringKeyValueField.fxml")); FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/StringKeyValueField.fxml"));
Parent headerField = loader.load(); Parent headerField = loader.load();
StringKeyValueFieldController controller = loader.getController(); StringKeyValueFieldController controller = loader.getController();
controller.setKeyField(key);
controller.setValueField(value);
paramsControllers.add(controller); paramsControllers.add(controller);
paramsBox.getChildren().add(headerField); paramsBox.getChildren().add(headerField);
} catch (IOException e) { } catch (IOException e) {
@ -360,34 +388,55 @@ public class DashboardController implements Initializable {
return addressField.textProperty(); return addressField.textProperty();
} }
// Returns the current state of the Dashboard /**
public RestaurantRequest getState() { * Returns the current state of the Dashboard
*
* @return DashboardState - Current state of the Dashboard
*/
public DashboardState getState() {
DashboardState dashboardState = null;
try { try {
switch (httpMethodBox.getValue()) { switch (httpMethodBox.getValue()) {
case "GET":
GETRequest getRequest = new GETRequest(addressField.getText());
getRequest.setHeaders(headerTabController.getHeaders());
return getRequest;
case "POST": case "POST":
case "PUT": case "PUT":
DataDispatchRequest dataDispatchRequest = bodyTabController.getBasicRequest(httpMethodBox.getValue()); dashboardState = new DashboardState(bodyTabController.getBasicRequest(httpMethodBox.getValue()));
dataDispatchRequest.setHeaders(headerTabController.getHeaders()); dashboardState.setHeaders(headerTabController.getHeaders());
return dataDispatchRequest; break;
case "DELETE": default:
DELETERequest deleteRequest = new DELETERequest(addressField.getText()); // For GET, DELETE requests
deleteRequest.setHeaders(headerTabController.getHeaders()); dashboardState = new DashboardState();
return deleteRequest;
} }
dashboardState.setTarget(addressField.getText());
dashboardState.setHttpMethod(httpMethodBox.getValue());
dashboardState.setHeaders(headerTabController.getHeaders());
dashboardState.setParams(getParams());
} catch (MalformedURLException MURLE) { } catch (MalformedURLException MURLE) {
System.out.println("Dashboard state was saved with a malformed URL."); System.out.println("Dashboard state was saved with a malformed URL.");
} }
return null; return dashboardState;
} }
public void setState(RestaurantRequest request) { /**
addressField.setText(request.getTarget().toString()); * Sets the Dashboard to the given application state.
*
* @param dashboardState - State of the dashboard
*/
public void setState(DashboardState dashboardState) {
if (dashboardState.getTarget() != null)
addressField.setText(dashboardState.getTarget().toString());
for (Map.Entry entry : request.getHeaders().entrySet()) httpMethodBox.getSelectionModel().select(dashboardState.getHttpMethod());
headerTabController.addHeader(entry.getKey().toString(), entry.getValue().toString());
if (dashboardState.getHeaders() != null)
for (Map.Entry entry : dashboardState.getHeaders().entrySet())
headerTabController.addHeader(entry.getKey().toString(), entry.getValue().toString());
if (dashboardState.getParams() != null)
for (Map.Entry entry : dashboardState.getParams().entrySet())
addParamField(entry.getKey().toString(), entry.getValue().toString());
if (httpMethodBox.getValue().equals("POST") || httpMethodBox.getValue().equals("PUT"))
bodyTabController.setState(dashboardState);
} }
} }

View file

@ -89,4 +89,12 @@ public class FileKeyValueFieldController implements Initializable {
public boolean isChecked() { public boolean isChecked() {
return checkBox.isSelected(); return checkBox.isSelected();
} }
public void setFileKeyField(String key) {
fileKeyField.setText(key);
}
public void setFileValueField(String value) {
fileValueField.setText(value);
}
} }

View file

@ -48,11 +48,17 @@ public class FormDataTabController implements Initializable {
@FXML @FXML
private void addFileField() { private void addFileField() {
addFileField("", "");
}
public void addFileField(String key, String value) {
try { try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/FileKeyValueField.fxml")); FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/FileKeyValueField.fxml"));
Parent headerField = loader.load(); Parent headerField = loader.load();
ThemeManager.setTheme(headerField); ThemeManager.setTheme(headerField);
FileKeyValueFieldController controller = loader.getController(); FileKeyValueFieldController controller = loader.getController();
controller.setFileKeyField(key);
controller.setFileValueField(value);
fileControllers.add(controller); fileControllers.add(controller);
headersBox.getChildren().add(headerField); headersBox.getChildren().add(headerField);
} catch (IOException e) { } catch (IOException e) {
@ -62,10 +68,16 @@ public class FormDataTabController implements Initializable {
@FXML @FXML
private void addStringField() { private void addStringField() {
addStringField("", "");
}
public void addStringField(String key, String value) {
try { try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/StringKeyValueField.fxml")); FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/StringKeyValueField.fxml"));
Parent headerField = loader.load(); Parent headerField = loader.load();
StringKeyValueFieldController controller = loader.getController(); StringKeyValueFieldController controller = loader.getController();
controller.setKeyField(key);
controller.setValueField(value);
stringControllers.add(controller); stringControllers.add(controller);
headersBox.getChildren().add(headerField); headersBox.getChildren().add(headerField);
} catch (IOException e) { } catch (IOException e) {

View file

@ -16,7 +16,7 @@
package com.rohitawate.restaurant.homewindow; package com.rohitawate.restaurant.homewindow;
import com.rohitawate.restaurant.models.requests.RestaurantRequest; import com.rohitawate.restaurant.models.DashboardState;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.fxml.FXML; import javafx.fxml.FXML;
@ -63,14 +63,14 @@ public class HomeWindowController implements Initializable {
addTab(null); addTab(null);
} }
private void addTab(RestaurantRequest request) { private void addTab(DashboardState dashboardState) {
try { try {
Tab newTab = new Tab(); Tab newTab = new Tab();
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/Dashboard.fxml")); FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/Dashboard.fxml"));
Parent dashboard = loader.load(); Parent dashboard = loader.load();
DashboardController controller = loader.getController(); DashboardController controller = loader.getController();
if (request != null) if (dashboardState != null)
controller.setState(request); controller.setState(dashboardState);
newTab.setContent(dashboard); newTab.setContent(dashboard);
newTab.textProperty().bind(Bindings newTab.textProperty().bind(Bindings
.when(controller.getAddressProperty().isNotEmpty()) .when(controller.getAddressProperty().isNotEmpty())
@ -89,11 +89,11 @@ public class HomeWindowController implements Initializable {
} }
private void saveState() { private void saveState() {
List<RestaurantRequest> states = new ArrayList<>(); List<DashboardState> dashboardStates = new ArrayList<>();
// Get the states of all the tabs // Get the states of all the tabs
for (DashboardController controller : controllers) for (DashboardController controller : controllers)
states.add(controller.getState()); dashboardStates.add(controller.getState());
try { try {
File configFolder = new File("config/"); File configFolder = new File("config/");
@ -102,8 +102,9 @@ public class HomeWindowController implements Initializable {
OutputStream fileStream = new FileOutputStream("config/restaurant.state"); OutputStream fileStream = new FileOutputStream("config/restaurant.state");
ObjectOutputStream objectStream = new ObjectOutputStream(fileStream); ObjectOutputStream objectStream = new ObjectOutputStream(fileStream);
objectStream.writeObject(states); objectStream.writeObject(dashboardStates);
objectStream.close(); objectStream.close();
fileStream.close();
System.out.println("Application state saved successfully."); System.out.println("Application state saved successfully.");
} catch (IOException e) { } catch (IOException e) {
System.out.println("Failed to save the application's state:"); System.out.println("Failed to save the application's state:");
@ -116,24 +117,26 @@ public class HomeWindowController implements Initializable {
InputStream fileStream = new FileInputStream("config/restaurant.state"); InputStream fileStream = new FileInputStream("config/restaurant.state");
ObjectInputStream objectStream = new ObjectInputStream(fileStream); ObjectInputStream objectStream = new ObjectInputStream(fileStream);
System.out.print("Application state file found. Recovering state... "); System.out.println("Application state file found. Recovering state... ");
List<RestaurantRequest> states = (List<RestaurantRequest>) objectStream.readObject(); List<DashboardState> dashboardStates = (List<DashboardState>) objectStream.readObject();
objectStream.close();
fileStream.close();
if (states.size() > 0) { if (dashboardStates.size() > 0) {
for (RestaurantRequest request : states) for (DashboardState dashboardState : dashboardStates)
addTab(request); addTab(dashboardState);
} else { } else {
addTab(); addTab();
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
System.out.print("Application state file not found. Loading default state... "); System.out.println("Application state file not found. Loading default state... ");
addTab(); addTab();
} catch (IOException | ClassNotFoundException e) { } catch (IOException | ClassNotFoundException e) {
System.out.print("Application state file is possibly corrupted. Could not recover the state.\nLoading default state... "); System.out.println("Application state file is possibly corrupted. Could not recover the state.\nLoading default state... ");
addTab(); addTab();
} finally { } finally {
System.out.println("Successful"); System.out.println("Application loaded.");
} }
} }
} }

View file

@ -44,11 +44,17 @@ public class URLTabController implements Initializable {
@FXML @FXML
private void addField() { private void addField() {
addField("", "");
}
public void addField(String key, String value) {
try { try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/StringKeyValueField.fxml")); FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/StringKeyValueField.fxml"));
Parent parent = loader.load(); Parent parent = loader.load();
ThemeManager.setTheme(parent); ThemeManager.setTheme(parent);
StringKeyValueFieldController controller = loader.getController(); StringKeyValueFieldController controller = loader.getController();
controller.setKeyField(key);
controller.setValueField(value);
controllers.add(controller); controllers.add(controller);
fieldsBox.getChildren().add(parent); fieldsBox.getChildren().add(parent);
} catch (IOException e) { } catch (IOException e) {

View file

@ -0,0 +1,62 @@
/*
* Copyright 2018 Rohit Awate.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.rohitawate.restaurant.models;
import com.rohitawate.restaurant.models.requests.DataDispatchRequest;
import java.io.Serializable;
import java.util.HashMap;
/**
* Convenience class to abstract the state of the application.
*/
public class DashboardState extends DataDispatchRequest implements Serializable {
private HashMap<String, String> params;
private String httpMethod;
public DashboardState() {
}
/*
Special copy constructor to instantiate DashboardState from
BodyTabController's getBasicRequest()
*/
public DashboardState(DataDispatchRequest dataDispatchRequest) {
super();
this.setHttpMethod(dataDispatchRequest.getRequestType());
this.setBody(dataDispatchRequest.getBody());
this.setContentType(dataDispatchRequest.getContentType());
this.setStringTuples(dataDispatchRequest.getStringTuples());
this.setFileTuples(dataDispatchRequest.getFileTuples());
}
public void setParams(HashMap<String, String> params) {
this.params = params;
}
public HashMap<String, String> getParams() {
return params;
}
public void setHttpMethod(String httpMethod) {
this.httpMethod = httpMethod;
}
public String getHttpMethod() {
return httpMethod;
}
}

View file

@ -16,38 +16,26 @@
package com.rohitawate.restaurant.models.requests; package com.rohitawate.restaurant.models.requests;
import java.net.MalformedURLException; import java.io.Serializable;
import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
/** /**
* Represents HTTP requests which contain data viz. POST and PUT. * Represents HTTP requests which contain data viz. POST and PUT.
*/ */
public class DataDispatchRequest extends RestaurantRequest { public class DataDispatchRequest extends RestaurantRequest implements Serializable {
private String requestType; private String requestType;
private String body; private String body;
private String contentType; private String contentType;
private HashMap<String, String> stringTuples; private HashMap<String, String> stringTuples;
private HashMap<String, String> fileTuples; private HashMap<String, String> fileTuples;
public DataDispatchRequest() {
}
public DataDispatchRequest(String requestType) { public DataDispatchRequest(String requestType) {
this.requestType = requestType; this.requestType = requestType;
} }
public DataDispatchRequest(URL target, String requestType) {
super(target);
this.requestType = requestType;
}
public DataDispatchRequest(String target, String requestType) throws MalformedURLException {
super(target);
this.requestType = requestType;
}
public void setTarget(String target) throws MalformedURLException {
this.target = new URL(target);
}
public String getBody() { public String getBody() {
return body; return body;
} }

View file

@ -22,7 +22,7 @@ import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
public abstract class RestaurantRequest implements Serializable { public abstract class RestaurantRequest implements Serializable {
URL target; private URL target;
private HashMap<String, String> headers; private HashMap<String, String> headers;
RestaurantRequest() { RestaurantRequest() {
@ -36,8 +36,12 @@ public abstract class RestaurantRequest implements Serializable {
this.target = target; this.target = target;
} }
public void setTarget(String target) throws MalformedURLException {
this.target = new URL(target);
}
public URL getTarget() { public URL getTarget() {
return target; return this.target;
} }
public void addHeader(String key, String value) { public void addHeader(String key, String value) {

View file

@ -60,9 +60,9 @@ public class SettingsLoader implements Runnable {
Settings.theme = JSONUtils.trimString(nodes.get("theme").toString()); Settings.theme = JSONUtils.trimString(nodes.get("theme").toString());
} catch (Exception E) { } catch (Exception E) {
System.out.print("Settings file not found. Loading default values... "); System.out.println("Settings file not found. Loading default values... ");
} finally { } finally {
System.out.println("Successful"); System.out.println("Settings loaded.");
} }
} }
} }