From a3904f505b6a378518ecf5fe53dc765f82eb8de5 Mon Sep 17 00:00:00 2001 From: The Viet Nguyen Date: Wed, 25 Jul 2018 18:50:05 +0300 Subject: [PATCH 1/2] Add syntax from file name parser option --- .../typesafe/config/ConfigParseOptions.java | 14 +++++++++ .../typesafe/config/impl/ConfigImplUtil.java | 20 +++++++++++++ .../com/typesafe/config/impl/Parseable.java | 17 ++--------- config/src/test/resources/test01.properties | 1 + .../config/impl/ParseableReaderTest.scala | 30 +++++++++++++++++++ .../com/typesafe/config/impl/UtilTest.scala | 26 ++++++++++++++++ 6 files changed, 94 insertions(+), 14 deletions(-) create mode 100644 config/src/test/scala/com/typesafe/config/impl/ParseableReaderTest.scala diff --git a/config/src/main/java/com/typesafe/config/ConfigParseOptions.java b/config/src/main/java/com/typesafe/config/ConfigParseOptions.java index fcfb4d69a..9dc7a121a 100644 --- a/config/src/main/java/com/typesafe/config/ConfigParseOptions.java +++ b/config/src/main/java/com/typesafe/config/ConfigParseOptions.java @@ -4,6 +4,8 @@ package com.typesafe.config; +import com.typesafe.config.impl.ConfigImplUtil; + /** * A set of options related to parsing. * @@ -62,6 +64,18 @@ public ConfigParseOptions setSyntax(ConfigSyntax syntax) { this.includer, this.classLoader); } + /** + * Set the file format. If set to null, assume {@link ConfigSyntax#CONF}. + * + * @param filename + * a configuration file name + * @return options with the syntax set + */ + public ConfigParseOptions setSyntaxFromFilename(String filename) { + ConfigSyntax syntax = ConfigImplUtil.syntaxFromExtension(filename); + return setSyntax(syntax); + } + /** * Gets the current syntax option, which may be null for "any". * @return the current syntax or null diff --git a/config/src/main/java/com/typesafe/config/impl/ConfigImplUtil.java b/config/src/main/java/com/typesafe/config/impl/ConfigImplUtil.java index 279f5ec84..9a13ea84c 100644 --- a/config/src/main/java/com/typesafe/config/impl/ConfigImplUtil.java +++ b/config/src/main/java/com/typesafe/config/impl/ConfigImplUtil.java @@ -15,6 +15,7 @@ import com.typesafe.config.ConfigException; import com.typesafe.config.ConfigOrigin; +import com.typesafe.config.ConfigSyntax; /** * Internal implementation detail, not ABI stable, do not touch. @@ -233,4 +234,23 @@ static String toCamelCase(String originalName) { } return nameBuilder.toString(); } + + /** + * Guess configuration syntax from given filename. + * + * @param filename configuration filename + * @return configuration syntax if a match is found. Otherwise, null. + */ + public static ConfigSyntax syntaxFromExtension(String filename) { + if (filename == null) + return null; + if (filename.endsWith(".json")) + return ConfigSyntax.JSON; + else if (filename.endsWith(".conf")) + return ConfigSyntax.CONF; + else if (filename.endsWith(".properties")) + return ConfigSyntax.PROPERTIES; + else + return null; + } } diff --git a/config/src/main/java/com/typesafe/config/impl/Parseable.java b/config/src/main/java/com/typesafe/config/impl/Parseable.java index ae54a7d42..ad5146301 100644 --- a/config/src/main/java/com/typesafe/config/impl/Parseable.java +++ b/config/src/main/java/com/typesafe/config/impl/Parseable.java @@ -326,17 +326,6 @@ public String toString() { return getClass().getSimpleName(); } - private static ConfigSyntax syntaxFromExtension(String name) { - if (name.endsWith(".json")) - return ConfigSyntax.JSON; - else if (name.endsWith(".conf")) - return ConfigSyntax.CONF; - else if (name.endsWith(".properties")) - return ConfigSyntax.PROPERTIES; - else - return null; - } - private static Reader readerFromStream(InputStream input) { return readerFromStream(input, "UTF-8"); } @@ -574,7 +563,7 @@ protected Reader reader(ConfigParseOptions options) throws IOException { @Override ConfigSyntax guessSyntax() { - return syntaxFromExtension(input.getPath()); + return ConfigImplUtil.syntaxFromExtension(input.getPath()); } @Override @@ -643,7 +632,7 @@ protected Reader reader() throws IOException { @Override ConfigSyntax guessSyntax() { - return syntaxFromExtension(input.getName()); + return ConfigImplUtil.syntaxFromExtension(input.getName()); } @Override @@ -756,7 +745,7 @@ protected AbstractConfigObject rawParseValue(ConfigOrigin origin, @Override ConfigSyntax guessSyntax() { - return syntaxFromExtension(resource); + return ConfigImplUtil.syntaxFromExtension(resource); } static String parent(String resource) { diff --git a/config/src/test/resources/test01.properties b/config/src/test/resources/test01.properties index 94eec4470..71de4e0be 100644 --- a/config/src/test/resources/test01.properties +++ b/config/src/test/resources/test01.properties @@ -2,3 +2,4 @@ fromProps.abc=abc fromProps.one=1 fromProps.bool=true +fromProps.specialChars=hello^^ diff --git a/config/src/test/scala/com/typesafe/config/impl/ParseableReaderTest.scala b/config/src/test/scala/com/typesafe/config/impl/ParseableReaderTest.scala new file mode 100644 index 000000000..70182df54 --- /dev/null +++ b/config/src/test/scala/com/typesafe/config/impl/ParseableReaderTest.scala @@ -0,0 +1,30 @@ +package com.typesafe.config.impl + +import java.io.InputStreamReader + +import com.typesafe.config.{ConfigException, ConfigFactory, ConfigParseOptions} +import org.hamcrest.CoreMatchers.containsString +import org.junit.Assert.{assertEquals, assertThat} +import org.junit.Test + +class ParseableReaderTest extends TestUtils { + + @Test + def parse(): Unit = { + val filename = "/test01.properties" + val configInput = new InputStreamReader(getClass.getResourceAsStream(filename)) + val config = ConfigFactory.parseReader(configInput, ConfigParseOptions.defaults() + .setSyntaxFromFilename(filename)) + assertEquals("hello^^", config.getString("fromProps.specialChars")) + } + + @Test + def parseIncorrectFormat(): Unit = { + val filename = "/test01.properties" + val configInput = new InputStreamReader(getClass.getResourceAsStream(filename)) + val e = intercept[ConfigException.Parse] { + ConfigFactory.parseReader(configInput) + } + assertThat(e.getMessage, containsString("Expecting end of input or a comma, got '^'")) + } +} diff --git a/config/src/test/scala/com/typesafe/config/impl/UtilTest.scala b/config/src/test/scala/com/typesafe/config/impl/UtilTest.scala index cf31a7166..bccbaa476 100644 --- a/config/src/test/scala/com/typesafe/config/impl/UtilTest.scala +++ b/config/src/test/scala/com/typesafe/config/impl/UtilTest.scala @@ -3,6 +3,7 @@ */ package com.typesafe.config.impl +import com.typesafe.config.ConfigSyntax import org.junit.Assert._ import org.junit._ @@ -90,4 +91,29 @@ class UtilTest extends TestUtils { roundtripUnquoted(s) } } + + @Test + def syntaxFromExtensionConf(): Unit = { + assertEquals(ConfigSyntax.CONF, ConfigImplUtil.syntaxFromExtension("application.conf")) + } + + @Test + def syntaxFromExtensionJson(): Unit = { + assertEquals(ConfigSyntax.JSON, ConfigImplUtil.syntaxFromExtension("application.json")) + } + + @Test + def syntaxFromExtensionProperties(): Unit = { + assertEquals(ConfigSyntax.PROPERTIES, ConfigImplUtil.syntaxFromExtension("application.properties")) + } + + @Test + def syntaxFromExtensionUnknown(): Unit = { + assertNull(ConfigImplUtil.syntaxFromExtension("application.exe")) + } + + @Test + def syntaxFromExtensionNull(): Unit = { + assertNull(ConfigImplUtil.syntaxFromExtension(null)) + } } From b091c8f641ff113d71a4869a646b2a98dc1abac4 Mon Sep 17 00:00:00 2001 From: The Viet Nguyen Date: Wed, 25 Jul 2018 19:11:50 +0300 Subject: [PATCH 2/2] Unify guess syntax decision tree --- .../src/main/java/com/typesafe/config/impl/ConfigImplUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/src/main/java/com/typesafe/config/impl/ConfigImplUtil.java b/config/src/main/java/com/typesafe/config/impl/ConfigImplUtil.java index 9a13ea84c..1dcc43d3d 100644 --- a/config/src/main/java/com/typesafe/config/impl/ConfigImplUtil.java +++ b/config/src/main/java/com/typesafe/config/impl/ConfigImplUtil.java @@ -244,7 +244,7 @@ static String toCamelCase(String originalName) { public static ConfigSyntax syntaxFromExtension(String filename) { if (filename == null) return null; - if (filename.endsWith(".json")) + else if (filename.endsWith(".json")) return ConfigSyntax.JSON; else if (filename.endsWith(".conf")) return ConfigSyntax.CONF;