diff --git a/src/main/java/com/rohitawate/everest/controllers/DashboardController.java b/src/main/java/com/rohitawate/everest/controllers/DashboardController.java index e03236d..dc575d9 100644 --- a/src/main/java/com/rohitawate/everest/controllers/DashboardController.java +++ b/src/main/java/com/rohitawate/everest/controllers/DashboardController.java @@ -26,7 +26,7 @@ import com.rohitawate.everest.controllers.state.FieldState; import com.rohitawate.everest.controllers.visualizers.TreeVisualizer; import com.rohitawate.everest.controllers.visualizers.Visualizer; import com.rohitawate.everest.exceptions.RedirectException; -import com.rohitawate.everest.exceptions.UnreliableResponseException; +import com.rohitawate.everest.exceptions.NullResponseException; import com.rohitawate.everest.format.FormatterFactory; import com.rohitawate.everest.logging.LoggingService; import com.rohitawate.everest.misc.EverestUtilities; @@ -34,9 +34,9 @@ import com.rohitawate.everest.misc.Services; import com.rohitawate.everest.misc.ThemeManager; import com.rohitawate.everest.models.requests.DELETERequest; import com.rohitawate.everest.models.requests.DataRequest; +import com.rohitawate.everest.models.requests.EverestRequest; import com.rohitawate.everest.models.requests.GETRequest; import com.rohitawate.everest.models.responses.EverestResponse; -import com.rohitawate.everest.requestmanager.DataRequestManager; import com.rohitawate.everest.requestmanager.RequestManager; import com.rohitawate.everest.requestmanager.RequestManagersPool; import javafx.beans.binding.Bindings; @@ -239,7 +239,7 @@ public class DashboardController implements Initializable { getRequest.setTarget(address); getRequest.setHeaders(headerTabController.getHeaders()); - requestManager = RequestManagersPool.get(); + requestManager = RequestManagersPool.manager(); requestManager.setRequest(getRequest); break; case "POST": @@ -284,7 +284,7 @@ public class DashboardController implements Initializable { dataRequest.setContentType(MediaType.APPLICATION_FORM_URLENCODED); } - requestManager = RequestManagersPool.data(); + requestManager = RequestManagersPool.manager(); requestManager.setRequest(dataRequest); break; case "DELETE": @@ -294,7 +294,7 @@ public class DashboardController implements Initializable { deleteRequest.setTarget(address); deleteRequest.setHeaders(headerTabController.getHeaders()); - requestManager = RequestManagersPool.delete(); + requestManager = RequestManagersPool.manager(); requestManager.setRequest(deleteRequest); break; default: @@ -322,8 +322,8 @@ public class DashboardController implements Initializable { Exception exception = (Exception) throwable; LoggingService.logWarning(httpMethodBox.getValue() + " request could not be processed.", exception, LocalDateTime.now()); - if (throwable.getClass() == UnreliableResponseException.class) { - UnreliableResponseException URE = (UnreliableResponseException) throwable; + if (throwable.getClass() == NullResponseException.class) { + NullResponseException URE = (NullResponseException) throwable; errorTitle.setText(URE.getExceptionTitle()); errorDetails.setText(URE.getExceptionDetails()); } else if (throwable.getClass() == ProcessingException.class) { @@ -338,7 +338,7 @@ public class DashboardController implements Initializable { return; } - if (requestManager.getClass() == DataRequestManager.class) { + if (requestManager.getRequest().getClass().equals(DataRequest.class)) { if (throwable.getCause() != null && throwable.getCause().getClass() == IllegalArgumentException.class) { errorTitle.setText("Did you forget something?"); errorDetails.setText("Please specify a body for your " + httpMethodBox.getValue() + " request."); diff --git a/src/main/java/com/rohitawate/everest/controllers/HomeWindowController.java b/src/main/java/com/rohitawate/everest/controllers/HomeWindowController.java index 0d8fd9f..917a1f2 100644 --- a/src/main/java/com/rohitawate/everest/controllers/HomeWindowController.java +++ b/src/main/java/com/rohitawate/everest/controllers/HomeWindowController.java @@ -78,7 +78,7 @@ public class HomeWindowController implements Initializable { e.printStackTrace(); } - // Using LinkedHashMap because they retain order + // Using LinkedHashMap because it retains order tabStateMap = new LinkedHashMap<>(); recoverState(); @@ -199,9 +199,10 @@ public class HomeWindowController implements Initializable { } private void removeTab(Tab newTab) { - DashboardState closedState = tabStateMap.remove(newTab); - closedState = null; + DashboardState state = tabStateMap.remove(newTab); + state = null; tabPane.getTabs().remove(newTab); + newTab.setOnCloseRequest(null); newTab = null; } diff --git a/src/main/java/com/rohitawate/everest/controllers/state/DashboardState.java b/src/main/java/com/rohitawate/everest/controllers/state/DashboardState.java index b6ad258..c6ff86a 100644 --- a/src/main/java/com/rohitawate/everest/controllers/state/DashboardState.java +++ b/src/main/java/com/rohitawate/everest/controllers/state/DashboardState.java @@ -20,11 +20,11 @@ import com.rohitawate.everest.controllers.DashboardController.ComposerTab; import com.rohitawate.everest.controllers.DashboardController.ResponseLayer; import com.rohitawate.everest.controllers.DashboardController.ResponseTab; import com.rohitawate.everest.exceptions.RedirectException; -import com.rohitawate.everest.exceptions.UnreliableResponseException; +import com.rohitawate.everest.exceptions.NullResponseException; import com.rohitawate.everest.logging.LoggingService; +import com.rohitawate.everest.models.requests.DataRequest; import com.rohitawate.everest.models.requests.EverestRequest; import com.rohitawate.everest.models.responses.EverestResponse; -import com.rohitawate.everest.requestmanager.DataRequestManager; import com.rohitawate.everest.requestmanager.RequestManager; import javafx.event.Event; @@ -106,8 +106,8 @@ public class DashboardState { Exception exception = (Exception) throwable; LoggingService.logWarning(this.composer.httpMethod + " request could not be processed.", exception, LocalDateTime.now()); - if (throwable.getClass() == UnreliableResponseException.class) { - UnreliableResponseException URE = (UnreliableResponseException) throwable; + if (throwable.getClass() == NullResponseException.class) { + NullResponseException URE = (NullResponseException) throwable; errorTitle = URE.getExceptionTitle(); errorDetails = URE.getExceptionDetails(); } else if (throwable.getClass() == ProcessingException.class) { @@ -131,7 +131,7 @@ public class DashboardState { errorDetails = "Something went wrong. Try to make another request.Restart Everest if that doesn't work."; } - if (requestManager.getClass() == DataRequestManager.class) { + if (requestManager.getRequest().getClass().equals(DataRequest.class)) { if (throwable.getCause() != null && throwable.getCause().getClass() == IllegalArgumentException.class) { errorTitle = "Did you forget something?"; errorDetails = "Please specify a body for your " + this.composer.httpMethod + " request."; diff --git a/src/main/java/com/rohitawate/everest/controllers/visualizers/TreeVisualizer.java b/src/main/java/com/rohitawate/everest/controllers/visualizers/TreeVisualizer.java index 68e72db..e70364d 100644 --- a/src/main/java/com/rohitawate/everest/controllers/visualizers/TreeVisualizer.java +++ b/src/main/java/com/rohitawate/everest/controllers/visualizers/TreeVisualizer.java @@ -33,6 +33,7 @@ public class TreeVisualizer extends Visualizer { public TreeVisualizer() { visualizer = new TreeView<>(); visualizer.setShowRoot(false); + visualizer.setCache(true); setContent(visualizer); } @@ -62,6 +63,7 @@ public class TreeVisualizer extends Visualizer { items.add(new TreeItem<>(i++ + ": " + EverestUtilities.trimString(currentNode.toString()))); } else if (currentNode.isObject()) { TreeItem newRoot = new TreeItem<>(); + newRoot.setExpanded(true); items.add(newRoot); populate(newRoot, i++ + ": [Anonymous Object]", currentNode); } @@ -79,6 +81,7 @@ public class TreeVisualizer extends Visualizer { + EverestUtilities.trimString(currentNode.toString()))); } else if (currentNode.isArray() || currentNode.isObject()) { TreeItem newRoot = new TreeItem<>(); + newRoot.setExpanded(true); items.add(newRoot); populate(newRoot, currentEntry.getKey(), currentNode); } @@ -90,5 +93,6 @@ public class TreeVisualizer extends Visualizer { public void clear() { visualizer.setRoot(null); + System.gc(); } } diff --git a/src/main/java/com/rohitawate/everest/exceptions/UnreliableResponseException.java b/src/main/java/com/rohitawate/everest/exceptions/NullResponseException.java similarity index 89% rename from src/main/java/com/rohitawate/everest/exceptions/UnreliableResponseException.java rename to src/main/java/com/rohitawate/everest/exceptions/NullResponseException.java index dd5d66c..4a67feb 100644 --- a/src/main/java/com/rohitawate/everest/exceptions/UnreliableResponseException.java +++ b/src/main/java/com/rohitawate/everest/exceptions/NullResponseException.java @@ -21,11 +21,11 @@ package com.rohitawate.everest.exceptions; *

* Used by DashboardController to display ErrorLayer. */ -public class UnreliableResponseException extends Exception { +public class NullResponseException extends Exception { private String exceptionTitle; private String exceptionDetails; - public UnreliableResponseException(String exceptionTitle, String exceptionDetails) { + public NullResponseException(String exceptionTitle, String exceptionDetails) { this.exceptionTitle = exceptionTitle; this.exceptionDetails = exceptionDetails; } diff --git a/src/main/java/com/rohitawate/everest/requestmanager/DELETERequestManager.java b/src/main/java/com/rohitawate/everest/requestmanager/DELETERequestManager.java deleted file mode 100644 index bbe415d..0000000 --- a/src/main/java/com/rohitawate/everest/requestmanager/DELETERequestManager.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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.requestmanager; - -import com.rohitawate.everest.models.responses.EverestResponse; -import javafx.concurrent.Task; - -import javax.ws.rs.ProcessingException; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.core.Response; - -public class DELETERequestManager extends RequestManager { - - @Override - protected Task createTask() throws ProcessingException { - return new Task() { - @Override - protected EverestResponse call() throws Exception { - Invocation invocation = requestBuilder.buildDelete(); - - initialTime = System.currentTimeMillis(); - Response serverResponse = invocation.invoke(); - finalTime = System.currentTimeMillis(); - - processServerResponse(serverResponse); - - return response; - } - }; - } -} diff --git a/src/main/java/com/rohitawate/everest/requestmanager/DataRequestManager.java b/src/main/java/com/rohitawate/everest/requestmanager/DataRequestManager.java deleted file mode 100644 index 0f3b323..0000000 --- a/src/main/java/com/rohitawate/everest/requestmanager/DataRequestManager.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * 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.requestmanager; - -import com.rohitawate.everest.models.requests.DataRequest; -import com.rohitawate.everest.models.responses.EverestResponse; -import javafx.concurrent.Task; -import org.glassfish.jersey.media.multipart.FormDataMultiPart; -import org.glassfish.jersey.media.multipart.file.FileDataBodyPart; - -import javax.ws.rs.ProcessingException; -import javax.ws.rs.client.Entity; -import javax.ws.rs.client.Invocation; -import javax.ws.rs.core.Form; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.util.HashMap; -import java.util.Map; - -/** - * Processes DataRequest by automatically determining whether it - * is a POST, PUT or PATCH request. - */ -public class DataRequestManager extends RequestManager { - private DataRequest dataRequest; - private String requestType; - - @Override - protected Task createTask() throws ProcessingException { - return new Task() { - @Override - protected EverestResponse call() throws Exception { - dataRequest = (DataRequest) request; - requestType = dataRequest.getRequestType(); - - Invocation invocation = appendBody(); - initialTime = System.currentTimeMillis(); - Response serverResponse = invocation.invoke(); - finalTime = System.currentTimeMillis(); - - processServerResponse(serverResponse); - - return response; - } - }; - } - - - /** - * Adds the request body based on the content type and generates an invocation. - * - * @return invocation object - */ - private Invocation appendBody() throws Exception { - /* - Checks if a custom mime-type is mentioned in the headers. - If present, it will override the logical Content-Type. - */ - String overriddenContentType = request.getHeaders().get("Content-Type"); - Invocation invocation = null; - Map.Entry mapEntry; - - switch (dataRequest.getContentType()) { - case MediaType.MULTIPART_FORM_DATA: - FormDataMultiPart formData = new FormDataMultiPart(); - - // Adding the string tuples to the request - HashMap pairs = dataRequest.getStringTuples(); - for (Map.Entry entry : pairs.entrySet()) { - mapEntry = (Map.Entry) entry; - formData.field(mapEntry.getKey(), mapEntry.getValue()); - } - - String filePath; - File file; - boolean fileException = false; - String fileExceptionMessage = null; - pairs = dataRequest.getFileTuples(); - - // Adding the file tuples to the request - for (Map.Entry entry : pairs.entrySet()) { - mapEntry = (Map.Entry) entry; - filePath = mapEntry.getValue(); - file = new File(filePath); - - if (file.exists()) - formData.bodyPart(new FileDataBodyPart(mapEntry.getKey(), - file, MediaType.APPLICATION_OCTET_STREAM_TYPE)); - else { - fileException = true; - // For pretty-printing FileNotFoundException to the UI - fileExceptionMessage = " - " + filePath + "\n"; - } - } - - if (fileException) { - throw new FileNotFoundException(fileExceptionMessage); - } - - formData.setMediaType(MediaType.MULTIPART_FORM_DATA_TYPE); - - if (requestType.equals("POST")) - invocation = requestBuilder.buildPost(Entity.entity(formData, MediaType.MULTIPART_FORM_DATA_TYPE)); - else - invocation = requestBuilder.buildPut(Entity.entity(formData, MediaType.MULTIPART_FORM_DATA_TYPE)); - break; - case MediaType.APPLICATION_OCTET_STREAM: - if (overriddenContentType == null) - overriddenContentType = MediaType.APPLICATION_OCTET_STREAM; - filePath = dataRequest.getBody(); - - File check = new File(filePath); - - if (!check.exists()) { - throw new FileNotFoundException(filePath); - } - - FileInputStream stream = new FileInputStream(filePath); - - if (requestType.equals("POST")) - invocation = requestBuilder.buildPost(Entity.entity(stream, overriddenContentType)); - else - invocation = requestBuilder.buildPut(Entity.entity(stream, overriddenContentType)); - break; - case MediaType.APPLICATION_FORM_URLENCODED: - if (overriddenContentType == null) - overriddenContentType = MediaType.APPLICATION_FORM_URLENCODED; - - Form form = new Form(); - - for (Map.Entry entry : dataRequest.getStringTuples().entrySet()) { - mapEntry = (Map.Entry) entry; - form.param(mapEntry.getKey(), mapEntry.getValue()); - } - - if (requestType.equals("POST")) - invocation = requestBuilder.buildPost(Entity.entity(form, overriddenContentType)); - else - invocation = requestBuilder.buildPut(Entity.entity(form, overriddenContentType)); - break; - default: - // Handles raw data types (JSON, Plain text, XML, HTML) - String originalContentType = dataRequest.getContentType(); - if (overriddenContentType == null) - overriddenContentType = originalContentType; - switch (requestType) { - case "POST": - invocation = requestBuilder - .buildPost(Entity.entity(dataRequest.getBody(), overriddenContentType)); - break; - case "PUT": - invocation = requestBuilder - .buildPut(Entity.entity(dataRequest.getBody(), overriddenContentType)); - break; - case "PATCH": - invocation = requestBuilder - .build("PATCH", Entity.entity(dataRequest.getBody(), overriddenContentType)); - break; - } - } - - return invocation; - } -} diff --git a/src/main/java/com/rohitawate/everest/requestmanager/GETRequestManager.java b/src/main/java/com/rohitawate/everest/requestmanager/GETRequestManager.java deleted file mode 100644 index aa4c731..0000000 --- a/src/main/java/com/rohitawate/everest/requestmanager/GETRequestManager.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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.requestmanager; - -import com.rohitawate.everest.models.responses.EverestResponse; -import javafx.concurrent.Task; - -import javax.ws.rs.ProcessingException; -import javax.ws.rs.core.Response; - -public class GETRequestManager extends RequestManager { - - @Override - protected Task createTask() throws ProcessingException { - return new Task() { - @Override - protected EverestResponse call() throws Exception { - initialTime = System.currentTimeMillis(); - Response serverResponse = requestBuilder.get(); - finalTime = System.currentTimeMillis(); - - processServerResponse(serverResponse); - - return response; - } - }; - } -} diff --git a/src/main/java/com/rohitawate/everest/requestmanager/RequestManager.java b/src/main/java/com/rohitawate/everest/requestmanager/RequestManager.java index 01cf109..e77d2c5 100644 --- a/src/main/java/com/rohitawate/everest/requestmanager/RequestManager.java +++ b/src/main/java/com/rohitawate/everest/requestmanager/RequestManager.java @@ -16,23 +16,55 @@ package com.rohitawate.everest.requestmanager; import com.rohitawate.everest.exceptions.RedirectException; -import com.rohitawate.everest.exceptions.UnreliableResponseException; +import com.rohitawate.everest.exceptions.NullResponseException; +import com.rohitawate.everest.models.requests.DELETERequest; +import com.rohitawate.everest.models.requests.DataRequest; import com.rohitawate.everest.models.requests.EverestRequest; +import com.rohitawate.everest.models.requests.GETRequest; import com.rohitawate.everest.models.responses.EverestResponse; import com.rohitawate.everest.settings.Settings; import javafx.concurrent.Service; +import javafx.concurrent.Task; import javafx.concurrent.WorkerStateEvent; import javafx.event.EventHandler; import org.glassfish.jersey.client.ClientProperties; import org.glassfish.jersey.client.HttpUrlConnectorProvider; +import org.glassfish.jersey.media.multipart.FormDataMultiPart; import org.glassfish.jersey.media.multipart.MultiPartFeature; +import org.glassfish.jersey.media.multipart.file.FileDataBodyPart; +import javax.ws.rs.ProcessingException; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation; import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.core.Form; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.HashMap; +import java.util.Map; -public abstract class RequestManager extends Service { +/** + * Manages all the requests made through Everest. + * Converts EverestRequests into JAX-RS Invocations are then processed by Jersey. + * Also, parses the response and returns EverestResponses. + * + * Previously, Everest used separate managers for GET, Data (POST, PUT and PATCH) and DELETE + * requests. However, RequestManager extends JavaFX's Service class which is expensive to create objects of. + * This made the creation of separate pools for every kind of RequestManager too expensive memory-wise. + * Thus, now a single class manages all kinds of Requests thus requiring only a single kind of pool. + * Also, this enables us to re-use inactive RequestManagers for all kinds of Requests. For example, previously, + * if a GETRequestManager was requested, and all GETRequestManagers were running, a new one would be created even + * if a DELETERequestManager was idle. + * + * TLDR: At the cost of some reduced semantic clarity, the old, separate-for-every-type-of-request RequestManagers + * are now replaced by this single works-for-all one to save some serious amount of memory and for better re-use. + */ +public class RequestManager extends Service { private static final Client client; static { @@ -49,12 +81,46 @@ public abstract class RequestManager extends Service { client.property(ClientProperties.READ_TIMEOUT, Settings.connectionReadTimeOut); } - long initialTime; - long finalTime; + private long initialTime; + private long finalTime; - EverestRequest request; - EverestResponse response; - Builder requestBuilder; + private EverestRequest request; + private EverestResponse response; + private Builder requestBuilder; + + /** + * Creates a JavaFX Task for processing the required kind of request. + */ + @Override + protected Task createTask() throws ProcessingException { + return new Task() { + @Override + protected EverestResponse call() throws Exception { + Response serverResponse = null; + + if (request.getClass().equals(GETRequest.class)) { + initialTime = System.currentTimeMillis(); + serverResponse = requestBuilder.get(); + finalTime = System.currentTimeMillis(); + } else if (request.getClass().equals(DataRequest.class)) { + DataRequest dataRequest = (DataRequest) request; + + Invocation invocation = appendBody(dataRequest); + initialTime = System.currentTimeMillis(); + serverResponse = invocation.invoke(); + finalTime = System.currentTimeMillis(); + } else if (request.getClass().equals(DELETERequest.class)) { + initialTime = System.currentTimeMillis(); + serverResponse = requestBuilder.delete(); + finalTime = System.currentTimeMillis(); + } + + processServerResponse(serverResponse); + + return response; + } + }; + } public void setRequest(EverestRequest request) { this.request = request; @@ -71,10 +137,14 @@ public abstract class RequestManager extends Service { requestBuilder.header("User-Agent", "Everest"); } - void processServerResponse(Response serverResponse) - throws UnreliableResponseException, RedirectException { + /** + * Takes a ServerResponse and extracts all the headers, the body, the response time and other details + * into a EverestResponse. + */ + private void processServerResponse(Response serverResponse) + throws NullResponseException, RedirectException { if (serverResponse == null) { - throw new UnreliableResponseException("The server did not respond.", + throw new NullResponseException("The server did not respond.", "Like that crush from high school.."); } else if (serverResponse.getStatus() == 301 || serverResponse.getStatus() == 302) { throw new RedirectException( @@ -108,4 +178,122 @@ public abstract class RequestManager extends Service { removeEventHandler(WorkerStateEvent.WORKER_STATE_FAILED, getOnFailed()); removeEventHandler(WorkerStateEvent.WORKER_STATE_CANCELLED, getOnCancelled()); } + + /** + * Adds the request body based on the content type and generates an invocation. + * Used for DataRequests. + * + * @return invocation object + */ + private Invocation appendBody(DataRequest dataRequest) throws Exception { + /* + Checks if a custom mime-type is mentioned in the headers. + If present, it will override the logical Content-Type. + */ + String overriddenContentType = request.getHeaders().get("Content-Type"); + Invocation invocation = null; + Map.Entry mapEntry; + String requestType = dataRequest.getRequestType(); + + switch (dataRequest.getContentType()) { + case MediaType.MULTIPART_FORM_DATA: + FormDataMultiPart formData = new FormDataMultiPart(); + + // Adding the string tuples to the request + HashMap pairs = dataRequest.getStringTuples(); + for (Map.Entry entry : pairs.entrySet()) { + mapEntry = (Map.Entry) entry; + formData.field(mapEntry.getKey(), mapEntry.getValue()); + } + + String filePath; + File file; + boolean fileException = false; + String fileExceptionMessage = null; + pairs = dataRequest.getFileTuples(); + + // Adding the file tuples to the request + for (Map.Entry entry : pairs.entrySet()) { + mapEntry = (Map.Entry) entry; + filePath = mapEntry.getValue(); + file = new File(filePath); + + if (file.exists()) + formData.bodyPart(new FileDataBodyPart(mapEntry.getKey(), + file, MediaType.APPLICATION_OCTET_STREAM_TYPE)); + else { + fileException = true; + // For pretty-printing FileNotFoundException to the UI + fileExceptionMessage = " - " + filePath + "\n"; + } + } + + if (fileException) { + throw new FileNotFoundException(fileExceptionMessage); + } + + formData.setMediaType(MediaType.MULTIPART_FORM_DATA_TYPE); + + if (requestType.equals("POST")) + invocation = requestBuilder.buildPost(Entity.entity(formData, MediaType.MULTIPART_FORM_DATA_TYPE)); + else + invocation = requestBuilder.buildPut(Entity.entity(formData, MediaType.MULTIPART_FORM_DATA_TYPE)); + break; + case MediaType.APPLICATION_OCTET_STREAM: + if (overriddenContentType == null) + overriddenContentType = MediaType.APPLICATION_OCTET_STREAM; + filePath = dataRequest.getBody(); + + File check = new File(filePath); + + if (!check.exists()) { + throw new FileNotFoundException(filePath); + } + + FileInputStream stream = new FileInputStream(filePath); + + if (requestType.equals("POST")) + invocation = requestBuilder.buildPost(Entity.entity(stream, overriddenContentType)); + else + invocation = requestBuilder.buildPut(Entity.entity(stream, overriddenContentType)); + break; + case MediaType.APPLICATION_FORM_URLENCODED: + if (overriddenContentType == null) + overriddenContentType = MediaType.APPLICATION_FORM_URLENCODED; + + Form form = new Form(); + + for (Map.Entry entry : dataRequest.getStringTuples().entrySet()) { + mapEntry = (Map.Entry) entry; + form.param(mapEntry.getKey(), mapEntry.getValue()); + } + + if (requestType.equals("POST")) + invocation = requestBuilder.buildPost(Entity.entity(form, overriddenContentType)); + else + invocation = requestBuilder.buildPut(Entity.entity(form, overriddenContentType)); + break; + default: + // Handles raw data types (JSON, Plain text, XML, HTML) + String originalContentType = dataRequest.getContentType(); + if (overriddenContentType == null) + overriddenContentType = originalContentType; + switch (requestType) { + case "POST": + invocation = requestBuilder + .buildPost(Entity.entity(dataRequest.getBody(), overriddenContentType)); + break; + case "PUT": + invocation = requestBuilder + .buildPut(Entity.entity(dataRequest.getBody(), overriddenContentType)); + break; + case "PATCH": + invocation = requestBuilder + .build("PATCH", Entity.entity(dataRequest.getBody(), overriddenContentType)); + break; + } + } + + return invocation; + } } diff --git a/src/main/java/com/rohitawate/everest/requestmanager/RequestManagersPool.java b/src/main/java/com/rohitawate/everest/requestmanager/RequestManagersPool.java index fcc921e..df58982 100644 --- a/src/main/java/com/rohitawate/everest/requestmanager/RequestManagersPool.java +++ b/src/main/java/com/rohitawate/everest/requestmanager/RequestManagersPool.java @@ -19,70 +19,26 @@ package com.rohitawate.everest.requestmanager; import java.util.ArrayList; /** - * Provides the various RequestManagers employed by Everest. + * Provides a dynamically-growing pool RequestManagers used by Everest. *

- * 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. - *

- * When demanding a RequestManager, the pool is checked linearly. + * The manager() method when invoked, searches the pool 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. + * a new one will be created, added to the pool, and returned. */ public class RequestManagersPool { - private static ArrayList getManagers; - private static ArrayList dataManagers; - private static ArrayList deleteManagers; + private static ArrayList pool = new ArrayList<>(); - public static GETRequestManager get() { - if (getManagers == null) - getManagers = new ArrayList<>(); - - for (GETRequestManager getManager : getManagers) { - if (!getManager.isRunning()) { - getManager.reset(); - return getManager; + public static RequestManager manager() { + for (RequestManager manager: pool) { + if (!manager.isRunning()) { + manager.reset(); + return manager; } } - GETRequestManager newManager = new GETRequestManager(); - getManagers.add(newManager); - - return newManager; - } - - public static DataRequestManager data() { - if (dataManagers == null) - dataManagers = new ArrayList<>(); - - for (DataRequestManager dataManager : dataManagers) { - if (!dataManager.isRunning()) { - dataManager.reset(); - return dataManager; - } - } - - DataRequestManager newManager = new DataRequestManager(); - dataManagers.add(newManager); - - return newManager; - } - - public static DELETERequestManager delete() { - if (deleteManagers == null) - deleteManagers = new ArrayList<>(); - - for (DELETERequestManager deleteManager : deleteManagers) { - if (!deleteManager.isRunning()) { - deleteManager.reset(); - return deleteManager; - } - } - - DELETERequestManager newManager = new DELETERequestManager(); - deleteManagers.add(newManager); + RequestManager newManager = new RequestManager(); + pool.add(newManager); return newManager; }