diff --git a/src/main/java/com/rohitawate/everest/controllers/BodyTabController.java b/src/main/java/com/rohitawate/everest/controllers/BodyTabController.java index 05a173e..fd34aa9 100644 --- a/src/main/java/com/rohitawate/everest/controllers/BodyTabController.java +++ b/src/main/java/com/rohitawate/everest/controllers/BodyTabController.java @@ -63,10 +63,6 @@ public class BodyTabController implements Initializable { FormDataTabController formDataTabController; URLTabController urlTabController; - public enum BodyTab { - FORM, URL, RAW, BINARY - } - @Override public void initialize(URL location, ResourceBundle resources) { rawInputTypeBox.getItems().addAll( @@ -152,18 +148,18 @@ public class BodyTabController implements Initializable { state.rawBodyBoxValue = MediaType.TEXT_PLAIN; } - if (rawTab.isSelected()) { - state.visibleBodyTab = BodyTab.RAW; - state.contentType = state.rawBodyBoxValue; - } else if (formTab.isSelected()) { - state.visibleBodyTab = BodyTab.FORM; - state.contentType = MediaType.MULTIPART_FORM_DATA; - } else if (urlTab.isSelected()) { - state.visibleBodyTab = BodyTab.URL; - state.contentType = MediaType.APPLICATION_FORM_URLENCODED; - } else { - state.visibleBodyTab = BodyTab.BINARY; - state.contentType = MediaType.APPLICATION_OCTET_STREAM; + switch (bodyTabPane.getSelectionModel().getSelectedIndex()) { + case 1: + state.contentType = MediaType.APPLICATION_FORM_URLENCODED; + break; + case 2: + state.contentType = state.rawBodyBoxValue; + break; + case 3: + state.contentType = MediaType.APPLICATION_OCTET_STREAM; + break; + default: + state.contentType = MediaType.MULTIPART_FORM_DATA; } return state; @@ -190,24 +186,26 @@ public class BodyTabController implements Initializable { setRawTab(state); filePathField.setText(state.binaryFilePath); - int tab; - if (state.visibleBodyTab != null) { - switch (state.visibleBodyTab) { - case BINARY: + int tab = 0; + if (state.contentType != null) { + switch (state.contentType) { + case MediaType.APPLICATION_OCTET_STREAM: tab = 3; break; - case URL: + case MediaType.APPLICATION_FORM_URLENCODED: tab = 1; break; - case RAW: + case MediaType.APPLICATION_JSON: + case MediaType.APPLICATION_XML: + case MediaType.TEXT_HTML: + case MediaType.TEXT_PLAIN: tab = 2; break; default: tab = 0; } - } else { - tab = 0; } + bodyTabPane.getSelectionModel().select(tab); } diff --git a/src/main/java/com/rohitawate/everest/history/HistoryManager.java b/src/main/java/com/rohitawate/everest/history/HistoryManager.java index 0a8db90..5a7a5c3 100644 --- a/src/main/java/com/rohitawate/everest/history/HistoryManager.java +++ b/src/main/java/com/rohitawate/everest/history/HistoryManager.java @@ -74,10 +74,6 @@ public class HistoryManager { conn.prepareStatement(EverestUtilities.trimString(queries.get("createRequestsTable").toString())); statement.execute(); - statement = - conn.prepareStatement(EverestUtilities.trimString(queries.get("createHeadersTable").toString())); - statement.execute(); - statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("createRequestContentMapTable").toString())); statement.execute(); @@ -89,12 +85,15 @@ public class HistoryManager { statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("createTuplesTable").toString())); statement.execute(); - } - // Method is synchronized to allow only one database transaction at a time. + statement = + conn.prepareStatement(EverestUtilities.trimString(queries.get("createFilePathsTable").toString())); + statement.execute(); + } /** * Saves the request to the database if it is not identical to one made exactly before it. + * Method is synchronized to allow only one database transaction at a time. * * @param state - The state of the Dashboard while making the request. */ @@ -129,33 +128,36 @@ public class HistoryManager { state.target = resultSet.getString("Target"); int requestID = resultSet.getInt("ID"); - state.headers = getRequestHeaders(requestID); + state.headers = getTuples(requestID, "Header"); state.params = getTuples(requestID, "Param"); state.httpMethod = resultSet.getString("Type"); if (!(state.httpMethod.equals(HTTPConstants.GET) || state.httpMethod.equals(HTTPConstants.DELETE))) { // Retrieves request body ContentType for querying corresponding table - statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("selectRequestContentType").toString())); - statement.setInt(1, requestID); - - ResultSet RS = statement.executeQuery(); - - String contentType = ""; - if (RS.next()) - contentType = RS.getString("ContentType"); + String contentType = getRequestContentType(requestID); state.contentType = contentType; statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("selectRequestBody").toString())); statement.setInt(1, requestID); + ResultSet RS = statement.executeQuery(); + + if (RS.next()) { + state.rawBody = RS.getString("Body"); + state.rawBodyBoxValue = RS.getString("Type"); + } + + statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("selectFilePath").toString())); + statement.setInt(1, requestID); + RS = statement.executeQuery(); if (RS.next()) - state.rawBody = RS.getString("Body"); + state.binaryFilePath = RS.getString("Path"); - state.urlStringTuples = getTuples(requestID, "String"); - state.formStringTuples = getTuples(requestID, "String"); + state.urlStringTuples = getTuples(requestID, "URLString"); + state.formStringTuples = getTuples(requestID, "FormString"); state.formFileTuples = getTuples(requestID, "File"); } @@ -164,31 +166,22 @@ public class HistoryManager { } catch (SQLException e) { LoggingService.logWarning("Database error.", e, LocalDateTime.now()); } + return history; } - private ArrayList getRequestHeaders(int requestID) { - ArrayList headers = new ArrayList<>(); + private String getRequestContentType(int requestID) throws SQLException { + String contentType = null; - try { - PreparedStatement statement = - conn.prepareStatement(EverestUtilities.trimString(queries.get("selectRequestHeaders").toString())); - statement.setInt(1, requestID); + statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("selectRequestContentType").toString())); + statement.setInt(1, requestID); - ResultSet RS = statement.executeQuery(); + ResultSet RS = statement.executeQuery(); - String key, value; - boolean checked; - while (RS.next()) { - key = RS.getString("Key"); - value = RS.getString("Value"); - checked = RS.getBoolean("Checked"); - headers.add(new FieldState(key, value, checked)); - } - } catch (SQLException e) { - LoggingService.logWarning("Database error.", e, LocalDateTime.now()); - } - return headers; + if (RS.next()) + contentType = RS.getString("ContentType"); + + return contentType; } /** @@ -197,14 +190,15 @@ public class HistoryManager { * @return tuples - Map of tuples of corresponding type */ private ArrayList getTuples(int requestID, String type) { - if (!(type.equals("String") || type.equals("File") || type.equals("Param"))) + if (!(type.equals("FormString") || type.equals("URLString") || + type.equals("File") || type.equals("Param") || type.equals("Header"))) return null; ArrayList tuples = new ArrayList<>(); try { PreparedStatement statement = - conn.prepareStatement(EverestUtilities.trimString(queries.get("selectTuples").toString())); + conn.prepareStatement(EverestUtilities.trimString(queries.get("selectTuplesByType").toString())); statement.setInt(1, requestID); statement.setString(2, type); @@ -253,7 +247,7 @@ public class HistoryManager { ArrayList states; // Checks for new or modified headers - states = getRequestHeaders(lastRequestID); + states = getTuples(lastRequestID, "Header"); if (!areListsEqual(states, newState.headers)) return false; @@ -286,18 +280,23 @@ public class HistoryManager { RS = statement.executeQuery(); - if (RS.next()) - if (!RS.getString("Body").equals(newState.rawBody)) + while (RS.next()) { + if (!(RS.getString("Type").equals("Raw") && + RS.getString("Body").equals(newState.rawBody))) return false; + else if (!(RS.getString("Type").equals("FilePath") && + RS.getString("Body").equals(newState.binaryFilePath))) + return false; + } break; case MediaType.APPLICATION_FORM_URLENCODED: // Checks for new or modified string tuples - states = getTuples(lastRequestID, "String"); + states = getTuples(lastRequestID, "URLString"); return areListsEqual(states, newState.urlStringTuples); case MediaType.MULTIPART_FORM_DATA: // Checks for new or modified string tuples - states = getTuples(lastRequestID, "String"); + states = getTuples(lastRequestID, "FormString"); boolean stringComparison = areListsEqual(states, newState.formStringTuples); // Checks for new or modified file tuples @@ -320,12 +319,11 @@ public class HistoryManager { } private static boolean areListsEqual(ArrayList firstList, ArrayList secondList) { - if (firstList == null && secondList == null) - return true; + if (firstList == null && secondList == null) return true; - if ((firstList == null && secondList != null) || - (firstList != null && secondList == null)) - return false; + if ((firstList == null && secondList != null) || (firstList != null && secondList == null)) return false; + + if (firstList.size() != secondList.size()) return false; for (FieldState state : secondList) { if (!state.isEmpty() && state.checked && !firstList.contains(state)) @@ -347,7 +345,6 @@ public class HistoryManager { statement.setString(1, state.httpMethod); statement.setString(2, state.target); statement.setString(3, LocalDate.now().toString()); - statement.executeUpdate(); // Get latest RequestID to insert into Headers table @@ -358,23 +355,7 @@ public class HistoryManager { if (RS.next()) requestID = RS.getInt("MaxID"); - if (state.headers.size() > 0) { - // Saves request headers - statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveHeader").toString())); - - for (FieldState fieldState : state.headers) { - if (!fieldState.isEmpty() && fieldState.checked) { - statement.setInt(1, requestID); - statement.setString(2, fieldState.key); - statement.setString(3, fieldState.value); - statement.setInt(4, fieldState.checked ? 1 : 0); - - statement.executeUpdate(); - } - } - } - - // Saves request parameters + saveTuple(state.headers, "Header", requestID); saveTuple(state.params, "Param", requestID); if (!(state.httpMethod.equals(HTTPConstants.GET) || state.httpMethod.equals(HTTPConstants.DELETE))) { @@ -382,16 +363,21 @@ public class HistoryManager { statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveRequestContentPair").toString())); statement.setInt(1, requestID); statement.setString(2, state.contentType); - statement.executeUpdate(); statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveBody").toString())); statement.setInt(1, requestID); statement.setString(2, state.rawBody); + statement.setString(3, state.rawBodyBoxValue); statement.executeUpdate(); - saveTuple(state.urlStringTuples, "String", requestID); - saveTuple(state.formStringTuples, "String", requestID); + statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveFilePath").toString())); + statement.setInt(1, requestID); + statement.setString(2, state.binaryFilePath); + statement.executeUpdate(); + + saveTuple(state.urlStringTuples, "URLString", requestID); + saveTuple(state.formStringTuples, "FormString", requestID); saveTuple(state.formFileTuples, "File", requestID); } } catch (SQLException e) { @@ -401,21 +387,21 @@ public class HistoryManager { private void saveTuple(ArrayList tuples, String tupleType, int requestID) { if (tuples.size() > 0) { - for (FieldState fieldState : tuples) { - if (!fieldState.isEmpty() && fieldState.checked) { - try { + try { + for (FieldState fieldState : tuples) { + if (!fieldState.isEmpty() && fieldState.checked) { statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveTuple").toString())); statement.setInt(1, requestID); statement.setString(2, tupleType); statement.setString(3, fieldState.key); statement.setString(4, fieldState.value); statement.setInt(5, fieldState.checked ? 1 : 0); - - statement.executeUpdate(); - } catch (SQLException e) { - LoggingService.logWarning("Database error.", e, LocalDateTime.now()); + statement.addBatch(); } } + statement.executeBatch(); + } catch (SQLException e) { + LoggingService.logSevere("Database error.", e, LocalDateTime.now()); } } } diff --git a/src/main/java/com/rohitawate/everest/state/ComposerState.java b/src/main/java/com/rohitawate/everest/state/ComposerState.java index d2b4f35..6792417 100644 --- a/src/main/java/com/rohitawate/everest/state/ComposerState.java +++ b/src/main/java/com/rohitawate/everest/state/ComposerState.java @@ -16,17 +16,14 @@ package com.rohitawate.everest.state; -import com.rohitawate.everest.controllers.BodyTabController.BodyTab; import com.rohitawate.everest.models.requests.HTTPConstants; import java.util.ArrayList; /** - * Convenience class to abstract the state of the application. + * Represents the state of the Composer. */ public class ComposerState { - public BodyTab visibleBodyTab; - public String target; public String httpMethod; diff --git a/src/main/resources/sql/Queries.json b/src/main/resources/sql/Queries.json index e17bec5..024e518 100644 --- a/src/main/resources/sql/Queries.json +++ b/src/main/resources/sql/Queries.json @@ -1,18 +1,18 @@ { "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, 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))", - "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, Checked INTEGER CHECK (Checked IN (0, 1)), FOREIGN KEY(RequestID) REFERENCES Requests(ID))", + "createBodiesTable": "CREATE TABLE IF NOT EXISTS Bodies(RequestID INTEGER, Type TEXT NOT NULL CHECK(Type IN ('application/json', 'application/xml', 'text/html', 'text/plain')), Body TEXT NOT NULL, FOREIGN KEY(RequestID) REFERENCES Requests(ID))", + "createFilePathsTable": "CREATE TABLE IF NOT EXISTS FilePaths(RequestID INTEGER, Path TEXT NOT NULL, FOREIGN KEY(RequestID) REFERENCES Requests(ID))", + "createTuplesTable": "CREATE TABLE IF NOT EXISTS Tuples(RequestID INTEGER, Type TEXT NOT NULL CHECK(Type IN ('Header', 'Param', 'URLString', 'FormString', 'File')), 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(?, ?, ?)", - "saveHeader": "INSERT INTO Headers(RequestID, Key, Value, Checked) VALUES(?, ?, ?, ?)", "saveRequestContentPair": "INSERT INTO RequestContentMap(RequestID, ContentType) VALUES(?, ?)", - "saveBody": "INSERT INTO Bodies(RequestID, Body) VALUES(?, ?)", - "saveTuple": "INSERT INTO Tuples(RequestID, TupleType, Key, Value, Checked) VALUES(?, ?, ?, ?, ?)", + "saveBody": "INSERT INTO Bodies(RequestID, Body, Type) VALUES(?, ?, ?)", + "saveFilePath": "INSERT INTO FilePaths(RequestID, Path) VALUES(?, ?)", + "saveTuple": "INSERT INTO Tuples(RequestID, Type, Key, Value, Checked) VALUES(?, ?, ?, ?, ?)", "selectRecentRequests": "SELECT * FROM Requests WHERE Requests.Date > ?", - "selectRequestHeaders": "SELECT * FROM Headers WHERE RequestID == ?", "selectRequestContentType": "SELECT ContentType FROM RequestContentMap WHERE RequestID == ?", - "selectRequestBody": "SELECT Body FROM Bodies WHERE RequestID == ?", - "selectTuples": "SELECT * FROM Tuples WHERE RequestID == ? AND TupleType == ?", + "selectRequestBody": "SELECT Body, Type FROM Bodies WHERE RequestID == ?", + "selectFilePath": "SELECT Path FROM FilePaths WHERE RequestID == ?", + "selectTuplesByType": "SELECT * FROM Tuples WHERE RequestID == ? AND Type == ?", "selectMostRecentRequest": "SELECT * FROM Requests ORDER BY ID DESC LIMIT 1" } \ No newline at end of file