@ConditionalOnExpression SPEL wrapped in #{} and not

This commit is contained in:
aboyko
2024-09-15 13:03:08 -04:00
parent 0f0696ba3a
commit 80de787224
2 changed files with 166 additions and 14 deletions

View File

@@ -57,8 +57,8 @@ public final class AnnotationParamSpelExtractor {
new AnnotationParamSpelExtractor(SPRING_POST_FILTER, null, "", ""),
new AnnotationParamSpelExtractor(SPRING_POST_FILTER, "value", "", ""),
new AnnotationParamSpelExtractor(SPRING_CONDITIONAL_ON_EXPRESSION, null, "", ""),
new AnnotationParamSpelExtractor(SPRING_CONDITIONAL_ON_EXPRESSION, "value", "", ""),
new AnnotationParamSpelExtractor(SPRING_CONDITIONAL_ON_EXPRESSION, null, "#{", "}", true),
new AnnotationParamSpelExtractor(SPRING_CONDITIONAL_ON_EXPRESSION, "value", "#{", "}", true),
new AnnotationParamSpelExtractor(Annotations.SCHEDULED, "cron", "#{", "}"),
};
@@ -66,19 +66,27 @@ public final class AnnotationParamSpelExtractor {
public record Snippet(String text, int offset) {}
public record PrefixSuffix(String prefix, String suffix) {}
private final String annotationType;
private final String paramName;
private final String paramValuePrefix;
private final String paramValuePostfix;
private final List<PrefixSuffix> prefixSuffixes;
public AnnotationParamSpelExtractor(String annotationType, String paramName, String paramValuePrefix,
String paramValuePostfix) {
String paramValueSuffix) {
this.annotationType = annotationType;
this.paramName = paramName;
this.paramValuePrefix = paramValuePrefix;
this.paramValuePostfix = paramValuePostfix;
this.prefixSuffixes = List.of(new PrefixSuffix(paramValuePrefix, paramValueSuffix));
}
public AnnotationParamSpelExtractor(String annotationType, String paramName, String paramValuePrefix,
String paramValueSuffx, boolean optinalPrefixAndSuffix) {
this.annotationType = annotationType;
this.paramName = paramName;
this.prefixSuffixes = List.of(new PrefixSuffix(paramValuePrefix, paramValueSuffx), new PrefixSuffix("", ""));
}
public Optional<Snippet> getSpelRegion(NormalAnnotation a) {
if (paramName == null) {
return Optional.empty();
@@ -128,13 +136,15 @@ public final class AnnotationParamSpelExtractor {
String value = valueExp.getEscapedValue();
value = value.substring(1, value.length() - 1);
if (value != null) {
int startIdx = value.indexOf(paramValuePrefix);
if (startIdx >= 0) {
int endIdx = value.lastIndexOf(paramValuePostfix);
if (endIdx >= 0) {
String spelText = value.substring(startIdx + paramValuePrefix.length(), endIdx);
int offset = valueExp.getStartPosition() + startIdx + paramValuePrefix.length() + 1;
return Optional.of(new Snippet(spelText, offset));
for (PrefixSuffix ps : prefixSuffixes) {
int startIdx = value.indexOf(ps.prefix);
if (startIdx >= 0) {
int endIdx = value.lastIndexOf(ps.suffix);
if (endIdx >= 0) {
String spelText = value.substring(startIdx + ps.prefix.length(), endIdx);
int offset = valueExp.getStartPosition() + startIdx + ps.prefix.length() + 1;
return Optional.of(new Snippet(spelText, offset));
}
}
}
}

View File

@@ -0,0 +1,142 @@
/*******************************************************************************
* Copyright (c) 2024 Broadcom, 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
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Broadcom, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.spel;
import java.io.File;
import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.ide.vscode.boot.bootiful.BootLanguageServerTest;
import org.springframework.ide.vscode.boot.bootiful.SymbolProviderTestConf;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.languageserver.util.Settings;
import org.springframework.ide.vscode.commons.util.text.LanguageId;
import org.springframework.ide.vscode.languageserver.testharness.Editor;
import org.springframework.ide.vscode.project.harness.BootLanguageServerHarness;
import org.springframework.ide.vscode.project.harness.ProjectsHarness;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
@ExtendWith(SpringExtension.class)
@BootLanguageServerTest
@Import(SymbolProviderTestConf.class)
public class JdtSpelReconcilerTest {
@Autowired
private BootLanguageServerHarness harness;
@Autowired
private JavaProjectFinder projectFinder;
private File directory;
@BeforeEach
public void setup() throws Exception {
harness.intialize(null);
directory = new File(ProjectsHarness.class.getResource("/test-projects/boot-mysql/").toURI());
String projectDir = directory.toURI().toString();
// trigger project creation
projectFinder.find(new TextDocumentIdentifier(projectDir)).get();
String changedSettings = """
{
"spring-boot": {
"ls": {
"problem": {
"spel": {
"JAVA_SPEL_EXPRESSION_SYNTAX": "ERROR"
}
}
}
}
}
""";
JsonElement settingsAsJson = new Gson().fromJson(changedSettings, JsonElement.class);
harness.changeConfiguration(new Settings(settingsAsJson));
}
@Test
void noErrors_ConditionalOnExpression_1() throws Exception {
String source = """
package example.demo;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@ConditionalOnExpression("${server.port:8080} == 5678")
public class A {
}
""";
String docUri = directory.toPath().resolve("src/main/java/example/demo/A.java").toUri()
.toString();
Editor editor = harness.newEditor(LanguageId.JAVA, source, docUri);
editor.assertProblems();
}
@Test
void noErrors_ConditionalOnExpression_2() throws Exception {
String source = """
package example.demo;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@ConditionalOnExpression("#{${server.port:8080} == 5678}")
public class A {
}
""";
String docUri = directory.toPath().resolve("src/main/java/example/demo/A.java").toUri()
.toString();
Editor editor = harness.newEditor(LanguageId.JAVA, source, docUri);
editor.assertProblems();
}
@Test
void errors_ConditionalOnExpression_1() throws Exception {
String source = """
package example.demo;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@ConditionalOnExpression("${server.port:8080 == 5678")
public class A {
}
""";
String docUri = directory.toPath().resolve("src/main/java/example/demo/A.java").toUri()
.toString();
Editor editor = harness.newEditor(LanguageId.JAVA, source, docUri);
editor.assertProblems("\"|SPEL: mismatched input '<EOF>'");
}
@Test
void errors_ConditionalOnExpression_2() throws Exception {
String source = """
package example.demo;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@ConditionalOnExpression("#{${server.port:8080 == 5678}")
public class A {
}
""";
String docUri = directory.toPath().resolve("src/main/java/example/demo/A.java").toUri()
.toString();
Editor editor = harness.newEditor(LanguageId.JAVA, source, docUri);
editor.assertProblems("}|SPEL: mismatched input '<EOF>'");
}
}