Project-wide cleanup and optimizations

This commit is contained in:
Rohit Awate 2018-07-04 19:23:31 +05:30
parent ca6bcabdb9
commit f1ca82d61c
No known key found for this signature in database
GPG key ID: 1051D7B79CF2EE25
15 changed files with 579 additions and 617 deletions

31
.gitignore vendored
View file

@ -1,16 +1,17 @@
/target/ /target/
*.iml *.iml
.idea/ .idea/
classes/ classes/
src/main/java/META-INF/ src/main/java/META-INF/
dependency-reduced-pom.xml dependency-reduced-pom.xml
# Hides Eclipse Artifacts # Hides Eclipse Artifacts
.settings/ .settings/
.classpath .classpath
.project .project
/BugReporter/src/META-INF/ /BugReporter/src/META-INF/
BugReporter/src/META-INF/ BugReporter/src/META-INF/
Everest/ Everest/
out/ out/
BugReporter.jar

View file

@ -15,7 +15,6 @@
*/ */
package com.rohitawate.everest; package com.rohitawate.everest;
import com.rohitawate.everest.misc.EverestUtilities;
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 com.rohitawate.everest.settings.SettingsLoader; import com.rohitawate.everest.settings.SettingsLoader;
@ -51,8 +50,6 @@ public class Main extends Application {
dashboardStage.setScene(new Scene(homeWindow)); dashboardStage.setScene(new Scene(homeWindow));
dashboardStage.setTitle("Everest"); dashboardStage.setTitle("Everest");
dashboardStage.show(); dashboardStage.show();
EverestUtilities.createBugReporter();
} }
public static void main(String args[]) { public static void main(String args[]) {

View file

@ -1,186 +0,0 @@
package com.rohitawate.everest.controllers;
import java.io.IOException;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.concurrent.ExecutionException;
import com.jfoenix.controls.JFXButton;
import com.rohitawate.everest.misc.Services;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
public abstract class AbstractSearchablePaneController<T> implements Initializable {
@FXML
private StackPane searchPromptLayer, searchLayer, searchFailedLayer;
@FXML
private JFXButton clearSearchFieldButton;
@FXML
private TextField searchTextField;
@FXML
private VBox searchTab, searchBox, searchPane;
private List<Searchable<T>> searchableItems;
protected static class SearchEntry<T> {
private final Parent fxmlItem;
private final Searchable<T> searchable;
public SearchEntry(Parent fxmlItem, Searchable<T> searchable) {
super();
this.fxmlItem = fxmlItem;
this.searchable = searchable;
}
public Parent getFxmlItem() {
return fxmlItem;
}
public Searchable<T> getSearchable() {
return searchable;
}
}
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
searchableItems = new ArrayList<>();
searchLayer.visibleProperty().bind(searchTextField.textProperty().isNotEmpty());
searchTextField.textProperty().addListener(((observable, oldValue, newValue) -> {
searchBox.getChildren().remove(0, searchBox.getChildren().size());
searchFailedLayer.setVisible(false);
List<Searchable<T>> searchResults = getSearchResults(searchTextField.getText());
//TODO: this is calculating relativityIndex again
searchResults.sort((controller1, controller2) -> {
int relativity1 = controller1.getRelativityIndex(searchTextField.getText());
int relativity2 = controller2.getRelativityIndex(searchTextField.getText());
return relativity2 - relativity1;
});
if (searchResults.size() != 0) {
for (Searchable<T> controller : searchResults) {
addSearchItem(controller.getState());
}
} else {
searchFailedLayer.setVisible(true);
}
}));
clearSearchFieldButton.setOnAction(e -> searchTextField.clear());
Platform.runLater(this::loadInitialItemsAsync);
}
private void loadInitialItemsAsync() {
Task<List<T>> entryLoader = new Task<List<T>>() {
@Override
protected List<T> call() {
return loadInitialEntries();
}
};
entryLoader.setOnSucceeded(e -> {
try {
List<T> entries = entryLoader.get();
if (entries.size() == 0) {
searchPromptLayer.setVisible(true);
return;
}
for (T state : entries)
addHistoryItem(state);
} catch (InterruptedException | ExecutionException E) {
Services.loggingService.logSevere("Task thread interrupted while populating HistoryTab.", E,
LocalDateTime.now());
}
});
entryLoader.setOnFailed(e -> Services.loggingService.logWarning("Failed to load history.",
(Exception) entryLoader.getException(), LocalDateTime.now()));
new Thread(entryLoader).start();
}
private void addSearchItem(T state) {
appendToList(state, searchBox, false);
}
protected abstract List<T> loadInitialEntries();
public void focusSearchField() {
searchTextField.requestFocus();
}
private Searchable<T> appendToList(T state, VBox layer, boolean appendToStart) {
searchPromptLayer.setVisible(false);
try {
SearchEntry<T> searchEntry = createEntryFromState(state);
if (appendToStart)
layer.getChildren().add(0, searchEntry.getFxmlItem());
else
layer.getChildren().add(searchEntry.getFxmlItem());
return searchEntry.getSearchable();
} catch (IOException e) {
Services.loggingService.logSevere("Could not append HistoryItem to list.", e, LocalDateTime.now());
}
return null;
}
protected abstract SearchEntry<T> createEntryFromState(T state) throws IOException;
public void addHistoryItem(T state) {
Searchable<T> controller = appendToList(state, searchTab, true);
searchableItems.add(controller);
}
private List<Searchable<T>> getSearchResults(String searchString) {
List<Searchable<T>> filteredList = new ArrayList<>();
for (Searchable<T> controller : searchableItems) {
int relativityIndex = controller.getRelativityIndex(searchString);
// Split the string into words and get total relativity index as sum of
// individual indices.
String words[] = searchString.split("\\s");
for (String word : words)
relativityIndex += controller.getRelativityIndex(word);
if (relativityIndex != 0)
filteredList.add(controller);
}
return filteredList;
}
public void toggleVisibilityIn(SplitPane splitPane) {
if (searchPane.isVisible()) {
searchPane = (VBox) splitPane.getItems().remove(0);
} else {
splitPane.getItems().add(0, searchPane);
}
searchPane.setVisible(!searchPane.isVisible());
}
}

View file

@ -23,6 +23,7 @@ import java.util.ResourceBundle;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import com.rohitawate.everest.controllers.search.Searchable;
import com.rohitawate.everest.controllers.state.DashboardState; import com.rohitawate.everest.controllers.state.DashboardState;
import com.rohitawate.everest.controllers.state.FieldState; import com.rohitawate.everest.controllers.state.FieldState;
import com.rohitawate.everest.misc.Services; import com.rohitawate.everest.misc.Services;

View file

@ -1,53 +1,65 @@
package com.rohitawate.everest.controllers; /*
* Copyright 2018 Rohit Awate.
import java.io.IOException; *
import java.util.LinkedList; * Licensed under the Apache License, Version 2.0 (the "License");
import java.util.List; * you may not use this file except in compliance with the License.
import java.util.function.Consumer; * You may obtain a copy of the License at
*
import com.rohitawate.everest.controllers.state.DashboardState; * http://www.apache.org/licenses/LICENSE-2.0
import com.rohitawate.everest.misc.Services; *
* Unless required by applicable law or agreed to in writing, software
import javafx.fxml.FXMLLoader; * distributed under the License is distributed on an "AS IS" BASIS,
import javafx.scene.Parent; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
import javafx.scene.input.MouseButton; * See the License for the specific language governing permissions and
import javafx.scene.layout.VBox; * limitations under the License.
*/
public class SearchPaneController extends AbstractSearchablePaneController<DashboardState> {
package com.rohitawate.everest.controllers;
private List<Consumer<DashboardState>> stateClickHandler = new LinkedList<>();
import com.rohitawate.everest.controllers.search.SearchablePaneController;
@Override import com.rohitawate.everest.controllers.state.DashboardState;
protected List<DashboardState> loadInitialEntries() { import com.rohitawate.everest.misc.Services;
return Services.historyManager.getHistory(); import javafx.fxml.FXMLLoader;
} import javafx.scene.Parent;
import javafx.scene.input.MouseButton;
protected SearchEntry<DashboardState> createEntryFromState(DashboardState state) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/HistoryItem.fxml")); import java.io.IOException;
Parent historyItem = loader.load(); import java.util.LinkedList;
import java.util.List;
HistoryItemController controller = loader.getController(); import java.util.function.Consumer;
controller = loader.getController(); public class HistoryPaneController extends SearchablePaneController<DashboardState> {
controller.setState(state);
private List<Consumer<DashboardState>> stateClickHandler = new LinkedList<>();
// Clicking on HistoryItem opens it up in a new tab
historyItem.setOnMouseClicked(mouseEvent -> { @Override
if (mouseEvent.getButton() == MouseButton.PRIMARY) protected List<DashboardState> loadInitialEntries() {
handleClick(state); return Services.historyManager.getHistory();
}); }
return new SearchEntry<DashboardState>(historyItem, controller);
} protected SearchEntry<DashboardState> createEntryFromState(DashboardState state) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/HistoryItem.fxml"));
private void handleClick(DashboardState state) { Parent historyItem = loader.load();
for (Consumer<DashboardState> consumer : stateClickHandler) {
consumer.accept(state); HistoryItemController controller = loader.getController();
} controller.setState(state);
}
// Clicking on HistoryItem opens it up in a new tab
public void addItemClickHandler(Consumer<DashboardState> handler) { historyItem.setOnMouseClicked(mouseEvent -> {
stateClickHandler.add(handler); if (mouseEvent.getButton() == MouseButton.PRIMARY)
} handleClick(state);
});
} return new SearchEntry<>(historyItem, controller);
}
private void handleClick(DashboardState state) {
for (Consumer<DashboardState> consumer : stateClickHandler) {
consumer.accept(state);
}
}
public void addItemClickHandler(Consumer<DashboardState> handler) {
stateClickHandler.add(handler);
}
}

View file

@ -16,24 +16,12 @@
package com.rohitawate.everest.controllers; package com.rohitawate.everest.controllers;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ResourceBundle;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
import com.rohitawate.everest.controllers.state.DashboardState; 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;
import com.rohitawate.everest.misc.ThemeManager; import com.rohitawate.everest.misc.ThemeManager;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
@ -45,11 +33,18 @@ import javafx.scene.Scene;
import javafx.scene.control.SplitPane; import javafx.scene.control.SplitPane;
import javafx.scene.control.Tab; import javafx.scene.control.Tab;
import javafx.scene.control.TabPane; import javafx.scene.control.TabPane;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage; import javafx.stage.Stage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.ResourceBundle;
public class HomeWindowController implements Initializable { public class HomeWindowController implements Initializable {
@FXML @FXML
private StackPane homeWindowSP; private StackPane homeWindowSP;
@ -57,9 +52,8 @@ public class HomeWindowController implements Initializable {
private SplitPane splitPane; private SplitPane splitPane;
@FXML @FXML
private TabPane homeWindowTabPane; private TabPane homeWindowTabPane;
@FXML @FXML
private SearchPaneController searchPaneController; private HistoryPaneController historyPaneController;
private HashMap<Tab, DashboardController> tabControllerMap; private HashMap<Tab, DashboardController> tabControllerMap;
@ -69,7 +63,7 @@ public class HomeWindowController implements Initializable {
tabControllerMap = new LinkedHashMap<>(); tabControllerMap = new LinkedHashMap<>();
recoverState(); recoverState();
searchPaneController.addItemClickHandler(this::addTab); historyPaneController.addItemClickHandler(this::addTab);
homeWindowSP.setFocusTraversable(true); homeWindowSP.setFocusTraversable(true);
Platform.runLater(() -> { Platform.runLater(() -> {
@ -79,9 +73,6 @@ public class HomeWindowController implements Initializable {
// Saves the state of the application before closing // Saves the state of the application before closing
Stage thisStage = (Stage) homeWindowSP.getScene().getWindow(); Stage thisStage = (Stage) homeWindowSP.getScene().getWindow();
thisStage.setOnCloseRequest(e -> saveState()); thisStage.setOnCloseRequest(e -> saveState());
}); });
} }
@ -109,7 +100,7 @@ public class HomeWindowController implements Initializable {
homeWindowTabPane.getTabs().remove(activeTab); homeWindowTabPane.getTabs().remove(activeTab);
tabControllerMap.remove(activeTab); tabControllerMap.remove(activeTab);
} else if (KeyMap.searchHistory.match(e)) { } else if (KeyMap.searchHistory.match(e)) {
searchPaneController.focusSearchField(); historyPaneController.focusSearchField();
} else if (KeyMap.focusParams.match(e)) { } else if (KeyMap.focusParams.match(e)) {
Tab activeTab = getActiveTab(); Tab activeTab = getActiveTab();
DashboardController controller = tabControllerMap.get(activeTab); DashboardController controller = tabControllerMap.get(activeTab);
@ -140,7 +131,7 @@ public class HomeWindowController implements Initializable {
} }
private void toggleHistoryPane() { private void toggleHistoryPane() {
searchPaneController.toggleVisibilityIn(splitPane); historyPaneController.toggleVisibilityIn(splitPane);
} }
private void addTab() { private void addTab() {
@ -224,12 +215,9 @@ public class HomeWindowController implements Initializable {
} finally { } finally {
Services.loggingService.logInfo("Application loaded.", LocalDateTime.now()); Services.loggingService.logInfo("Application loaded.", LocalDateTime.now());
} }
} }
public void addHistoryItem(DashboardState state) { public void addHistoryItem(DashboardState state) {
searchPaneController.addHistoryItem(state); historyPaneController.addHistoryItem(state);
} }
} }

View file

@ -1,15 +0,0 @@
package com.rohitawate.everest.controllers;
/**
* a searchable item that is used in a search-pane.
* @author pmucha
*
* @param <T>
*/
public interface Searchable<T> {
int getRelativityIndex(String searchString);
T getState();
}

View file

@ -0,0 +1,28 @@
/*
* 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.search;
/**
* A searchable item that is used in a SearchPane.
*
* @param <T> The search item that Searchable encapsulates.
* @author pmucha
*/
public interface Searchable<T> {
int getRelativityIndex(String searchString);
T getState();
}

View file

@ -0,0 +1,194 @@
/*
* 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.search;
import com.jfoenix.controls.JFXButton;
import com.rohitawate.everest.misc.Services;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import java.io.IOException;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.concurrent.ExecutionException;
public abstract class SearchablePaneController<T> implements Initializable {
@FXML
private StackPane searchPromptLayer, searchLayer, searchFailedLayer;
@FXML
private JFXButton clearSearchFieldButton;
@FXML
private TextField searchTextField;
@FXML
private VBox searchTab, searchBox, searchPane;
private List<Searchable<T>> searchableItems;
protected static class SearchEntry<T> {
private final Parent fxmlItem;
private final Searchable<T> searchable;
public SearchEntry(Parent fxmlItem, Searchable<T> searchable) {
super();
this.fxmlItem = fxmlItem;
this.searchable = searchable;
}
public Parent getFxmlItem() {
return fxmlItem;
}
public Searchable<T> getSearchable() {
return searchable;
}
}
@Override
public void initialize(URL location, ResourceBundle resources) {
searchableItems = new ArrayList<>();
searchLayer.visibleProperty().bind(searchTextField.textProperty().isNotEmpty());
searchTextField.textProperty().addListener(((observable, oldValue, newValue) -> {
searchBox.getChildren().remove(0, searchBox.getChildren().size());
searchFailedLayer.setVisible(false);
List<Searchable<T>> searchResults = getSearchResults(searchTextField.getText());
searchResults.sort((controller1, controller2) -> {
int relativity1 = controller1.getRelativityIndex(searchTextField.getText());
int relativity2 = controller2.getRelativityIndex(searchTextField.getText());
return relativity2 - relativity1;
});
if (searchResults.size() != 0) {
for (Searchable<T> controller : searchResults) {
addSearchItem(controller.getState());
}
} else {
searchFailedLayer.setVisible(true);
}
}));
clearSearchFieldButton.setOnAction(e -> searchTextField.clear());
Platform.runLater(this::loadInitialItemsAsync);
}
private void loadInitialItemsAsync() {
Task<List<T>> entryLoader = new Task<List<T>>() {
@Override
protected List<T> call() {
return loadInitialEntries();
}
};
entryLoader.setOnSucceeded(e -> {
try {
List<T> entries = entryLoader.get();
if (entries.size() == 0) {
searchPromptLayer.setVisible(true);
return;
}
for (T state : entries)
addHistoryItem(state);
} catch (InterruptedException | ExecutionException E) {
Services.loggingService.logSevere("Task thread interrupted while populating HistoryTab.", E,
LocalDateTime.now());
}
});
entryLoader.setOnFailed(e -> Services.loggingService.logWarning("Failed to load history.",
(Exception) entryLoader.getException(), LocalDateTime.now()));
Services.singleExecutor.execute(entryLoader);
}
private void addSearchItem(T state) {
appendToList(state, searchBox, false);
}
protected abstract List<T> loadInitialEntries();
public void focusSearchField() {
searchTextField.requestFocus();
}
private Searchable<T> appendToList(T state, VBox layer, boolean appendToStart) {
searchPromptLayer.setVisible(false);
try {
SearchEntry<T> searchEntry = createEntryFromState(state);
if (appendToStart)
layer.getChildren().add(0, searchEntry.getFxmlItem());
else
layer.getChildren().add(searchEntry.getFxmlItem());
return searchEntry.getSearchable();
} catch (IOException e) {
Services.loggingService.logSevere("Could not append HistoryItem to list.", e, LocalDateTime.now());
}
return null;
}
protected abstract SearchEntry<T> createEntryFromState(T state) throws IOException;
public void addHistoryItem(T state) {
Searchable<T> controller = appendToList(state, searchTab, true);
searchableItems.add(controller);
}
private List<Searchable<T>> getSearchResults(String searchString) {
List<Searchable<T>> filteredList = new ArrayList<>();
for (Searchable<T> controller : searchableItems) {
int relativityIndex = controller.getRelativityIndex(searchString);
// Split the string into words and get total relativity index as sum of
// individual indices.
String words[] = searchString.split("\\s");
for (String word : words)
relativityIndex += controller.getRelativityIndex(word);
if (relativityIndex != 0)
filteredList.add(controller);
}
return filteredList;
}
public void toggleVisibilityIn(SplitPane splitPane) {
if (searchPane.isVisible()) {
searchPane = (VBox) splitPane.getItems().remove(0);
} else {
splitPane.getItems().add(0, searchPane);
}
searchPane.setVisible(!searchPane.isVisible());
}
}

View file

@ -16,21 +16,6 @@
package com.rohitawate.everest.history; package com.rohitawate.everest.history;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.core.MediaType;
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.state.DashboardState; import com.rohitawate.everest.controllers.state.DashboardState;
@ -39,6 +24,16 @@ 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;
import javax.ws.rs.core.MediaType;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
public class HistoryManager { public class HistoryManager {
private Connection conn; private Connection conn;
private JsonNode queries; private JsonNode queries;
@ -387,19 +382,8 @@ public class HistoryManager {
} }
} }
if (state.params.size() > 0) { // Saves request parameters
// Saves request parameters saveTuple(state.params, "Param", requestID);
statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveTuple").toString()));
for (FieldState fieldState : state.params) {
statement.setInt(1, requestID);
statement.setString(2, "Param");
statement.setString(3, fieldState.key);
statement.setString(4, fieldState.value);
statement.setInt(5, fieldState.checked ? 1 : 0);
statement.executeUpdate();
}
}
if (!(state.httpMethod.equals("GET") || state.httpMethod.equals("DELETE"))) { if (!(state.httpMethod.equals("GET") || state.httpMethod.equals("DELETE"))) {
// Maps the request to its ContentType for faster retrieval // Maps the request to its ContentType for faster retrieval
@ -423,48 +407,11 @@ public class HistoryManager {
statement.executeUpdate(); statement.executeUpdate();
break; break;
case MediaType.APPLICATION_FORM_URLENCODED: case MediaType.APPLICATION_FORM_URLENCODED:
if (state.urlStringTuples.size() > 0) { saveTuple(state.urlStringTuples, "String", requestID);
for (FieldState fieldState : state.urlStringTuples) {
// Saves the string tuples
statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveTuple").toString()));
statement.setInt(1, requestID);
statement.setString(2, "String");
statement.setString(3, fieldState.key);
statement.setString(4, fieldState.value);
statement.setInt(5, fieldState.checked ? 1 : 0);
statement.executeUpdate();
}
}
break; break;
case MediaType.MULTIPART_FORM_DATA: case MediaType.MULTIPART_FORM_DATA:
if (state.formStringTuples.size() > 0) { saveTuple(state.formStringTuples, "String", requestID);
for (FieldState fieldState : state.formStringTuples) { saveTuple(state.formFileTuples, "File", requestID);
// Saves the string tuples
statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveTuple").toString()));
statement.setInt(1, requestID);
statement.setString(2, "String");
statement.setString(3, fieldState.key);
statement.setString(4, fieldState.value);
statement.setInt(5, fieldState.checked ? 1 : 0);
statement.executeUpdate();
}
}
if (state.formFileTuples.size() > 0) {
for (FieldState fieldState : state.formFileTuples) {
// Saves the string tuples
statement = conn.prepareStatement(EverestUtilities.trimString(queries.get("saveTuple").toString()));
statement.setInt(1, requestID);
statement.setString(2, "File");
statement.setString(3, fieldState.key);
statement.setString(4, fieldState.value);
statement.setInt(5, fieldState.checked ? 1 : 0);
statement.executeUpdate();
}
}
break; break;
} }
} }
@ -472,5 +419,25 @@ public class HistoryManager {
Services.loggingService.logWarning("Database error.", e, LocalDateTime.now()); Services.loggingService.logWarning("Database error.", e, LocalDateTime.now());
} }
} }
private void saveTuple(ArrayList<FieldState> tuples, String tupleType, int requestID) {
if (tuples.size() > 0) {
for (FieldState fieldState : tuples) {
// Saves the string tuples
try {
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) {
Services.loggingService.logWarning("Database error.", e, LocalDateTime.now());
}
}
}
}
} }
} }

View file

@ -19,14 +19,6 @@ package com.rohitawate.everest.misc;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializationFeature;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDateTime;
public class EverestUtilities { public class EverestUtilities {
public static ObjectMapper jsonMapper; public static ObjectMapper jsonMapper;
@ -44,21 +36,4 @@ public class EverestUtilities {
public static String trimString(String input) { public static String trimString(String input) {
return input.replaceAll("\"", ""); return input.replaceAll("\"", "");
} }
/**
* Copies the BugReporter from within the JAR to the installation directory.
*/
public static void createBugReporter() {
new Thread(() -> {
InputStream inputStream = EverestUtilities.class.getResourceAsStream("/BugReporter.jar");
Path bugReporter = Paths.get("Everest/BugReporter.jar");
try {
Files.copy(inputStream, bugReporter, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
e.printStackTrace();
}
Services.loggingService.logInfo("BugReporter was copied to installation directory.", LocalDateTime.now());
}).start();
}
} }

View file

@ -16,79 +16,74 @@
package com.rohitawate.everest.requestmanager; package com.rohitawate.everest.requestmanager;
import java.util.LinkedList; import java.util.ArrayList;
/**
* Provides the various RequestManagers employed by Everest.
* <p>
* Pools are created as needed i.e. the first DELETE request
* will create the pool of DELETERequestManagers. If a DELETE
* request is never made, the pool won't be created. Same applies
* for all other types of requests.
* <p>
* When demanding a RequestManager, the pool is checked linearly.
* The first RequestManager which is not currently running will be
* returned to the caller. If all the managers in the pool are running,
* a new one is created, added to the pool, and returned.
*/
public class RequestManagersPool { public class RequestManagersPool {
private LinkedList<GETRequestManager> getManagers; private ArrayList<GETRequestManager> getManagers;
private LinkedList<DataDispatchRequestManager> dataManagers; private ArrayList<DataDispatchRequestManager> dataManagers;
private LinkedList<DELETERequestManager> deleteManagers; private ArrayList<DELETERequestManager> deleteManagers;
public GETRequestManager get() { public GETRequestManager get() {
if (getManagers == null) { if (getManagers == null)
GETRequestManager newManager = new GETRequestManager(); getManagers = new ArrayList<>();
new Thread(() -> { for (GETRequestManager getManager : getManagers) {
getManagers = new LinkedList<>(); if (!getManager.isRunning()) {
getManagers.add(newManager); getManager.reset();
}).start(); return getManager;
return newManager;
} else {
for (GETRequestManager getManager : getManagers) {
if (!getManager.isRunning())
return getManager;
} }
GETRequestManager newManager = new GETRequestManager();
getManagers.add(newManager);
return newManager;
} }
GETRequestManager newManager = new GETRequestManager();
getManagers.add(newManager);
return newManager;
} }
public DataDispatchRequestManager data() { public DataDispatchRequestManager data() {
if (dataManagers == null) { if (dataManagers == null)
DataDispatchRequestManager newManager = new DataDispatchRequestManager(); dataManagers = new ArrayList<>();
new Thread(() -> { for (DataDispatchRequestManager dataManager : dataManagers) {
dataManagers = new LinkedList<>(); if (!dataManager.isRunning()) {
dataManagers.add(newManager); dataManager.reset();
}).start(); return dataManager;
return newManager;
} else {
for (DataDispatchRequestManager dataManager : dataManagers) {
if (!dataManager.isRunning())
return dataManager;
} }
DataDispatchRequestManager newManager = new DataDispatchRequestManager();
dataManagers.add(newManager);
return newManager;
} }
DataDispatchRequestManager newManager = new DataDispatchRequestManager();
dataManagers.add(newManager);
return newManager;
} }
public DELETERequestManager delete() { public DELETERequestManager delete() {
if (deleteManagers == null) { if (deleteManagers == null)
DELETERequestManager newManager = new DELETERequestManager(); deleteManagers = new ArrayList<>();
new Thread(() -> { for (DELETERequestManager deleteManager : deleteManagers) {
deleteManagers = new LinkedList<>(); if (!deleteManager.isRunning()) {
deleteManagers.add(newManager); deleteManager.reset();
}).start(); return deleteManager;
return newManager;
} else {
for (DELETERequestManager deleteManager : deleteManagers) {
if (!deleteManager.isRunning())
return deleteManager;
} }
DELETERequestManager newManager = new DELETERequestManager();
deleteManagers.add(newManager);
return newManager;
} }
DELETERequestManager newManager = new DELETERequestManager();
deleteManagers.add(newManager);
return newManager;
} }
} }

Binary file not shown.

View file

@ -1,151 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
~ Copyright 2018 Rohit Awate. ~ Copyright 2018 Rohit Awate.
~ ~
~ Licensed under the Apache License, Version 2.0 (the "License"); ~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License. ~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at ~ You may obtain a copy of the License at
~ ~
~ http://www.apache.org/licenses/LICENSE-2.0 ~ http://www.apache.org/licenses/LICENSE-2.0
~ ~
~ Unless required by applicable law or agreed to in writing, software ~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS, ~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and ~ See the License for the specific language governing permissions and
~ limitations under the License. ~ limitations under the License.
--> -->
<?import com.jfoenix.controls.JFXButton?> <?import com.jfoenix.controls.JFXButton?>
<?import javafx.geometry.*?> <?import javafx.geometry.*?>
<?import javafx.scene.control.*?> <?import javafx.scene.control.*?>
<?import javafx.scene.image.*?> <?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?> <?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?> <?import javafx.scene.text.Font?>
<VBox fx:id="searchPane" xmlns="http://javafx.com/javafx/8.0.141" <VBox fx:id="searchPane" xmlns="http://javafx.com/javafx/8.0.141"
xmlns:fx="http://javafx.com/fxml/1" alignment="TOP_CENTER" maxWidth="450.0" xmlns:fx="http://javafx.com/fxml/1" alignment="TOP_CENTER" maxWidth="450.0"
minWidth="400.0" SplitPane.resizableWithParent="false" fx:controller="com.rohitawate.everest.controllers.SearchPaneController"> minWidth="400.0" SplitPane.resizableWithParent="false" fx:controller="com.rohitawate.everest.controllers.HistoryPaneController">
<children> <children>
<HBox fx:id="historySearchFieldBox" alignment="CENTER" <HBox fx:id="historySearchFieldBox" alignment="CENTER"
fillHeight="false"> fillHeight="false">
<VBox.margin> <VBox.margin>
<Insets /> <Insets />
</VBox.margin> </VBox.margin>
<children> <children>
<ImageView fitHeight="20.0" fitWidth="20.0" <ImageView fitHeight="20.0" fitWidth="20.0"
pickOnBounds="true" preserveRatio="true" HBox.hgrow="ALWAYS"> pickOnBounds="true" preserveRatio="true" HBox.hgrow="ALWAYS">
<image> <image>
<Image url="@../../assets/Search.png" /> <Image url="@../../assets/Search.png" />
</image> </image>
</ImageView> </ImageView>
<TextField fx:id="searchTextField" styleClass="searchTextField" promptText="SEARCH HISTORY" <TextField fx:id="searchTextField" styleClass="searchTextField" promptText="SEARCH HISTORY"
HBox.hgrow="ALWAYS"> HBox.hgrow="ALWAYS">
<padding> <padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding> </padding>
</TextField> </TextField>
<JFXButton fx:id="clearSearchFieldButton" <JFXButton fx:id="clearSearchFieldButton"
ripplerFill="WHITE" HBox.hgrow="ALWAYS"> ripplerFill="WHITE" HBox.hgrow="ALWAYS">
<graphic> <graphic>
<ImageView fitHeight="20.0" fitWidth="20.0" <ImageView fitHeight="20.0" fitWidth="20.0"
pickOnBounds="true" preserveRatio="true"> pickOnBounds="true" preserveRatio="true">
<image> <image>
<Image url="@../../assets/BackspaceArrow.png" /> <Image url="@../../assets/BackspaceArrow.png" />
</image> </image>
</ImageView> </ImageView>
</graphic> </graphic>
</JFXButton> </JFXButton>
</children> </children>
<padding> <padding>
<Insets bottom="10.0" left="20.0" right="20.0" top="10.0" /> <Insets bottom="10.0" left="20.0" right="20.0" top="10.0" />
</padding> </padding>
</HBox> </HBox>
<StackPane VBox.vgrow="ALWAYS"> <StackPane VBox.vgrow="ALWAYS">
<children> <children>
<StackPane> <StackPane>
<children> <children>
<ScrollPane fx:id="historyScrollPane" <ScrollPane fx:id="historyScrollPane"
fitToHeight="true" fitToWidth="true" hbarPolicy="NEVER"> fitToHeight="true" fitToWidth="true" hbarPolicy="NEVER">
<content> <content>
<VBox fx:id="searchTab" alignment="TOP_CENTER" <VBox fx:id="searchTab" alignment="TOP_CENTER"
spacing="5.0"> spacing="5.0">
<padding> <padding>
<Insets bottom="20.0" left="20.0" right="20.0" <Insets bottom="20.0" left="20.0" right="20.0"
top="20.0" /> top="20.0" />
</padding> </padding>
</VBox> </VBox>
</content> </content>
</ScrollPane> </ScrollPane>
<StackPane fx:id="searchPromptLayer"> <StackPane fx:id="searchPromptLayer">
<children> <children>
<Label text="YOUR REQUESTS HISTORY WILL APPEAR HERE" <Label text="YOUR REQUESTS HISTORY WILL APPEAR HERE"
textAlignment="CENTER" textFill="#575757" wrapText="true"> textAlignment="CENTER" textFill="#575757" wrapText="true">
<font> <font>
<Font size="25.0" /> <Font size="25.0" />
</font> </font>
</Label> </Label>
</children> </children>
<padding> <padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" /> <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding> </padding>
</StackPane> </StackPane>
</children> </children>
</StackPane> </StackPane>
<StackPane fx:id="searchLayer"> <StackPane fx:id="searchLayer">
<children> <children>
<VBox alignment="TOP_CENTER"> <VBox alignment="TOP_CENTER">
<children> <children>
<Label graphicTextGap="10.0" text="SEARCH RESULTS" <Label graphicTextGap="10.0" text="SEARCH RESULTS"
textFill="#199F6F"> textFill="#199F6F">
<VBox.margin> <VBox.margin>
<Insets bottom="10.0" left="10.0" right="10.0" <Insets bottom="10.0" left="10.0" right="10.0"
top="10.0" /> top="10.0" />
</VBox.margin> </VBox.margin>
<font> <font>
<Font size="19.0" /> <Font size="19.0" />
</font> </font>
</Label> </Label>
<ScrollPane fx:id="searchScrollPane" <ScrollPane fx:id="searchScrollPane"
fitToHeight="true" fitToWidth="true" hbarPolicy="NEVER"> fitToHeight="true" fitToWidth="true" hbarPolicy="NEVER">
<content> <content>
<VBox fx:id="searchBox" alignment="TOP_CENTER" <VBox fx:id="searchBox" alignment="TOP_CENTER"
spacing="5.0"> spacing="5.0">
<padding> <padding>
<Insets bottom="20.0" left="20.0" right="20.0" <Insets bottom="20.0" left="20.0" right="20.0"
top="20.0" /> top="20.0" />
</padding> </padding>
</VBox> </VBox>
</content> </content>
</ScrollPane> </ScrollPane>
</children> </children>
</VBox> </VBox>
<StackPane fx:id="searchFailedLayer"> <StackPane fx:id="searchFailedLayer">
<children> <children>
<VBox alignment="CENTER"> <VBox alignment="CENTER">
<children> <children>
<ImageView fitHeight="100.0" fitWidth="100.0" <ImageView fitHeight="100.0" fitWidth="100.0"
opacity="0.51" pickOnBounds="true" preserveRatio="true"> opacity="0.51" pickOnBounds="true" preserveRatio="true">
<image> <image>
<Image url="@../../assets/Explosion.png" /> <Image url="@../../assets/Explosion.png" />
</image> </image>
</ImageView> </ImageView>
<Label text="NO RESULTS" textAlignment="CENTER" <Label text="NO RESULTS" textAlignment="CENTER"
textFill="#bfbfbf" wrapText="true" VBox.vgrow="ALWAYS"> textFill="#bfbfbf" wrapText="true" VBox.vgrow="ALWAYS">
<font> <font>
<Font size="25.0" /> <Font size="25.0" />
</font> </font>
</Label> </Label>
</children> </children>
</VBox> </VBox>
</children> </children>
<padding> <padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" /> <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding> </padding>
</StackPane> </StackPane>
</children> </children>
</StackPane> </StackPane>
</children> </children>
</StackPane> </StackPane>
</children> </children>
</VBox> </VBox>

View file

@ -1,29 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- ~ Copyright 2018 Rohit Awate. ~ ~ Licensed under the Apache License, <!--
Version 2.0 (the "License"); ~ you may not use this file except in compliance ~ Copyright 2018 Rohit Awate.
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 ~ ~ Licensed under the Apache License, Version 2.0 (the "License");
distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT ~ you may not use this file except in compliance with the License.
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the ~ You may obtain a copy of the License at
License for the specific language governing permissions and ~ limitations ~
under the License. --> ~ 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.
-->
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.StackPane?>
<?import com.jfoenix.controls.JFXButton?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Font?>
<StackPane fx:id="homeWindowSP" <StackPane fx:id="homeWindowSP"
stylesheets="@../../css/Adreana.css" stylesheets="@../../css/Adreana.css"
xmlns="http://javafx.com/javafx/8.0.141" xmlns="http://javafx.com/javafx/8.0.141"
xmlns:fx="http://javafx.com/fxml/1" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.rohitawate.everest.controllers.HomeWindowController"> fx:controller="com.rohitawate.everest.controllers.HomeWindowController">
<children> <children>
<SplitPane fx:id="splitPane" dividerPositions="0.3"> <SplitPane fx:id="splitPane" dividerPositions="0.3">
<items> <items>
<fx:include fx:id="searchPane" source="SearchPane.fxml" /> <fx:include fx:id="historyPane" source="HistoryPane.fxml" />
<TabPane fx:id="homeWindowTabPane" <TabPane fx:id="homeWindowTabPane"
tabClosingPolicy="ALL_TABS" tabMaxHeight="30.0" tabMaxWidth="200.0" tabClosingPolicy="ALL_TABS" tabMaxHeight="30.0" tabMaxWidth="200.0"
tabMinHeight="30.0" tabMinWidth="200.0" tabMinHeight="30.0" tabMinWidth="200.0"