From 77cfc0d9bdd711be3f6dd585d4850efb35e9159e Mon Sep 17 00:00:00 2001 From: Trisha Anand Date: Thu, 30 Jan 2020 09:48:48 +0000 Subject: [PATCH] All the page load actions and their dependent page load actions now are stored as part of on page load actions --- .../com/appsmith/server/domains/Layout.java | 7 +- .../server/exceptions/AppsmithError.java | 13 +- .../services/LayoutActionServiceImpl.java | 113 +++++++++++------- 3 files changed, 81 insertions(+), 52 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Layout.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Layout.java index 2a7268a403..ef535d3568 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Layout.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/domains/Layout.java @@ -8,6 +8,7 @@ import lombok.Setter; import lombok.ToString; import net.minidev.json.JSONObject; +import java.util.List; import java.util.Set; @Getter @@ -29,14 +30,14 @@ public class Layout extends BaseDomain { @Deprecated Set layoutActions; - Set layoutOnLoadActions; + List> layoutOnLoadActions; @Deprecated @JsonIgnore Set publishedLayoutActions; @JsonIgnore - Set publishedLayoutOnLoadActions; + List> publishedLayoutOnLoadActions; @JsonIgnore Set widgetNames; @@ -54,7 +55,7 @@ public class Layout extends BaseDomain { return viewMode ? publishedLayoutActions : layoutActions; } - public Set getLayoutOnLoadActions() { + public List> getLayoutOnLoadActions() { return viewMode ? publishedLayoutOnLoadActions : layoutOnLoadActions; } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java index 4122d6c790..2eba7a4227 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/exceptions/AppsmithError.java @@ -26,11 +26,14 @@ public enum AppsmithError { PAGE_DOESNT_BELONG_TO_APPLICATION(400, 4018, "Page {0} does not belong to the application {1}"), UNAUTHORIZED_DOMAIN(401, 4019, "Invalid email domain provided. Please sign in with a valid work email ID"), INVALID_PASSWORD_RESET(400, 4020, "Unable to reset the password. Please initiate a request via 'forgot password' link to reset your password"), - NO_RESOURCE_FOUND(404, 4021, "Unable to find {0} with id {1}"), - UNAUTHORIZED_ACCESS(401, 4022, "Unauthorized access"), - INVALID_DATASOURCE_NAME(400, 4023, "Datasource name is invalid"), - DUPLICATE_KEY(409, 4024, "Unable to save the object in the database. Detailed error message: {0}"), - GENERIC_BAD_REQUEST(400, 4025, "Bad Request: {0}"), + LOGIN_INTERNAL_ERROR(401, 4021, "Internal error while trying to login"), + JSON_PROCESSING_ERROR(400, 4022, "Json processing error with error {0}"), + INVALID_CREDENTIALS(200, 4023, "Invalid credentials provided. Did you input the credentials correctly?"), + DUPLICATE_KEY(409, 4024, "Duplicate key error"), + UNAUTHORIZED_ACCESS(401, 4025, "Unauthorized access"), + INVALID_DATASOURCE_NAME(400, 4026, "Datasource name is invalid"), + NO_RESOURCE_FOUND(404, 4027, "Unable to find {0} with id {1}"), + GENERIC_BAD_REQUEST(400, 4028, "Bad Request: {0}"), INTERNAL_SERVER_ERROR(500, 5000, "Internal server error while processing request"), REPOSITORY_SAVE_FAILED(500, 5001, "Repository save failed"), PLUGIN_INSTALLATION_FAILED_DOWNLOAD_ERROR(500, 5002, "Due to error in downloading the plugin from remote repository, plugin installation has failed. Check the jar location and try again"), diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java index 2003f36d5a..06aceccd32 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/services/LayoutActionServiceImpl.java @@ -82,6 +82,7 @@ public class LayoutActionServiceImpl implements LayoutActionService { dslString = objectMapper.writeValueAsString(dsl); } catch (JsonProcessingException e) { log.debug("Exception caught during conversion of DSL Json object to String. ", e); + Mono.error(new AppsmithException(AppsmithError.JSON_PROCESSING_ERROR, e.getMessage())); } Set widgetNames = new HashSet<>(); @@ -95,46 +96,23 @@ public class LayoutActionServiceImpl implements LayoutActionService { Set dynamicBindingNames = new HashSet<>(); if (!dynamicBindings.isEmpty()) { for (String mustacheKey : dynamicBindings) { - String key = mustacheKey.trim(); - // Extract all the words in the dynamic bindings - Matcher matcher = pattern.matcher(key); - - while (matcher.find()) { - String word = matcher.group(); - - String[] subStrings = word.split(Pattern.quote(".")); - if (subStrings.length > 0) { - // We are only interested in the top level. e.g. if its Input1.text, we want just Input1 - dynamicBindingNames.add(subStrings[0]); - } - } + extractWordsAndAddToSet(dynamicBindingNames, mustacheKey); } } return dynamicBindingNames; }); - - Mono> onLoadActionsMono = dynamicBindingNamesMono - .flatMapMany(dynamicBindingNames -> findRestApiActionsByPageIdAndHTTPMethodGET(dynamicBindingNames, pageId)) - .map(action -> { - // Since we are only interested in few fields, prepare the DslActionDTO that needs to be stored in - // the layout and return it to be collected in to a set. - DslActionDTO newAction = new DslActionDTO(); - newAction.setId(action.getId()); - newAction.setPluginType(action.getPluginType()); - newAction.setJsonPathKeys(action.getJsonPathKeys()); - newAction.setName(action.getName()); - return newAction; - }) - .collect(toSet()); + List> onLoadActionsList = new ArrayList<>(); + Mono>> onLoadActionsMono = dynamicBindingNamesMono + .flatMap(dynamicBindingNames -> findOnLoadActionsInPage(onLoadActionsList, dynamicBindingNames, pageId)); return pageService.findByIdAndLayoutsId(pageId, layoutId) .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.PAGE_ID + " or " + FieldName.LAYOUT_ID))) .zipWith(onLoadActionsMono) .map(tuple -> { Page page = tuple.getT1(); - Set onLoadActions = tuple.getT2(); + List> onLoadActions = tuple.getT2(); List layoutList = page.getLayouts(); @@ -143,7 +121,7 @@ public class LayoutActionServiceImpl implements LayoutActionService { if (storedLayout.getId().equals(layoutId)) { //Copy the variables to conserve before update JSONObject publishedDsl = storedLayout.getPublishedDsl(); - Set publishedLayoutOnLoadActions = storedLayout.getPublishedLayoutOnLoadActions(); + List> publishedLayoutOnLoadActions = storedLayout.getPublishedLayoutOnLoadActions(); //Update layout.setLayoutOnLoadActions(onLoadActions); @@ -171,6 +149,53 @@ public class LayoutActionServiceImpl implements LayoutActionService { }); } + private Mono>> findOnLoadActionsInPage(List> onLoadActions, Set dynamicBindingNames, String pageId) { + if (dynamicBindingNames == null || dynamicBindingNames.isEmpty()) { + return Mono.just(onLoadActions); + } + Set bindingNames = new HashSet<>(); + return findRestApiActionsByPageIdAndHTTPMethodGET(dynamicBindingNames, pageId) + .map(action -> { + for (String mustacheKey : action.getJsonPathKeys()) { + extractWordsAndAddToSet(bindingNames, mustacheKey); + } + DslActionDTO newAction = new DslActionDTO(); + newAction.setId(action.getId()); + newAction.setPluginType(action.getPluginType()); + newAction.setJsonPathKeys(action.getJsonPathKeys()); + newAction.setName(action.getName()); + return newAction; + }) + .collect(toSet()) + .flatMap(actions -> { + Set onLoadSet = new HashSet<>(); + onLoadSet.addAll(actions); + + // If the resultant set of actions is empty, don't add it to the array list. + if (!onLoadSet.isEmpty()) { + onLoadActions.add(0, onLoadSet); + } + return findOnLoadActionsInPage(onLoadActions, bindingNames, pageId); + }); + } + + private void extractWordsAndAddToSet(Set bindingNames, String mustacheKey) { + String key = mustacheKey.trim(); + + // Extract all the words in the dynamic bindings + Matcher matcher = pattern.matcher(key); + + while (matcher.find()) { + String word = matcher.group(); + + String[] subStrings = word.split(Pattern.quote(".")); + if (subStrings.length > 0) { + // We are only interested in the top level. e.g. if its Input1.text, we want just Input1 + bindingNames.add(subStrings[0]); + } + } + } + /** * Given a list of names of actions (nodes) and pageId, it hits the database and returns all the actions matching * this criteria of name and pageId with http method 'GET' @@ -206,19 +231,19 @@ public class LayoutActionServiceImpl implements LayoutActionService { .flatMap(savedAction -> pageService .findById(oldPageId) .map(page -> { - if (page.getLayouts() == null) { - return Mono.empty(); - } + if (page.getLayouts() == null) { + return Mono.empty(); + } - return page.getLayouts() - .stream() - /* - * subscribe() is being used here because within a stream, the master subscriber provided - * by spring framework does not get attached here leading to the updateLayout mono not - * emitting. The same is true for the updateLayout call for the new page. - */ - .map(layout -> updateLayout(oldPageId, layout.getId(), layout).subscribe()) - .collect(toSet()); + return page.getLayouts() + .stream() + /* + * subscribe() is being used here because within a stream, the master subscriber provided + * by spring framework does not get attached here leading to the updateLayout mono not + * emitting. The same is true for the updateLayout call for the new page. + */ + .map(layout -> updateLayout(oldPageId, layout.getId(), layout).subscribe()) + .collect(toSet()); }) .then(pageService.findById(actionMoveDTO.getDestinationPageId())) .map(page -> { @@ -227,9 +252,9 @@ public class LayoutActionServiceImpl implements LayoutActionService { } return page.getLayouts() - .stream() - .map(layout -> updateLayout(actionMoveDTO.getDestinationPageId(), layout.getId(), layout).subscribe()) - .collect(toSet()); + .stream() + .map(layout -> updateLayout(actionMoveDTO.getDestinationPageId(), layout.getId(), layout).subscribe()) + .collect(toSet()); }) .thenReturn(savedAction)); }