Skip to content

Commit 324085b

Browse files
committed
Merge branch 'master' of https://github.com/Johnlon/config
2 parents f687a8f + 7f5be86 commit 324085b

File tree

14 files changed

+474
-60
lines changed

14 files changed

+474
-60
lines changed

README.md

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,17 @@ to merge it in.
7676
- [Debugging Your Configuration](#debugging-your-configuration)
7777
- [Supports Java 8 and Later](#supports-java-8-and-later)
7878
- [Rationale for Supported File Formats](#rationale-for-supported-file-formats)
79-
- [Other APIs (Wrappers and Ports)](#other-apis-wrappers-and-ports)
79+
- [Other APIs (Wrappers, Ports and Utilities)](#other-apis-wrappers-ports-and-utilities)
80+
- [Guice integration](#guice-integration)
81+
- [Java (yep!) wrappers for the Java library](#java-yep-wrappers-for-the-java-library)
8082
- [Scala wrappers for the Java library](#scala-wrappers-for-the-java-library)
8183
- [Clojure wrappers for the Java library](#clojure-wrappers-for-the-java-library)
84+
- [Scala port](#scala-port)
8285
- [Ruby port](#ruby-port)
8386
- [Puppet module](#puppet-module)
8487
- [Python port](#python-port)
85-
- [C++ port](#c++-port)
86-
88+
- [C++ port](#c-port)
89+
- [Linting tool](#linting-tool)
8790

8891
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
8992

@@ -837,11 +840,16 @@ format.
837840
* config-annotation https://github.com/wacai/config-annotation
838841
* PureConfig https://github.com/melrief/pureconfig
839842
* Simple Scala Config https://github.com/ElderResearch/ssc
843+
* konfig https://github.com/vpon/konfig
840844

841845
#### Clojure wrappers for the Java library
842846

843847
* beamly-core.config https://github.com/beamly/beamly-core.config
844848

849+
#### Scala port
850+
851+
* SHocon https://github.com/unicredit/shocon (work with both Scala and Scala.Js)
852+
845853
#### Ruby port
846854

847855
* https://github.com/puppetlabs/ruby-hocon
@@ -859,5 +867,6 @@ format.
859867
* https://github.com/puppetlabs/cpp-hocon
860868

861869
#### Linting tool
862-
863-
* A web based linting tool http://www.hoconlint.com/
870+
871+
* A web based linting tool http://www.hoconlint.com/
872+

appveyor.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
version: '{build}'
2+
os: Windows Server 2012
3+
install:
4+
- cmd: choco install sbt -ia "INSTALLDIR=""C:\sbt"""
5+
- cmd: SET PATH=C:\sbt\bin;%JAVA_HOME%\bin;%PATH%
6+
- cmd: SET SBT_OPTS=-XX:MaxPermSize=2g -Xmx4g
7+
build_script:
8+
- sbt clean compile
9+
test_script:
10+
- sbt test
11+
- sbt doc
12+
cache:
13+
- C:\sbt\
14+
- C:\Users\appveyor\.ivy2

config/src/main/java/com/typesafe/config/Config.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,22 @@ public interface Config extends ConfigMergeable {
597597
*/
598598
String getString(String path);
599599

600+
/**
601+
* @param enumClass
602+
* an enum class
603+
* @param <T>
604+
* a generic denoting a specific type of enum
605+
* @param path
606+
* path expression
607+
* @return the {@code Enum} value at the requested path
608+
* of the requested enum class
609+
* @throws ConfigException.Missing
610+
* if value is absent or null
611+
* @throws ConfigException.WrongType
612+
* if value is not convertible to an Enum
613+
*/
614+
public <T extends Enum<T>> T getEnum(Class<T> enumClass, String path);
615+
600616
/**
601617
* @param path
602618
* path expression
@@ -882,6 +898,25 @@ public interface Config extends ConfigMergeable {
882898
*/
883899
List<String> getStringList(String path);
884900

901+
/**
902+
* Gets a list value with {@code Enum} elements. Throws if the
903+
* path is unset or null or not a list or contains values not
904+
* convertible to {@code Enum}.
905+
*
906+
* @param enumClass
907+
* the enum class
908+
* @param <T>
909+
* a generic denoting a specific type of enum
910+
* @param path
911+
* the path to the list value.
912+
* @return the list at the path
913+
* @throws ConfigException.Missing
914+
* if value is absent or null
915+
* @throws ConfigException.WrongType
916+
* if value is not convertible to a list of {@code Enum}
917+
*/
918+
<T extends Enum<T>> List<T> getEnumList(Class<T> enumClass, String path);
919+
885920
/**
886921
* Gets a list value with object elements. Throws if the
887922
* path is unset or null or not a list or contains values not

config/src/main/java/com/typesafe/config/ConfigFactory.java

Lines changed: 21 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,16 @@
33
*/
44
package com.typesafe.config;
55

6+
import com.typesafe.config.impl.ConfigImpl;
7+
import com.typesafe.config.impl.Parseable;
8+
69
import java.io.File;
710
import java.io.Reader;
8-
import java.net.MalformedURLException;
911
import java.net.URL;
1012
import java.util.Map;
1113
import java.util.Properties;
1214
import java.util.concurrent.Callable;
1315

14-
import com.typesafe.config.impl.ConfigImpl;
15-
import com.typesafe.config.impl.Parseable;
16-
1716
/**
1817
* Contains static methods for creating {@link Config} instances.
1918
*
@@ -36,6 +35,8 @@
3635
* examples.
3736
*/
3837
public final class ConfigFactory {
38+
private static final String STRATEGY_PROPERTY_NAME = "config.strategy";
39+
3940
private ConfigFactory() {
4041
}
4142

@@ -213,54 +214,7 @@ public static Config load(ClassLoader loader, Config config, ConfigResolveOption
213214
.resolve(resolveOptions);
214215
}
215216

216-
private static Config parseApplicationConfig(ConfigParseOptions parseOptions) {
217-
ClassLoader loader = parseOptions.getClassLoader();
218-
if (loader == null)
219-
throw new ConfigException.BugOrBroken(
220-
"ClassLoader should have been set here; bug in ConfigFactory. "
221-
+ "(You can probably work around this bug by passing in a class loader or calling currentThread().setContextClassLoader() though.)");
222-
223-
int specified = 0;
224-
225-
// override application.conf with config.file, config.resource,
226-
// config.url if requested.
227-
String resource = System.getProperty("config.resource");
228-
if (resource != null)
229-
specified += 1;
230-
String file = System.getProperty("config.file");
231-
if (file != null)
232-
specified += 1;
233-
String url = System.getProperty("config.url");
234-
if (url != null)
235-
specified += 1;
236-
237-
if (specified == 0) {
238-
return ConfigFactory.parseResourcesAnySyntax("application", parseOptions);
239-
} else if (specified > 1) {
240-
throw new ConfigException.Generic("You set more than one of config.file='" + file
241-
+ "', config.url='" + url + "', config.resource='" + resource
242-
+ "'; don't know which one to use!");
243-
} else {
244-
// the override file/url/resource MUST be present or it's an error
245-
ConfigParseOptions overrideOptions = parseOptions.setAllowMissing(false);
246-
if (resource != null) {
247-
if (resource.startsWith("/"))
248-
resource = resource.substring(1);
249-
// this deliberately does not parseResourcesAnySyntax; if
250-
// people want that they can use an include statement.
251-
return parseResources(loader, resource, overrideOptions);
252-
} else if (file != null) {
253-
return parseFile(new File(file), overrideOptions);
254-
} else {
255-
try {
256-
return parseURL(new URL(url), overrideOptions);
257-
} catch (MalformedURLException e) {
258-
throw new ConfigException.Generic("Bad URL in config.url system property: '"
259-
+ url + "': " + e.getMessage(), e);
260-
}
261-
}
262-
}
263-
}
217+
264218

265219
/**
266220
* Loads a default configuration, equivalent to {@link #load(Config)
@@ -516,7 +470,7 @@ public static Config defaultApplication(ClassLoader loader) {
516470
* @return the default application configuration
517471
*/
518472
public static Config defaultApplication(ConfigParseOptions options) {
519-
return parseApplicationConfig(ensureClassLoader(options, "defaultApplication"));
473+
return getConfigLoadingStrategy().parseApplicationConfig(ensureClassLoader(options, "defaultApplication"));
520474
}
521475

522476
/**
@@ -1094,4 +1048,18 @@ public static Config parseMap(Map<String, ? extends Object> values,
10941048
public static Config parseMap(Map<String, ? extends Object> values) {
10951049
return parseMap(values, null);
10961050
}
1051+
1052+
private static ConfigLoadingStrategy getConfigLoadingStrategy() {
1053+
String className = System.getProperties().getProperty(STRATEGY_PROPERTY_NAME);
1054+
1055+
if (className != null) {
1056+
try {
1057+
return ConfigLoadingStrategy.class.cast(Class.forName(className).newInstance());
1058+
} catch (Throwable e) {
1059+
throw new ConfigException.BugOrBroken("Failed to load strategy: " + className, e);
1060+
}
1061+
} else {
1062+
return new DefaultConfigLoadingStrategy();
1063+
}
1064+
}
10971065
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.typesafe.config;
2+
3+
/**
4+
* This method allows you to alter default config loading strategy for all the code which
5+
* calls {@link ConfigFactory#load}.
6+
*
7+
* Usually you don't have to implement this interface but it may be required
8+
* when you fixing a improperly implemented library with unavailable source code.
9+
*
10+
* You have to define VM property {@code config.strategy} to replace default strategy with your own.
11+
*/
12+
public interface ConfigLoadingStrategy {
13+
/**
14+
* This method must load and parse application config.
15+
*
16+
* @param parseOptions {@link ConfigParseOptions} to use
17+
* @return loaded config
18+
*/
19+
Config parseApplicationConfig(ConfigParseOptions parseOptions);
20+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.typesafe.config;
2+
3+
import java.io.File;
4+
import java.net.MalformedURLException;
5+
import java.net.URL;
6+
7+
/**
8+
* Default config loading strategy. Able to load resource, file or URL.
9+
* Behavior may be altered by defining one of VM properties
10+
* {@code config.resource}, {@code config.file} or {@code config.url}
11+
*/
12+
public class DefaultConfigLoadingStrategy implements ConfigLoadingStrategy {
13+
@Override
14+
public Config parseApplicationConfig(ConfigParseOptions parseOptions) {
15+
ClassLoader loader = parseOptions.getClassLoader();
16+
if (loader == null)
17+
throw new ConfigException.BugOrBroken(
18+
"ClassLoader should have been set here; bug in ConfigFactory. "
19+
+ "(You can probably work around this bug by passing in a class loader or calling currentThread().setContextClassLoader() though.)");
20+
21+
int specified = 0;
22+
23+
// override application.conf with config.file, config.resource,
24+
// config.url if requested.
25+
String resource = System.getProperty("config.resource");
26+
if (resource != null)
27+
specified += 1;
28+
String file = System.getProperty("config.file");
29+
if (file != null)
30+
specified += 1;
31+
String url = System.getProperty("config.url");
32+
if (url != null)
33+
specified += 1;
34+
35+
if (specified == 0) {
36+
return ConfigFactory.parseResourcesAnySyntax("application", parseOptions);
37+
} else if (specified > 1) {
38+
throw new ConfigException.Generic("You set more than one of config.file='" + file
39+
+ "', config.url='" + url + "', config.resource='" + resource
40+
+ "'; don't know which one to use!");
41+
} else {
42+
// the override file/url/resource MUST be present or it's an error
43+
ConfigParseOptions overrideOptions = parseOptions.setAllowMissing(false);
44+
if (resource != null) {
45+
if (resource.startsWith("/"))
46+
resource = resource.substring(1);
47+
// this deliberately does not parseResourcesAnySyntax; if
48+
// people want that they can use an include statement.
49+
return ConfigFactory.parseResources(loader, resource, overrideOptions);
50+
} else if (file != null) {
51+
return ConfigFactory.parseFile(new File(file), overrideOptions);
52+
} else {
53+
try {
54+
return ConfigFactory.parseURL(new URL(url), overrideOptions);
55+
} catch (MalformedURLException e) {
56+
throw new ConfigException.Generic("Bad URL in config.url system property: '"
57+
+ url + "': " + e.getMessage(), e);
58+
}
59+
}
60+
}
61+
}
62+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.typesafe.config;
2+
3+
import java.lang.annotation.Documented;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
7+
/**
8+
* Allows an config property to be {@code null}.
9+
*/
10+
@Documented
11+
@Retention(RetentionPolicy.RUNTIME)
12+
public @interface Optional {
13+
14+
}

0 commit comments

Comments
 (0)