From d5fcd91148a86780c953a0dafabcae245696baf4 Mon Sep 17 00:00:00 2001 From: nsingh Date: Thu, 2 Nov 2017 13:10:13 -0700 Subject: [PATCH] Refactored live conditionals so that they are parsed via SpringBootApp API --- .../ConditionalsLiveHoverProvider.java | 188 +++++------------- .../boot/java/utils/HoverContentUtils.java | 6 +- .../test/ConditionalsLiveHoverTest.java | 12 +- .../harness/MockRunningAppProvider.java | 11 +- .../commons/boot/app/cli/LiveConditional.java | 75 ++++++- .../boot/app/cli/LiveConditionalParser.java | 121 +++++++++++ .../commons/boot/app/cli/SpringBootApp.java | 19 ++ 7 files changed, 280 insertions(+), 152 deletions(-) create mode 100644 headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/LiveConditionalParser.java diff --git a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/conditionals/ConditionalsLiveHoverProvider.java b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/conditionals/ConditionalsLiveHoverProvider.java index 5056d9fe6..80e8c0eff 100644 --- a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/conditionals/ConditionalsLiveHoverProvider.java +++ b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/conditionals/ConditionalsLiveHoverProvider.java @@ -12,7 +12,6 @@ package org.springframework.ide.vscode.boot.java.conditionals; import java.util.ArrayList; import java.util.Collection; -import java.util.Iterator; import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; @@ -27,13 +26,10 @@ import org.eclipse.lsp4j.Hover; import org.eclipse.lsp4j.MarkedString; import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.jsonrpc.messages.Either; -import org.json.JSONArray; -import org.json.JSONObject; import org.springframework.ide.vscode.boot.java.handlers.HoverProvider; import org.springframework.ide.vscode.boot.java.utils.HoverContentUtils; import org.springframework.ide.vscode.commons.boot.app.cli.LiveConditional; import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp; -import org.springframework.ide.vscode.commons.util.BadLocationException; import org.springframework.ide.vscode.commons.util.Log; import org.springframework.ide.vscode.commons.util.text.TextDocument; @@ -55,28 +51,45 @@ public class ConditionalsLiveHoverProvider implements HoverProvider { @Override public Collection getLiveHoverHints(Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) { try { - if (runningApps.length > 0) { - ConditionalParserFromRunningApp parser = new ConditionalParserFromRunningApp(); - Optional> val = parser.parse(annotation, runningApps); - if (val.isPresent()) { - Range hoverRange = doc.toRange(annotation.getStartPosition(), annotation.getLength()); - return ImmutableList.of(hoverRange); - } + Optional> val = getMatchedLiveConditionals(annotation, runningApps); + if (val.isPresent()) { + Range hoverRange = doc.toRange(annotation.getStartPosition(), annotation.getLength()); + return ImmutableList.of(hoverRange); } - } catch (BadLocationException e) { + } catch (Exception e) { Log.log(e); } return null; } + private Optional> getMatchedLiveConditionals(Annotation annotation, + SpringBootApp[] runningApps) throws Exception { + if (runningApps != null) { + List all = new ArrayList<>(); + + for (SpringBootApp springBootApp : runningApps) { + springBootApp.getLiveConditionals().ifPresent((conditionals) -> { + conditionals.stream().forEach((conditional) -> { + if (matchesAnnotation(annotation, conditional)) { + all.add(conditional); + } + }); + }); + } + if (!all.isEmpty()) { + return Optional.of(all); + } + } + return Optional.empty(); + } + private CompletableFuture provideHover(Annotation annotation, TextDocument doc, SpringBootApp[] runningApps) { try { List> hoverContent = new ArrayList<>(); - ConditionalParserFromRunningApp parser = new ConditionalParserFromRunningApp(); - Optional> val = parser.parse(annotation, runningApps); + Optional> val = getMatchedLiveConditionals(annotation, runningApps); if (val.isPresent()) { addHoverContent(val.get(), hoverContent); @@ -96,138 +109,43 @@ public class ConditionalsLiveHoverProvider implements HoverProvider { return null; } - private void addHoverContent(List conditions, - List> hoverContent) throws Exception { - for (int i = 0; i < conditions.size(); i++) { - LiveConditional condition = conditions.get(i); - hoverContent.add(Either.forLeft(condition.message)); - hoverContent.add(Either - .forLeft(HoverContentUtils.getProcessInformation(condition.app))); + private void addHoverContent(List conditionals, List> hoverContent) + throws Exception { + for (int i = 0; i < conditionals.size(); i++) { + LiveConditional conditional = conditionals.get(i); + hoverContent.add(Either.forLeft(conditional.getMessage())); + hoverContent.add(Either.forLeft(HoverContentUtils.getProcessInformation(conditional.getProcessId(), conditional.getProcessName()))); - if (i < conditions.size() - 1) { + if (i < conditionals.size() - 1) { hoverContent.add(Either.forLeft("---")); } } } /** - * Parsers @ConditionalOn annotations from a spring boot running app's - * autoconfig report. An example of a conditional that is parsed from a running - * app's autoconfig report would be: - * - * {"TraceRepositoryAutoConfiguration#traceRepository":[{"condition":"OnBeanCondition","message":"@ConditionalOnMissingBean - * (types: org.springframework.boot.actuate.trace.TraceRepository; - * SearchStrategy: all) did not find any beans"}] * + * @param annotation + * @param jsonKey + * @return true if the annotation matches the information in the json key from + * the running app. */ - public static class ConditionalParserFromRunningApp { + protected boolean matchesAnnotation(Annotation annotation, LiveConditional liveConditional) { - public Optional> parse(Annotation annotation, SpringBootApp[] runningApps) { + ASTNode parent = annotation.getParent(); + String rawJsonKey = liveConditional.getPositiveMatchKey(); - try { - List allConditionals = new ArrayList<>(); - for (SpringBootApp app : runningApps) { - String autoConfigRecord = app.getAutoConfigReport(); - if (autoConfigRecord != null) { - JSONObject autoConfigJson = new JSONObject(autoConfigRecord); - List conditionalsFromPositiveMatches = getConditionals(app, annotation, - autoConfigJson); - if (!conditionalsFromPositiveMatches.isEmpty()) { - allConditionals.addAll(conditionalsFromPositiveMatches); - } - } - } - if (!allConditionals.isEmpty()) { - return Optional.of(allConditionals); - } - } catch (Exception e) { - Log.log(e); - } - return Optional.empty(); - } - - /** - * - * @param app - * @param annotation - * @param autoConfigJson - * @return non-null list of conditionals parsed from an autoconfig report. List - * may be empty. - */ - private List getConditionals(SpringBootApp app, Annotation annotation, - JSONObject autoConfigJson) { - List conditions = new ArrayList<>(); - - getPositiveMatches(autoConfigJson).ifPresent((positiveMatches) -> { - Iterator pMKeys = positiveMatches.keys(); - while (pMKeys.hasNext()) { - String positiveMatchKey = pMKeys.next(); - if (matchesAnnotation(annotation, positiveMatchKey)) { - JSONArray matchList = (JSONArray) positiveMatches.get(positiveMatchKey); - matchList.forEach((match) -> { - if (match instanceof JSONObject) { - getMatchedCondition(app, (JSONObject) match, annotation) - .ifPresent((condition) -> conditions.add(condition)); - } - }); - } - } - }); - - return conditions; - } - - protected Optional getPositiveMatches(JSONObject autoConfigJson) { - - Iterator keys = autoConfigJson.keys(); - - while (keys.hasNext()) { - String key = keys.next(); - if ("positiveMatches".equals(key)) { - Object obj = autoConfigJson.get(key); - if (obj instanceof JSONObject) { - return Optional.of((JSONObject) obj); - } - } - } - return Optional.empty(); - } - - /** - * - * @param annotation - * @param jsonKey - * @return true if the annotation matches the information in the json key from - * the running app. - */ - protected boolean matchesAnnotation(Annotation annotation, String jsonKey) { - - ASTNode parent = annotation.getParent(); - if (parent instanceof MethodDeclaration) { - MethodDeclaration methodDec = (MethodDeclaration) parent; - IMethodBinding binding = methodDec.resolveBinding(); - String annotationDeclaringClassName = binding.getDeclaringClass().getName(); - String annotationMethodName = binding.getName(); - return jsonKey.contains(annotationDeclaringClassName) && jsonKey.contains(annotationMethodName); - } else if (parent instanceof TypeDeclaration) { - TypeDeclaration typeDec = (TypeDeclaration) parent; - String annotationDeclaringClassName = typeDec.resolveBinding().getName(); - return jsonKey.contains(annotationDeclaringClassName); - } - return false; - } - - protected Optional getMatchedCondition(SpringBootApp app, JSONObject conditionJson, - Annotation annotation) { - if (conditionJson != null) { - String condition = (String) conditionJson.get("condition"); - String message = (String) conditionJson.get("message"); - String annotationName = annotation.resolveTypeBinding().getName(); - if (message.contains(annotationName)) { - return Optional.of(new LiveConditional(app, condition, message)); - } - } - return Optional.empty(); + if (parent instanceof MethodDeclaration) { + MethodDeclaration methodDec = (MethodDeclaration) parent; + IMethodBinding binding = methodDec.resolveBinding(); + String annotationDeclaringClassName = binding.getDeclaringClass().getName(); + String annotationMethodName = binding.getName(); + return rawJsonKey.contains(annotationDeclaringClassName) && rawJsonKey.contains(annotationMethodName); + } else if (parent instanceof TypeDeclaration) { + TypeDeclaration typeDec = (TypeDeclaration) parent; + String annotationDeclaringClassName = typeDec.resolveBinding().getName(); + return rawJsonKey.contains(annotationDeclaringClassName); } + return false; } + } diff --git a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/HoverContentUtils.java b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/HoverContentUtils.java index 5b34dea3c..7998a8443 100644 --- a/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/HoverContentUtils.java +++ b/headless-services/boot-java-language-server/src/main/java/org/springframework/ide/vscode/boot/java/utils/HoverContentUtils.java @@ -15,7 +15,11 @@ import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp; public class HoverContentUtils { public static String getProcessInformation(SpringBootApp app) { - return "Process " + app.getProcessID() + ": " + app.getProcessName(); + return getProcessInformation(app.getProcessID(), app.getProcessName()); + } + + public static String getProcessInformation(String processId, String processName) { + return "Process " + processId + ": " + processName; } } diff --git a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/conditionals/test/ConditionalsLiveHoverTest.java b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/conditionals/test/ConditionalsLiveHoverTest.java index ce876ca07..354c5cc64 100644 --- a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/conditionals/test/ConditionalsLiveHoverTest.java +++ b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/boot/java/conditionals/test/ConditionalsLiveHoverTest.java @@ -67,7 +67,7 @@ public class ConditionalsLiveHoverTest { // Build a mock running boot app mockAppProvider.builder().isSpringBootApp(true).port("1111").processId("22022").host("cfapps.io") .processName("test-conditionals-live-hover") - .getAutoConfigReport( + .getLiveConditionals( "{\"positiveMatches\":{\"ConditionalOnBeanConfig#hi\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnBean (types: example.Hello; SearchStrategy: all) found bean 'missing'\"}]}}") .build(); @@ -91,7 +91,7 @@ public class ConditionalsLiveHoverTest { // Build a mock running boot app mockAppProvider.builder().isSpringBootApp(true).port("1111").processId("22022").host("cfapps.io") .processName("test-conditionals-live-hover") - .getAutoConfigReport( + .getLiveConditionals( "{\"positiveMatches\":{\"ConditionalOnMissingBeanConfig#missing\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnMissingBean (types: example.Hello; SearchStrategy: all) did not find any beans\"}]}}") .build(); @@ -114,7 +114,7 @@ public class ConditionalsLiveHoverTest { // Build a mock running boot app mockAppProvider.builder().isSpringBootApp(true).port("1111").processId("22022").host("cfapps.io") .processName("test-conditionals-live-hover") - .getAutoConfigReport( + .getLiveConditionals( "{\"positiveMatches\":{\"HelloConfig#missing\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnMissingBean (types: example.Hello; SearchStrategy: all) did not find any beans\"}],\"HelloConfig2#hi\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnBean (types: example.Hello; SearchStrategy: all) found bean 'missing'\"}],\"MultipleConditionals#hi\":[{\"condition\":\"OnClassCondition\",\"message\":\"@ConditionalOnClass found required class; @ConditionalOnMissingClass did not find unwanted class\"},{\"condition\":\"OnWebApplicationCondition\",\"message\":\"@ConditionalOnWebApplication (required) found StandardServletEnvironment\"},{\"condition\":\"OnJavaCondition\",\"message\":\"@ConditionalOnJava (1.8 or newer) found 1.8\"},{\"condition\":\"OnExpressionCondition\",\"message\":\"@ConditionalOnExpression (#{true}) resulted in true\"},{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnBean (types: example.Hello; SearchStrategy: all) found beans 'hi', 'missing'\"}]}}") .build(); @@ -156,19 +156,19 @@ public class ConditionalsLiveHoverTest { // Build a mock running boot app mockAppProvider.builder().isSpringBootApp(true).port("1000").processId("70000").host("cfapps.io") .processName("test-conditionals-live-hover") - .getAutoConfigReport( + .getLiveConditionals( "{\"positiveMatches\":{\"ConditionalOnMissingBeanConfig#missing\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnMissingBean (types: example.Hello; SearchStrategy: all) did not find any beans\"}]}}") .build(); mockAppProvider.builder().isSpringBootApp(true).port("1001").processId("80000").host("cfapps.io") .processName("test-conditionals-live-hover") - .getAutoConfigReport( + .getLiveConditionals( "{\"positiveMatches\":{\"ConditionalOnMissingBeanConfig#missing\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnMissingBean (types: example.Hello; SearchStrategy: all) did not find any beans\"}]}}") .build(); mockAppProvider.builder().isSpringBootApp(true).port("1002").processId("90000").host("cfapps.io") .processName("test-conditionals-live-hover") - .getAutoConfigReport( + .getLiveConditionals( "{\"positiveMatches\":{\"ConditionalOnMissingBeanConfig#missing\":[{\"condition\":\"OnBeanCondition\",\"message\":\"@ConditionalOnMissingBean (types: example.Hello; SearchStrategy: all) did not find any beans\"}]}}") .build(); diff --git a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/project/harness/MockRunningAppProvider.java b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/project/harness/MockRunningAppProvider.java index b06af7246..409fd34cb 100644 --- a/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/project/harness/MockRunningAppProvider.java +++ b/headless-services/boot-java-language-server/src/test/java/org/springframework/ide/vscode/project/harness/MockRunningAppProvider.java @@ -19,8 +19,8 @@ import java.util.Collection; import org.mockito.Mockito; import org.springframework.ide.vscode.boot.java.handlers.RunningAppProvider; import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp; -import org.springframework.ide.vscode.commons.boot.app.cli.requestmappings.RequestMapping; import org.springframework.ide.vscode.commons.boot.app.cli.livebean.LiveBeansModel; +import org.springframework.ide.vscode.commons.boot.app.cli.requestmappings.RequestMapping; import org.springframework.ide.vscode.commons.util.ExceptionUtil; import com.google.common.collect.ImmutableList; @@ -57,6 +57,8 @@ public class MockRunningAppProvider { public static class MockAppBuilder { public final SpringBootApp app = mock(SpringBootApp.class); private MockRunningAppProvider runningAppProvider; + private String processId; + private String processName; public MockAppBuilder(MockRunningAppProvider runningAppProvider) { this.runningAppProvider = runningAppProvider; @@ -77,11 +79,13 @@ public class MockRunningAppProvider { } public MockAppBuilder processId(String processId) { + this.processId = processId; when(app.getProcessID()).thenReturn(processId); return this; } public MockAppBuilder processName(String name) { + this.processName = name; when(app.getProcessName()).thenReturn(name); return this; } @@ -112,6 +116,11 @@ public class MockRunningAppProvider { return this; } + public MockAppBuilder getLiveConditionals(String autoConfigReport) throws Exception{ + when(app.getLiveConditionals()).thenReturn(SpringBootApp.getLiveConditionals(autoConfigReport, processId, processName)); + return this; + } + public MockAppBuilder profiles(String... names) { when(app.getActiveProfiles()).thenReturn(ImmutableList.copyOf(names)); return this; diff --git a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/LiveConditional.java b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/LiveConditional.java index b19884db5..664b0f700 100644 --- a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/LiveConditional.java +++ b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/LiveConditional.java @@ -10,17 +10,74 @@ *******************************************************************************/ package org.springframework.ide.vscode.commons.boot.app.cli; -import org.springframework.ide.vscode.commons.boot.app.cli.SpringBootApp; - public class LiveConditional { - public final String condition; - public final String message; - public final SpringBootApp app; + private String condition; + private String message; + private String processId; + private String processName; + private String positiveMatchKey; - public LiveConditional(SpringBootApp app, String condition, String message) { - this.condition = condition; - this.message = message; - this.app = app; + public LiveConditional() { + + } + + public String getCondition() { + return condition; + } + + public String getMessage() { + return message; + } + + public String getProcessId() { + return processId; + } + + public String getProcessName() { + return processName; + } + + public String getPositiveMatchKey() { + return positiveMatchKey; + } + + public static class LiveConditionalBuilder { + + private LiveConditional conditional = new LiveConditional(); + + public LiveConditionalBuilder condition(String condition) { + conditional.condition = condition; + return this; + } + + public LiveConditionalBuilder message(String message) { + conditional.message = message; + return this; + } + + public LiveConditionalBuilder processId(String processId) { + conditional.processId = processId; + return this; + } + + public LiveConditionalBuilder processName(String processName) { + conditional.processName = processName; + return this; + } + + public LiveConditionalBuilder positiveMatchKey(String positiveMatchKey) { + conditional.positiveMatchKey = positiveMatchKey; + return this; + } + + public LiveConditional build() { + return conditional; + } + + } + + public static LiveConditionalBuilder builder() { + return new LiveConditionalBuilder(); } } \ No newline at end of file diff --git a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/LiveConditionalParser.java b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/LiveConditionalParser.java new file mode 100644 index 000000000..5c207cd86 --- /dev/null +++ b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/LiveConditionalParser.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2017 Pivotal, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Pivotal, Inc. - initial API and implementation + *******************************************************************************/ +package org.springframework.ide.vscode.commons.boot.app.cli; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; + +import org.json.JSONArray; +import org.json.JSONObject; +import org.springframework.ide.vscode.commons.util.Log; +import org.springframework.ide.vscode.commons.util.StringUtil; + +/** + * Parsers @ConditionalOn annotations from a spring boot running app's + * autoconfig report. An example of a conditional that is parsed from a running + * app's autoconfig report would be: + * + * {"TraceRepositoryAutoConfiguration#traceRepository":[{"condition":"OnBeanCondition","message":"@ConditionalOnMissingBean + * (types: org.springframework.boot.actuate.trace.TraceRepository; + * SearchStrategy: all) did not find any beans"}] + * + */ +public class LiveConditionalParser { + + private final String autoConfigRecord; + private final String appProcessName; + private final String appProcessId; + + public LiveConditionalParser(String autoConfigRecord, String appProcessId, String appProcessName) { + this.autoConfigRecord = autoConfigRecord; + this.appProcessId = appProcessId; + this.appProcessName = appProcessName; + } + + public Optional> parse() { + + try { + List allConditionals = new ArrayList<>(); + + if (StringUtil.hasText(autoConfigRecord)) { + getConditionalsFromPositiveMatches(autoConfigRecord).stream() + .forEach(conditional -> allConditionals.add(conditional)); + } + if (!allConditionals.isEmpty()) { + return Optional.of(allConditionals); + } + } catch (Exception e) { + Log.log(e); + } + return Optional.empty(); + } + + private Optional getPositiveMatchesJson(String autoConfigReport) { + JSONObject autoConfigJson = new JSONObject(autoConfigReport); + + Iterator keys = autoConfigJson.keys(); + + while (keys.hasNext()) { + String key = keys.next(); + if ("positiveMatches".equals(key)) { + Object obj = autoConfigJson.get(key); + if (obj instanceof JSONObject) { + return Optional.of((JSONObject) obj); + } + } + } + + return Optional.empty(); + } + + private List getConditionalsFromPositiveMatches(String autoconfigReport) { + List conditions = new ArrayList<>(); + + getPositiveMatchesJson(autoconfigReport).ifPresent((positiveMatches) -> { + Iterator pMKeys = positiveMatches.keys(); + while (pMKeys.hasNext()) { + // The positive match key contains the bean method information where conditional + // was applied to + String positiveMatchKey = pMKeys.next(); + JSONArray matchList = (JSONArray) positiveMatches.get(positiveMatchKey); + matchList.forEach((match) -> { + if (match instanceof JSONObject) { + resolveConditional(positiveMatchKey, (JSONObject) match) + .ifPresent((condition) -> conditions.add(condition)); + } + }); + } + }); + + return conditions; + } + + private Optional resolveConditional(String positiveMatchKey, JSONObject conditionalJson) { + if (conditionalJson != null) { + String condition = (String) conditionalJson.get("condition"); + String message = (String) conditionalJson.get("message"); + // We care about the message itself as it contains the actual annotation as well + // as the reason it matched + if (StringUtil.hasText(message)) { + return Optional.of(LiveConditional.builder().processId(appProcessId).processName(appProcessName) + .condition(condition).message(message).positiveMatchKey(positiveMatchKey).build()); + } + } + return Optional.empty(); + } + + public static Optional> parse(String autoConfigRecord, String appProcessId, + String appProcessName) { + return new LiveConditionalParser(autoConfigRecord, appProcessId, appProcessName).parse(); + } +} diff --git a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/SpringBootApp.java b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/SpringBootApp.java index a6207d5dd..3a6daeaaa 100644 --- a/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/SpringBootApp.java +++ b/headless-services/commons/commons-boot-app-cli/src/main/java/org/springframework/ide/vscode/commons/boot/app/cli/SpringBootApp.java @@ -19,6 +19,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; +import java.util.Optional; import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; @@ -235,6 +236,24 @@ public class SpringBootApp { return null; } + public Optional> getLiveConditionals() throws Exception { + return getLiveConditionals(getAutoConfigReport(), getProcessID(), getProcessName()); + } + + /** + * Publicly visible so that it can be tested via a mock app + * + * @param autoConfigReport + * @param processId + * @param processName + * @return + * @throws Exception + */ + public static Optional> getLiveConditionals(String autoConfigReport, String processId, + String processName) { + return new LiveConditionalParser(autoConfigReport, processId, processName).parse(); + } + public String getAutoConfigReport() throws Exception { Object result = getActuatorDataFromAttribute("org.springframework.boot:type=Endpoint,name=autoConfigurationReportEndpoint", "Data"); if (result != null) {