diff --git a/headless-services/commons/pom.xml b/headless-services/commons/pom.xml
index 595acd128..3810585f7 100644
--- a/headless-services/commons/pom.xml
+++ b/headless-services/commons/pom.xml
@@ -81,6 +81,7 @@
2.10
0.4.0-SNAPSHOT
3.2.7
+ 2.0.4.RELEASE
3.8.0.RELEASE
3.1.5.RELEASE
diff --git a/headless-services/spring-boot-language-server/pom.xml b/headless-services/spring-boot-language-server/pom.xml
index 7e6b985a0..4428158c2 100644
--- a/headless-services/spring-boot-language-server/pom.xml
+++ b/headless-services/spring-boot-language-server/pom.xml
@@ -1,17 +1,18 @@
-
4.0.0
spring-boot-language-server
jar
-
+
org.springframework.ide.vscode
commons-parent
0.6.0-SNAPSHOT
../commons/pom.xml
-
+
${project.version}
@@ -22,11 +23,11 @@
file://${project.basedir}/repo
-
+
-
+
org.springframework.ide.eclipse
org.json
1.0
@@ -61,11 +62,13 @@
commons-boot-app-cli
${dependencies.version}
-
+
+ org.springframework.boot
+ spring-boot
+ ${boot-version}
+
+
org.eclipse.jdt
org.eclipse.jdt.core
@@ -132,6 +135,6 @@
-
+
diff --git a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/types/TypeUtil.java b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/types/TypeUtil.java
index 658ac6049..6f35a5f16 100644
--- a/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/types/TypeUtil.java
+++ b/headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/metadata/types/TypeUtil.java
@@ -17,6 +17,7 @@ import static org.springframework.ide.vscode.commons.util.ArrayUtils.lastElement
import java.net.InetAddress;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -34,6 +35,7 @@ import java.util.stream.Stream;
import javax.inject.Provider;
+import org.springframework.boot.convert.DurationStyle;
import org.springframework.ide.vscode.boot.configurationmetadata.Deprecation;
import org.springframework.ide.vscode.boot.java.links.SourceLinkFactory;
import org.springframework.ide.vscode.boot.java.links.SourceLinks;
@@ -58,6 +60,7 @@ import org.springframework.ide.vscode.commons.util.Log;
import org.springframework.ide.vscode.commons.util.MimeTypes;
import org.springframework.ide.vscode.commons.util.Renderables;
import org.springframework.ide.vscode.commons.util.StringUtil;
+import org.springframework.ide.vscode.commons.util.ValueParseException;
import org.springframework.ide.vscode.commons.util.ValueParser;
import com.google.common.collect.ImmutableList;
@@ -95,6 +98,7 @@ public class TypeUtil {
private static final Object OBJECT_TYPE_NAME = Object.class.getName();
private static final String STRING_TYPE_NAME = String.class.getName();
private static final String INET_ADDRESS_TYPE_NAME = InetAddress.class.getName();
+ private static final String DURATION_TYPE_NAME = Duration.class.getName();
private static final String CLASS_TYPE_NAME = Class.class.getName();
public enum BeanPropertyNameMode {
@@ -171,6 +175,7 @@ public class TypeUtil {
"java.lang.Character",
"java.lang.Byte",
INET_ADDRESS_TYPE_NAME,
+ DURATION_TYPE_NAME,
CLASS_TYPE_NAME,
"java.lang.String[]"
));
@@ -178,6 +183,7 @@ public class TypeUtil {
private static final Set ATOMIC_TYPES = new HashSet<>(PRIMITIVE_TYPE_NAMES.keySet());
static {
ATOMIC_TYPES.add(INET_ADDRESS_TYPE_NAME);
+ ATOMIC_TYPES.add(DURATION_TYPE_NAME);
ATOMIC_TYPES.add(STRING_TYPE_NAME);
ATOMIC_TYPES.add(CLASS_TYPE_NAME);
}
@@ -239,6 +245,13 @@ public class TypeUtil {
throw new IllegalArgumentException("Value should be 'true' or 'false'");
}
});
+ VALUE_PARSERS.put(DURATION_TYPE_NAME, (s) -> {
+ try {
+ return DurationStyle.detectAndParse(s);
+ } catch (IllegalArgumentException e) {
+ throw new ValueParseException(e.getMessage());
+ }
+ });
}
public ValueParser getValueParser(Type type) {
diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/test/ApplicationPropertiesEditorTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/test/ApplicationPropertiesEditorTest.java
index 0007223ac..c56194ef0 100644
--- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/test/ApplicationPropertiesEditorTest.java
+++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/test/ApplicationPropertiesEditorTest.java
@@ -78,6 +78,33 @@ public class ApplicationPropertiesEditorTest extends AbstractPropsEditorTest {
editor.assertProblems("problem|extraneous input", "another|mismatched input");
}
+
+ @Test public void bug_158348104() throws Exception {
+ //See: https://www.pivotaltracker.com/story/show/158348104
+ data("spring.activemq.close-timeout", "java.time.Duration", null, null);
+
+ Editor editor;
+
+ editor = newEditor("");
+ editor.assertContextualCompletions("springactcloti",
+ "spring.activemq.close-timeout=<*>"
+ );
+
+ editor = newEditor(
+ "spring.activemq.close-timeout=garbage"
+ );
+ editor.assertProblems("garbage|not a valid duration");
+
+ editor = newEditor(
+ "spring.activemq.close-timeout: 15s"
+ );
+ editor.assertProblems(/*NONE*/);
+
+ editor = newEditor(
+ "spring.activemq.close-timeout: PT10S" //ISO duration format
+ );
+ editor.assertProblems(/*NONE*/);
+ }
@Test public void testServerPortCompletion() throws Exception {
data("server.port", INTEGER, 8080, "Port where server listens for http.");
assertCompletion("ser<*>", "server.port=<*>");
diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/test/ApplicationYamlEditorTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/test/ApplicationYamlEditorTest.java
index 80826454c..e45d57fce 100644
--- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/test/ApplicationYamlEditorTest.java
+++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/test/ApplicationYamlEditorTest.java
@@ -51,6 +51,41 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
////////////////////////////////////////////////////////////////////////////////////////
+ @Test public void bug_158348104() throws Exception {
+ //See: https://www.pivotaltracker.com/story/show/158348104
+ data("spring.activemq.close-timeout", "java.time.Duration", null, null);
+
+ Editor editor;
+
+ editor = newEditor("");
+ editor.assertContextualCompletions("springactcloti",
+ "spring:\n" +
+ " activemq:\n" +
+ " close-timeout: <*>"
+ );
+
+ editor = newEditor(
+ "spring:\n" +
+ " activemq:\n" +
+ " close-timeout: garbage"
+ );
+ editor.assertProblems("garbage|not a valid duration");
+
+ editor = newEditor(
+ "spring:\n" +
+ " activemq:\n" +
+ " close-timeout: 15s"
+ );
+ editor.assertProblems(/*NONE*/);
+
+ editor = newEditor(
+ "spring:\n" +
+ " activemq:\n" +
+ " close-timeout: PT10S" //ISO duration format
+ );
+ editor.assertProblems(/*NONE*/);
+ }
+
@Test public void bug_153144391() throws Exception {
//See: https://www.pivotaltracker.com/story/show/153144391
useProject(createPredefinedMavenProject("empty-boot-1.3.0-app"));