State maintenance logic now retains selection status of KeyValue fields

This commit is contained in:
Rohit Awate 2018-06-30 20:53:28 +05:30
parent 6e7606c99a
commit 51cbce3d7a
No known key found for this signature in database
GPG key ID: 1051D7B79CF2EE25
13 changed files with 299 additions and 149 deletions

View file

@ -18,6 +18,8 @@ package com.rohitawate.everest.controllers;
import com.rohitawate.everest.controllers.codearea.EverestCodeArea; import com.rohitawate.everest.controllers.codearea.EverestCodeArea;
import com.rohitawate.everest.controllers.codearea.EverestCodeArea.HighlightMode; import com.rohitawate.everest.controllers.codearea.EverestCodeArea.HighlightMode;
import com.rohitawate.everest.controllers.state.DashboardState;
import com.rohitawate.everest.controllers.state.FieldState;
import com.rohitawate.everest.misc.Services; import com.rohitawate.everest.misc.Services;
import com.rohitawate.everest.misc.ThemeManager; import com.rohitawate.everest.misc.ThemeManager;
import javafx.fxml.FXML; import javafx.fxml.FXML;
@ -36,7 +38,6 @@ import javax.ws.rs.core.MediaType;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Map.Entry;
import java.util.ResourceBundle; import java.util.ResourceBundle;
/* /*
@ -123,9 +124,9 @@ public class BodyTabController implements Initializable {
state.rawBodyType = rawInputTypeBox.getValue(); state.rawBodyType = rawInputTypeBox.getValue();
state.rawBody = rawInputArea.getText(); state.rawBody = rawInputArea.getText();
state.urlStringTuples = urlTabController.getStringTuples(false); state.urlStringTuples = urlTabController.getFieldStates();
state.formStringTuples = formDataTabController.getStringTuples(false); state.formStringTuples = formDataTabController.getStringFieldStates();
state.formFileTuples = formDataTabController.getFileTuples(false); state.formFileTuples = formDataTabController.getFileFieldStates();
state.binaryFilePath = filePathField.getText(); state.binaryFilePath = filePathField.getText();
if (rawTab.isSelected()) { if (rawTab.isSelected()) {
@ -156,18 +157,18 @@ public class BodyTabController implements Initializable {
public void setState(DashboardState state) { public void setState(DashboardState state) {
// Adding URL tab's tuples // Adding URL tab's tuples
if (state.urlStringTuples != null) if (state.urlStringTuples != null)
for (Entry<String, String> entry : state.urlStringTuples.entrySet()) for (FieldState fieldState : state.urlStringTuples)
urlTabController.addField(entry.getKey(), entry.getValue()); urlTabController.addField(fieldState);
// Adding Form tab's string tuples // Adding Form tab's string tuples
if (state.formStringTuples != null) if (state.formStringTuples != null)
for (Entry<String, String> entry : state.formStringTuples.entrySet()) for (FieldState fieldState : state.formStringTuples)
formDataTabController.addStringField(entry.getKey(), entry.getValue()); formDataTabController.addStringField(fieldState);
// Adding Form tab's file tuples // Adding Form tab's file tuples
if (state.formFileTuples != null) if (state.formFileTuples != null)
for (Entry<String, String> entry : state.formFileTuples.entrySet()) for (FieldState fieldState : state.formFileTuples)
formDataTabController.addFileField(entry.getKey(), entry.getValue()); formDataTabController.addFileField(fieldState);
setRawTab(state); setRawTab(state);

View file

@ -21,6 +21,8 @@ import com.jfoenix.controls.JFXProgressBar;
import com.jfoenix.controls.JFXSnackbar; import com.jfoenix.controls.JFXSnackbar;
import com.rohitawate.everest.controllers.codearea.EverestCodeArea; import com.rohitawate.everest.controllers.codearea.EverestCodeArea;
import com.rohitawate.everest.controllers.codearea.EverestCodeArea.HighlightMode; import com.rohitawate.everest.controllers.codearea.EverestCodeArea.HighlightMode;
import com.rohitawate.everest.controllers.state.DashboardState;
import com.rohitawate.everest.controllers.state.FieldState;
import com.rohitawate.everest.exceptions.RedirectException; import com.rohitawate.everest.exceptions.RedirectException;
import com.rohitawate.everest.exceptions.UnreliableResponseException; import com.rohitawate.everest.exceptions.UnreliableResponseException;
import com.rohitawate.everest.misc.EverestUtilities; import com.rohitawate.everest.misc.EverestUtilities;
@ -58,7 +60,6 @@ import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map.Entry;
import java.util.ResourceBundle; import java.util.ResourceBundle;
public class DashboardController implements Initializable { public class DashboardController implements Initializable {
@ -483,21 +484,33 @@ public class DashboardController implements Initializable {
return params; return params;
} }
private void addParamField() { /**
addParamField("", "", null); * Return an ArrayList of the state of all the fields in the Params tab.
*/
public ArrayList<FieldState> getParamFieldStates() {
ArrayList<FieldState> states = new ArrayList<>();
for (StringKeyValueFieldController controller : paramsControllers)
states.add(controller.getState());
return states;
} }
private void addParamField(String key, String value) { private void addParamField() {
addParamField(key, value, null); addParamField("", "", null, false);
}
private void addParamField(FieldState state) {
addParamField(state.key, state.value, null, state.checked);
} }
@FXML @FXML
private void addParamField(ActionEvent event) { private void addParamField(ActionEvent event) {
addParamField("", "", event); addParamField("", "", event, false);
} }
// Adds a new URL-parameter field // Adds a new URL-parameter field
private void addParamField(String key, String value, ActionEvent event) { private void addParamField(String key, String value, ActionEvent event, boolean checked) {
/* /*
Re-uses previous field if it is empty, Re-uses previous field if it is empty,
else loads a new one. else loads a new one.
@ -519,6 +532,7 @@ public class DashboardController implements Initializable {
StringKeyValueFieldController controller = loader.getController(); StringKeyValueFieldController controller = loader.getController();
controller.setKeyField(key); controller.setKeyField(key);
controller.setValueField(value); controller.setValueField(value);
controller.setChecked(checked);
paramsControllers.add(controller); paramsControllers.add(controller);
paramsCountProperty.set(paramsCountProperty.get() + 1); paramsCountProperty.set(paramsCountProperty.get() + 1);
controller.deleteButton.visibleProperty().bind(Bindings.greaterThan(paramsCountProperty, 1)); controller.deleteButton.visibleProperty().bind(Bindings.greaterThan(paramsCountProperty, 1));
@ -553,8 +567,8 @@ public class DashboardController implements Initializable {
dashboardState.target = addressField.getText(); dashboardState.target = addressField.getText();
dashboardState.httpMethod = httpMethodBox.getValue(); dashboardState.httpMethod = httpMethodBox.getValue();
dashboardState.headers = headerTabController.getHeaders(false); dashboardState.headers = headerTabController.getFieldStates();
dashboardState.params = getParams(false); dashboardState.params = getParamFieldStates();
return dashboardState; return dashboardState;
} }
@ -582,12 +596,12 @@ public class DashboardController implements Initializable {
addressField.setText(state.target); addressField.setText(state.target);
if (state.headers != null) if (state.headers != null)
for (Entry entry : state.headers.entrySet()) for (FieldState fieldState : state.headers)
headerTabController.addHeader(entry.getKey().toString(), entry.getValue().toString()); headerTabController.addHeader(fieldState);
if (state.params != null) if (state.params != null)
for (Entry entry : state.params.entrySet()) for (FieldState fieldState : state.params)
addParamField(entry.getKey().toString(), entry.getValue().toString()); addParamField(fieldState);
if (!(httpMethodBox.getValue().equals("GET") || httpMethodBox.getValue().equals("DELETE"))) if (!(httpMethodBox.getValue().equals("GET") || httpMethodBox.getValue().equals("DELETE")))
bodyTabController.setState(state); bodyTabController.setState(state);

View file

@ -18,6 +18,7 @@ package com.rohitawate.everest.controllers;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXCheckBox; import com.jfoenix.controls.JFXCheckBox;
import com.rohitawate.everest.controllers.state.FieldState;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
@ -108,4 +109,12 @@ public class FileKeyValueFieldController implements Initializable {
public boolean isFileValueFieldEmpty() { public boolean isFileValueFieldEmpty() {
return fileValueField.getText().isEmpty(); return fileValueField.getText().isEmpty();
} }
public FieldState getState() {
return new FieldState(fileKeyField.getText(), fileValueField.getText(), checkBox.isSelected());
}
public void setChecked(boolean checked) {
checkBox.setSelected(checked);
}
} }

View file

@ -16,6 +16,7 @@
package com.rohitawate.everest.controllers; package com.rohitawate.everest.controllers;
import com.rohitawate.everest.controllers.state.FieldState;
import com.rohitawate.everest.misc.Services; import com.rohitawate.everest.misc.Services;
import com.rohitawate.everest.misc.ThemeManager; import com.rohitawate.everest.misc.ThemeManager;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
@ -59,21 +60,20 @@ public class FormDataTabController implements Initializable {
addStringField(); addStringField();
} }
public void addFileField(FieldState state) {
addFileField(state.key, state.value, null, state.checked);
}
@FXML @FXML
private void addFileField(ActionEvent event) { private void addFileField(ActionEvent event) {
addFileField("", "", event); addFileField("", "", event, false);
} }
private void addFileField() { private void addFileField() {
addFileField("", "", null); addFileField("", "", null, false);
} }
public void addFileField(String key, String value) { private void addFileField(String key, String value, ActionEvent event, boolean checked) {
addFileField(key, value, null);
}
private void addFileField(String key, String value, ActionEvent event) {
//Re-uses previous field if it is empty else loads a new one. //Re-uses previous field if it is empty else loads a new one.
if (fileControllers.size() > 0 && event == null) { if (fileControllers.size() > 0 && event == null) {
FileKeyValueFieldController previousController = fileControllers.get(fileControllers.size() - 1); FileKeyValueFieldController previousController = fileControllers.get(fileControllers.size() - 1);
@ -93,6 +93,7 @@ public class FormDataTabController implements Initializable {
FileKeyValueFieldController controller = loader.getController(); FileKeyValueFieldController controller = loader.getController();
controller.setFileKeyField(key); controller.setFileKeyField(key);
controller.setFileValueField(value); controller.setFileValueField(value);
controller.setChecked(checked);
fileControllers.add(controller); fileControllers.add(controller);
fileControllersCount.set(fileControllersCount.get() + 1); fileControllersCount.set(fileControllersCount.get() + 1);
controller.deleteButton.visibleProperty().bind(Bindings.greaterThan(fileControllersCount, 1)); controller.deleteButton.visibleProperty().bind(Bindings.greaterThan(fileControllersCount, 1));
@ -107,20 +108,20 @@ public class FormDataTabController implements Initializable {
} }
} }
public void addStringField(FieldState state) {
addStringField(state.key, state.value, null, state.checked);
}
@FXML @FXML
private void addStringField(ActionEvent event) { private void addStringField(ActionEvent event) {
addStringField("", "", event); addStringField("", "", event, false);
} }
private void addStringField() { private void addStringField() {
addStringField("", "", null); addStringField("", "", null, false);
} }
public void addStringField(String key, String value) { private void addStringField(String key, String value, ActionEvent event, boolean checked) {
addStringField(key, value, null);
}
private void addStringField(String key, String value, ActionEvent event) {
/* /*
Re-uses previous field if it is empty, Re-uses previous field if it is empty,
else loads a new one. else loads a new one.
@ -142,6 +143,7 @@ public class FormDataTabController implements Initializable {
StringKeyValueFieldController controller = loader.getController(); StringKeyValueFieldController controller = loader.getController();
controller.setKeyField(key); controller.setKeyField(key);
controller.setValueField(value); controller.setValueField(value);
controller.setChecked(checked);
stringControllers.add(controller); stringControllers.add(controller);
stringControllersCount.set(stringControllersCount.get() + 1); stringControllersCount.set(stringControllersCount.get() + 1);
controller.deleteButton.visibleProperty().bind(Bindings.greaterThan(stringControllersCount, 1)); controller.deleteButton.visibleProperty().bind(Bindings.greaterThan(stringControllersCount, 1));
@ -186,4 +188,30 @@ public class FormDataTabController implements Initializable {
} }
return fileMap; return fileMap;
} }
/**
* Return an ArrayList of the state of all the string fields in the Form data tab.
*/
public ArrayList<FieldState> getStringFieldStates() {
ArrayList<FieldState> states = new ArrayList<>();
for (StringKeyValueFieldController controller : stringControllers)
states.add(controller.getState());
return states;
}
/**
* Return an ArrayList of the state of all the file fields in the Form data tab.
*/
public ArrayList<FieldState> getFileFieldStates() {
ArrayList<FieldState> states = new ArrayList<>();
for (FileKeyValueFieldController controller : fileControllers)
states.add(controller.getState());
return states;
}
} }

View file

@ -16,6 +16,7 @@
package com.rohitawate.everest.controllers; package com.rohitawate.everest.controllers;
import com.rohitawate.everest.controllers.state.FieldState;
import com.rohitawate.everest.misc.Services; import com.rohitawate.everest.misc.Services;
import com.rohitawate.everest.misc.ThemeManager; import com.rohitawate.everest.misc.ThemeManager;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
@ -52,20 +53,20 @@ public class HeaderTabController implements Initializable {
addHeader(); addHeader();
} }
public void addHeader(String key, String value) { public void addHeader(FieldState state) {
addHeader(key, value, null); addHeader(state.key, state.value, null, state.checked);
} }
private void addHeader() { private void addHeader() {
addHeader("", "", null); addHeader("", "", null, false);
} }
@FXML @FXML
private void addHeader(ActionEvent event) { private void addHeader(ActionEvent event) {
addHeader("", "", event); addHeader("", "", event, false);
} }
private void addHeader(String key, String value, ActionEvent event) { private void addHeader(String key, String value, ActionEvent event, boolean checked) {
/* /*
Re-uses previous field if it is empty, Re-uses previous field if it is empty,
else loads a new one. else loads a new one.
@ -88,6 +89,7 @@ public class HeaderTabController implements Initializable {
StringKeyValueFieldController controller = loader.getController(); StringKeyValueFieldController controller = loader.getController();
controller.setKeyField(key); controller.setKeyField(key);
controller.setValueField(value); controller.setValueField(value);
controller.setChecked(checked);
controllers.add(controller); controllers.add(controller);
controllersCount.set(controllersCount.get() + 1); controllersCount.set(controllersCount.get() + 1);
controller.deleteButton.visibleProperty().bind(Bindings.greaterThan(controllersCount, 1)); controller.deleteButton.visibleProperty().bind(Bindings.greaterThan(controllersCount, 1));
@ -118,6 +120,19 @@ public class HeaderTabController implements Initializable {
headers.put(controller.getHeader().getKey(), controller.getHeader().getValue()); headers.put(controller.getHeader().getKey(), controller.getHeader().getValue());
} }
return headers; return headers;
} }
/**
* Return an ArrayList of the state of all the fields in the Headers tab.
*/
public ArrayList<FieldState> getFieldStates() {
ArrayList<FieldState> states = new ArrayList<>();
for (StringKeyValueFieldController controller : controllers)
states.add(controller.getState());
return states;
}
} }

View file

@ -16,6 +16,8 @@
package com.rohitawate.everest.controllers; package com.rohitawate.everest.controllers;
import com.rohitawate.everest.controllers.state.DashboardState;
import com.rohitawate.everest.controllers.state.FieldState;
import com.rohitawate.everest.misc.Services; import com.rohitawate.everest.misc.Services;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
@ -26,7 +28,6 @@ import javax.ws.rs.core.MediaType;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Map;
import java.util.ResourceBundle; import java.util.ResourceBundle;
public class HistoryItemController implements Initializable { public class HistoryItemController implements Initializable {
@ -35,35 +36,21 @@ public class HistoryItemController implements Initializable {
@FXML @FXML
private Tooltip tooltip; private Tooltip tooltip;
private DashboardState dashboardState; private DashboardState state;
public void setRequestType(String requestType) {
this.requestType.setText(requestType);
}
public void setAddress(String address) {
this.address.setText(address);
}
public String getRequestType() {
return requestType.getText();
}
public String getAddress() {
return address.getText();
}
@Override @Override
public void initialize(URL location, ResourceBundle resources) { public void initialize(URL location, ResourceBundle resources) {
tooltip.textProperty().bind(address.textProperty()); tooltip.textProperty().bind(address.textProperty());
} }
public DashboardState getDashboardState() { public DashboardState getState() {
return dashboardState; return state;
} }
public void setDashboardState(DashboardState dashboardState) { public void setState(DashboardState state) {
this.dashboardState = dashboardState; this.state = state;
this.requestType.setText(state.httpMethod);
this.address.setText(state.target);
} }
public int getRelativityIndex(String searchString) { public int getRelativityIndex(String searchString) {
@ -71,12 +58,12 @@ public class HistoryItemController implements Initializable {
String comparisonString; String comparisonString;
// Checks if matches with target // Checks if matches with target
comparisonString = dashboardState.target.toLowerCase(); comparisonString = state.target.toLowerCase();
if (comparisonString.contains(searchString)) if (comparisonString.contains(searchString))
return 10; return 10;
try { try {
URL url = new URL(dashboardState.target); URL url = new URL(state.target);
// Checks if matches with target's hostname // Checks if matches with target's hostname
comparisonString = url.getHost().toLowerCase(); comparisonString = url.getHost().toLowerCase();
@ -92,55 +79,55 @@ public class HistoryItemController implements Initializable {
} }
// Checks if matches with HTTP method // Checks if matches with HTTP method
comparisonString = dashboardState.httpMethod.toLowerCase(); comparisonString = state.httpMethod.toLowerCase();
if (comparisonString.contains(searchString)) if (comparisonString.contains(searchString))
return 7; return 7;
// Checks for a match in the params // Checks for a match in the params
for (Map.Entry param : dashboardState.params.entrySet()) { for (FieldState state : state.params) {
if (param.getKey().toString().toLowerCase().contains(searchString) || if (state.key.toLowerCase().contains(searchString) ||
param.getKey().toString().toLowerCase().contains(searchString)) state.value.toLowerCase().contains(searchString))
return 5; return 5;
} }
// Checks for a match in the headers // Checks for a match in the headers
for (Map.Entry header : dashboardState.headers.entrySet()) { for (FieldState state : state.headers) {
if (header.getKey().toString().toLowerCase().contains(searchString) || if (state.key.toLowerCase().contains(searchString) ||
header.getValue().toString().toLowerCase().contains(searchString)) state.value.toLowerCase().contains(searchString))
return 6; return 6;
} }
if (dashboardState.httpMethod.equals("POST") || dashboardState.httpMethod.equals("PUT")) { if (state.httpMethod.equals("POST") || state.httpMethod.equals("PUT")) {
switch (dashboardState.contentType) { switch (state.contentType) {
case MediaType.TEXT_PLAIN: case MediaType.TEXT_PLAIN:
case MediaType.APPLICATION_JSON: case MediaType.APPLICATION_JSON:
case MediaType.APPLICATION_XML: case MediaType.APPLICATION_XML:
case MediaType.TEXT_HTML: case MediaType.TEXT_HTML:
case MediaType.APPLICATION_OCTET_STREAM: case MediaType.APPLICATION_OCTET_STREAM:
// Checks for match in rawBody of the request // Checks for match in rawBody of the request
comparisonString = dashboardState.rawBody.toLowerCase(); comparisonString = state.rawBody.toLowerCase();
if (comparisonString.contains(searchString)) if (comparisonString.contains(searchString))
return 8; return 8;
break; break;
case MediaType.APPLICATION_FORM_URLENCODED: case MediaType.APPLICATION_FORM_URLENCODED:
// Checks for match in string tuples // Checks for match in string tuples
for (Map.Entry tuple : dashboardState.urlStringTuples.entrySet()) { for (FieldState state : state.urlStringTuples) {
if (tuple.getKey().toString().toLowerCase().contains(searchString) || if (state.key.toLowerCase().contains(searchString) ||
tuple.getValue().toString().toLowerCase().contains(searchString)) state.value.toLowerCase().contains(searchString))
return 8; return 8;
} }
break; break;
case MediaType.MULTIPART_FORM_DATA: case MediaType.MULTIPART_FORM_DATA:
// Checks for match in string and file tuples // Checks for match in string and file tuples
for (Map.Entry tuple : dashboardState.formStringTuples.entrySet()) { for (FieldState state : state.formStringTuples) {
if (tuple.getKey().toString().toLowerCase().contains(searchString) || if (state.key.toLowerCase().contains(searchString) ||
tuple.getValue().toString().toLowerCase().contains(searchString)) state.value.toLowerCase().contains(searchString))
return 8; return 8;
} }
for (Map.Entry tuple : dashboardState.formFileTuples.entrySet()) { for (FieldState state : state.formFileTuples) {
if (tuple.getKey().toString().toLowerCase().contains(searchString) || if (state.key.toLowerCase().contains(searchString) ||
tuple.getValue().toString().toLowerCase().contains(searchString)) state.value.toLowerCase().contains(searchString))
return 8; return 8;
} }
break; break;

View file

@ -18,6 +18,7 @@ package com.rohitawate.everest.controllers;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import com.rohitawate.everest.controllers.state.DashboardState;
import com.rohitawate.everest.misc.EverestUtilities; import com.rohitawate.everest.misc.EverestUtilities;
import com.rohitawate.everest.misc.KeyMap; import com.rohitawate.everest.misc.KeyMap;
import com.rohitawate.everest.misc.Services; import com.rohitawate.everest.misc.Services;
@ -94,7 +95,7 @@ public class HomeWindowController implements Initializable {
if (searchResults.size() != 0) { if (searchResults.size() != 0) {
for (HistoryItemController controller : searchResults) { for (HistoryItemController controller : searchResults) {
addSearchItem(controller.getDashboardState()); addSearchItem(controller.getState());
} }
} else { } else {
searchFailedLayer.setVisible(true); searchFailedLayer.setVisible(true);
@ -307,11 +308,7 @@ public class HomeWindowController implements Initializable {
Parent historyItem = loader.load(); Parent historyItem = loader.load();
controller = loader.getController(); controller = loader.getController();
controller.setState(state);
controller.setRequestType(state.httpMethod);
controller.setAddress(state.target);
controller.setDashboardState(state);
if (appendToStart) if (appendToStart)
layer.getChildren().add(0, historyItem); layer.getChildren().add(0, historyItem);

View file

@ -18,6 +18,7 @@ package com.rohitawate.everest.controllers;
import com.jfoenix.controls.JFXButton; import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXCheckBox; import com.jfoenix.controls.JFXCheckBox;
import com.rohitawate.everest.controllers.state.FieldState;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
@ -91,4 +92,12 @@ public class StringKeyValueFieldController implements Initializable {
public boolean isValueFieldEmpty() { public boolean isValueFieldEmpty() {
return valueField.getText().isEmpty(); return valueField.getText().isEmpty();
} }
public FieldState getState() {
return new FieldState(keyField.getText(), valueField.getText(), checkBox.isSelected());
}
public void setChecked(boolean checked) {
checkBox.setSelected(checked);
}
} }

View file

@ -16,6 +16,7 @@
package com.rohitawate.everest.controllers; package com.rohitawate.everest.controllers;
import com.rohitawate.everest.controllers.state.FieldState;
import com.rohitawate.everest.misc.Services; import com.rohitawate.everest.misc.Services;
import com.rohitawate.everest.misc.ThemeManager; import com.rohitawate.everest.misc.ThemeManager;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
@ -51,20 +52,25 @@ public class URLTabController implements Initializable {
addField(); addField();
} }
public void addField(FieldState state) {
addField(state.key, state.value, null, state.checked);
}
private void addField() { private void addField() {
addField("", "", null); addField("", "", null, false);
} }
public void addField(String key, String value) { public void addField(String key, String value) {
addField(key, value, null); addField(key, value, null, false);
} }
@FXML @FXML
private void addField(ActionEvent event) { private void addField(ActionEvent event) {
addField("", "", event); addField("", "", event, false);
} }
private void addField(String key, String value, ActionEvent event) { private void addField(String key, String value, ActionEvent event, boolean checked) {
/* /*
Re-uses previous field if it is empty, Re-uses previous field if it is empty,
else loads a new one. else loads a new one.
@ -115,4 +121,17 @@ public class URLTabController implements Initializable {
} }
return tuples; return tuples;
} }
/**
* Return an ArrayList of the state of all the fields in the URL-encoded tab.
*/
public ArrayList<FieldState> getFieldStates() {
ArrayList<FieldState> states = new ArrayList<>();
for (StringKeyValueFieldController controller : controllers)
states.add(controller.getState());
return states;
}
} }

View file

@ -14,9 +14,9 @@
* limitations under the License. * limitations under the License.
*/ */
package com.rohitawate.everest.controllers; package com.rohitawate.everest.controllers.state;
import java.util.HashMap; import java.util.ArrayList;
/** /**
* Convenience class to abstract the state of the application. * Convenience class to abstract the state of the application.
@ -24,13 +24,23 @@ import java.util.HashMap;
public class DashboardState { public class DashboardState {
public String target; public String target;
public String httpMethod; public String httpMethod;
public HashMap<String, String> params; public ArrayList<FieldState> params;
public HashMap<String, String> headers; public ArrayList<FieldState> headers;
// Determined from the active tab within the Body tab
public String contentType; public String contentType;
// Body and content-type of requests with raw bodies
public String rawBody; public String rawBody;
public String rawBodyType; public String rawBodyType;
public HashMap<String, String> urlStringTuples;
public HashMap<String, String> formStringTuples; // Tuples of URL-encoded requests
public HashMap<String, String> formFileTuples; public ArrayList<FieldState> urlStringTuples;
// String and file tuples of multipart-form requests
public ArrayList<FieldState> formStringTuples;
public ArrayList<FieldState> formFileTuples;
// File path of application/octet-stream requests
public String binaryFilePath; public String binaryFilePath;
} }

View file

@ -0,0 +1,51 @@
/*
* 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.everest.controllers.state;
import java.util.Objects;
/**
* Convenience class to represent the state of StringKeyValueFieldController and FileKeyValueField for
* application state maintenance logic.
*/
public class FieldState {
public String key;
public String value;
public boolean checked;
public FieldState() {
this.key = null;
this.value = null;
this.checked = false;
}
public FieldState(String key, String value, boolean checked) {
this.key = key;
this.value = value;
this.checked = checked;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
FieldState that = (FieldState) o;
return checked == that.checked &&
Objects.equals(key, that.key) &&
Objects.equals(value, that.value);
}
}

View file

@ -18,7 +18,8 @@ package com.rohitawate.everest.history;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.rohitawate.everest.controllers.DashboardState; import com.rohitawate.everest.controllers.state.DashboardState;
import com.rohitawate.everest.controllers.state.FieldState;
import com.rohitawate.everest.misc.EverestUtilities; import com.rohitawate.everest.misc.EverestUtilities;
import com.rohitawate.everest.misc.Services; import com.rohitawate.everest.misc.Services;
import com.rohitawate.everest.settings.Settings; import com.rohitawate.everest.settings.Settings;
@ -31,9 +32,7 @@ import java.sql.*;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map.Entry;
public class HistoryManager { public class HistoryManager {
private Connection conn; private Connection conn;
@ -178,8 +177,8 @@ public class HistoryManager {
return history; return history;
} }
private HashMap<String, String> getRequestHeaders(int requestID) { private ArrayList<FieldState> getRequestHeaders(int requestID) {
HashMap<String, String> headers = new HashMap<>(); ArrayList<FieldState> headers = new ArrayList<>();
try { try {
PreparedStatement statement = PreparedStatement statement =
@ -189,10 +188,12 @@ public class HistoryManager {
ResultSet RS = statement.executeQuery(); ResultSet RS = statement.executeQuery();
String key, value; String key, value;
boolean checked;
while (RS.next()) { while (RS.next()) {
key = RS.getString("Key"); key = RS.getString("Key");
value = RS.getString("Value"); value = RS.getString("Value");
headers.put(key, value); checked = RS.getBoolean("Checked");
headers.add(new FieldState(key, value, checked));
} }
} catch (SQLException e) { } catch (SQLException e) {
Services.loggingService.logWarning("Database error.", e, LocalDateTime.now()); Services.loggingService.logWarning("Database error.", e, LocalDateTime.now());
@ -205,11 +206,11 @@ public class HistoryManager {
* @param type Type of tuples needed ('String', 'File' or 'Param') * @param type Type of tuples needed ('String', 'File' or 'Param')
* @return tuples - Map of tuples of corresponding type * @return tuples - Map of tuples of corresponding type
*/ */
private HashMap<String, String> getTuples(int requestID, String type) { private ArrayList<FieldState> getTuples(int requestID, String type) {
if (!(type.equals("String") || type.equals("File") || type.equals("Param"))) if (!(type.equals("String") || type.equals("File") || type.equals("Param")))
return null; return null;
HashMap<String, String> tuples = new HashMap<>(); ArrayList<FieldState> tuples = new ArrayList<>();
try { try {
PreparedStatement statement = PreparedStatement statement =
@ -220,14 +221,17 @@ public class HistoryManager {
ResultSet RS = statement.executeQuery(); ResultSet RS = statement.executeQuery();
String key, value; String key, value;
boolean checked;
while (RS.next()) { while (RS.next()) {
key = RS.getString("Key"); key = RS.getString("Key");
value = RS.getString("Value"); value = RS.getString("Value");
tuples.put(key, value); checked = RS.getBoolean("Checked");
tuples.add(new FieldState(key, value, checked));
} }
} catch (SQLException e) { } catch (SQLException e) {
Services.loggingService.logWarning("Database error.", e, LocalDateTime.now()); Services.loggingService.logWarning("Database error.", e, LocalDateTime.now());
} }
return tuples; return tuples;
} }
@ -256,16 +260,16 @@ public class HistoryManager {
if (lastRequestID == -1) if (lastRequestID == -1)
return false; return false;
HashMap<String, String> map; ArrayList<FieldState> states;
// Checks for new or modified headers // Checks for new or modified headers
map = getRequestHeaders(lastRequestID); states = getRequestHeaders(lastRequestID);
if (!areMapsIdentical(map, newState.headers)) if (!areListsEqual(states, newState.headers))
return false; return false;
// Checks for new or modified params // Checks for new or modified params
map = getTuples(lastRequestID, "Param"); states = getTuples(lastRequestID, "Param");
if (!areMapsIdentical(map, newState.params)) if (!areListsEqual(states, newState.params))
return false; return false;
if (!(newState.httpMethod.equals("GET") || newState.httpMethod.equals("DELETE"))) { if (!(newState.httpMethod.equals("GET") || newState.httpMethod.equals("DELETE"))) {
@ -287,16 +291,16 @@ public class HistoryManager {
break; break;
case MediaType.APPLICATION_FORM_URLENCODED: case MediaType.APPLICATION_FORM_URLENCODED:
// Checks for new or modified string tuples // Checks for new or modified string tuples
map = getTuples(lastRequestID, "String"); states = getTuples(lastRequestID, "String");
return areMapsIdentical(map, newState.urlStringTuples); return areListsEqual(states, newState.urlStringTuples);
case MediaType.MULTIPART_FORM_DATA: case MediaType.MULTIPART_FORM_DATA:
// Checks for new or modified string tuples // Checks for new or modified string tuples
map = getTuples(lastRequestID, "String"); states = getTuples(lastRequestID, "String");
boolean stringComparison = areMapsIdentical(map, newState.formStringTuples); boolean stringComparison = areListsEqual(states, newState.formStringTuples);
// Checks for new or modified file tuples // Checks for new or modified file tuples
map = getTuples(lastRequestID, "File"); states = getTuples(lastRequestID, "File");
boolean fileComparison = areMapsIdentical(map, newState.formFileTuples); boolean fileComparison = areListsEqual(states, newState.formFileTuples);
return stringComparison && fileComparison; return stringComparison && fileComparison;
} }
@ -313,19 +317,19 @@ public class HistoryManager {
return true; return true;
} }
private boolean areMapsIdentical(HashMap<String, String> firstMap, HashMap<String, String> secondMap) { private boolean areListsEqual(ArrayList<FieldState> firstList, ArrayList<FieldState> secondList) {
if (firstMap == null && secondMap == null) if (firstList == null && secondList == null)
return true; return true;
if ((firstMap == null && secondMap != null) || if ((firstList == null && secondList != null) ||
(firstMap != null && secondMap == null)) (firstList != null && secondList == null))
return false; return false;
for (Entry entry : secondMap.entrySet()) { for (FieldState state : secondList) {
if (!firstMap.containsKey(entry.getKey().toString()) || if (!firstList.contains(state))
!firstMap.get(entry.getKey().toString()).equals(entry.getValue().toString()))
return false; return false;
} }
return true; return true;
} }
@ -355,10 +359,12 @@ public class HistoryManager {
if (state.headers.size() > 0) { if (state.headers.size() > 0) {
// Saves request headers // Saves request headers
statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveHeader").toString())); statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveHeader").toString()));
for (Entry entry : state.headers.entrySet()) {
for (FieldState fieldState : state.headers) {
statement.setInt(1, requestID); statement.setInt(1, requestID);
statement.setString(2, entry.getKey().toString()); statement.setString(2, fieldState.key);
statement.setString(3, entry.getValue().toString()); statement.setString(3, fieldState.value);
statement.setInt(4, fieldState.checked ? 1 : 0);
statement.executeUpdate(); statement.executeUpdate();
} }
@ -367,11 +373,12 @@ public class HistoryManager {
if (state.params.size() > 0) { if (state.params.size() > 0) {
// Saves request parameters // Saves request parameters
statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveTuple").toString())); statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveTuple").toString()));
for (Entry entry : state.params.entrySet()) { for (FieldState fieldState : state.params) {
statement.setInt(1, requestID); statement.setInt(1, requestID);
statement.setString(2, "Param"); statement.setString(2, "Param");
statement.setString(3, entry.getKey().toString()); statement.setString(3, fieldState.key);
statement.setString(4, entry.getValue().toString()); statement.setString(4, fieldState.value);
statement.setInt(5, fieldState.checked ? 1 : 0);
statement.executeUpdate(); statement.executeUpdate();
} }
@ -400,13 +407,14 @@ public class HistoryManager {
break; break;
case MediaType.APPLICATION_FORM_URLENCODED: case MediaType.APPLICATION_FORM_URLENCODED:
if (state.urlStringTuples.size() > 0) { if (state.urlStringTuples.size() > 0) {
for (Entry<String, String> entry : state.urlStringTuples.entrySet()) { for (FieldState fieldState : state.urlStringTuples) {
// Saves the string tuples // Saves the string tuples
statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveTuple").toString())); statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveTuple").toString()));
statement.setInt(1, requestID); statement.setInt(1, requestID);
statement.setString(2, "String"); statement.setString(2, "String");
statement.setString(3, entry.getKey()); statement.setString(3, fieldState.key);
statement.setString(4, entry.getValue()); statement.setString(4, fieldState.value);
statement.setInt(5, fieldState.checked ? 1 : 0);
statement.executeUpdate(); statement.executeUpdate();
} }
@ -414,26 +422,28 @@ public class HistoryManager {
break; break;
case MediaType.MULTIPART_FORM_DATA: case MediaType.MULTIPART_FORM_DATA:
if (state.formStringTuples.size() > 0) { if (state.formStringTuples.size() > 0) {
for (Entry<String, String> entry : state.formStringTuples.entrySet()) { for (FieldState fieldState : state.formStringTuples) {
// Saves the string tuples // Saves the string tuples
statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveTuple").toString())); statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveTuple").toString()));
statement.setInt(1, requestID); statement.setInt(1, requestID);
statement.setString(2, "String"); statement.setString(2, "String");
statement.setString(3, entry.getKey()); statement.setString(3, fieldState.key);
statement.setString(4, entry.getValue()); statement.setString(4, fieldState.value);
statement.setInt(5, fieldState.checked ? 1 : 0);
statement.executeUpdate(); statement.executeUpdate();
} }
} }
if (state.formFileTuples.size() > 0) { if (state.formFileTuples.size() > 0) {
for (Entry<String, String> entry : state.formFileTuples.entrySet()) { for (FieldState fieldState : state.formFileTuples) {
// Saves the file tuples // Saves the string tuples
statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveTuple").toString())); statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveTuple").toString()));
statement.setInt(1, requestID); statement.setInt(1, requestID);
statement.setString(2, "File"); statement.setString(2, "File");
statement.setString(3, entry.getKey()); statement.setString(3, fieldState.key);
statement.setString(4, entry.getValue()); statement.setString(4, fieldState.value);
statement.setInt(5, fieldState.checked ? 1 : 0);
statement.executeUpdate(); statement.executeUpdate();
} }

View file

@ -1,14 +1,14 @@
{ {
"createRequestsTable": "CREATE TABLE IF NOT EXISTS Requests(ID INTEGER PRIMARY KEY, Type TEXT NOT NULL, Target TEXT NOT NULL, Date TEXT NOT NULL)", "createRequestsTable": "CREATE TABLE IF NOT EXISTS Requests(ID INTEGER PRIMARY KEY, Type TEXT NOT NULL, Target TEXT NOT NULL, Date TEXT NOT NULL)",
"createHeadersTable": "CREATE TABLE IF NOT EXISTS Headers(RequestID INTEGER, Key TEXT NOT NULL, Value TEXT NOT NULL, FOREIGN KEY(RequestID) REFERENCES Requests(ID))", "createHeadersTable": "CREATE TABLE IF NOT EXISTS Headers(RequestID INTEGER, Key TEXT NOT NULL, Value TEXT NOT NULL, Checked INTEGER CHECK (Checked IN (0, 1)), FOREIGN KEY(RequestID) REFERENCES Requests(ID))",
"createRequestContentMapTable": "CREATE TABLE IF NOT EXISTS RequestContentMap(RequestID INTEGER, ContentType TEXT NOT NULL, FOREIGN KEY(RequestID) REFERENCES Requests(ID))", "createRequestContentMapTable": "CREATE TABLE IF NOT EXISTS RequestContentMap(RequestID INTEGER, ContentType TEXT NOT NULL, FOREIGN KEY(RequestID) REFERENCES Requests(ID))",
"createBodiesTable": "CREATE TABLE IF NOT EXISTS Bodies(RequestID INTEGER, Body TEXT NOT NULL, FOREIGN KEY(RequestID) REFERENCES Requests(ID))", "createBodiesTable": "CREATE TABLE IF NOT EXISTS Bodies(RequestID INTEGER, Body TEXT NOT NULL, FOREIGN KEY(RequestID) REFERENCES Requests(ID))",
"createTuplesTable": "CREATE TABLE IF NOT EXISTS Tuples(RequestID INTEGER, TupleType TEXT NOT NULL, Key TEXT NOT NULL, Value TEXT NOT NULL, FOREIGN KEY(RequestID) REFERENCES Requests(ID))", "createTuplesTable": "CREATE TABLE IF NOT EXISTS Tuples(RequestID INTEGER, TupleType TEXT NOT NULL, Key TEXT NOT NULL, Value TEXT NOT NULL, Checked INTEGER CHECK (Checked IN (0, 1)), FOREIGN KEY(RequestID) REFERENCES Requests(ID))",
"saveRequest": "INSERT INTO Requests(Type, Target, Date) VALUES(?, ?, ?)", "saveRequest": "INSERT INTO Requests(Type, Target, Date) VALUES(?, ?, ?)",
"saveHeader": "INSERT INTO Headers(RequestID, Key, Value) VALUES(?, ?, ?)", "saveHeader": "INSERT INTO Headers(RequestID, Key, Value, Checked) VALUES(?, ?, ?, ?)",
"saveRequestContentPair": "INSERT INTO RequestContentMap(RequestID, ContentType) VALUES(?, ?)", "saveRequestContentPair": "INSERT INTO RequestContentMap(RequestID, ContentType) VALUES(?, ?)",
"saveBody": "INSERT INTO Bodies(RequestID, Body) VALUES(?, ?)", "saveBody": "INSERT INTO Bodies(RequestID, Body) VALUES(?, ?)",
"saveTuple": "INSERT INTO Tuples(RequestID, TupleType, Key, Value) VALUES(?, ?, ?, ?)", "saveTuple": "INSERT INTO Tuples(RequestID, TupleType, Key, Value, Checked) VALUES(?, ?, ?, ?, ?)",
"selectRecentRequests": "SELECT * FROM Requests WHERE Requests.Date > ?", "selectRecentRequests": "SELECT * FROM Requests WHERE Requests.Date > ?",
"selectRequestHeaders": "SELECT * FROM Headers WHERE RequestID == ?", "selectRequestHeaders": "SELECT * FROM Headers WHERE RequestID == ?",
"selectRequestContentType": "SELECT ContentType FROM RequestContentMap WHERE RequestID == ?", "selectRequestContentType": "SELECT ContentType FROM RequestContentMap WHERE RequestID == ?",