Skip to content

Commit

Permalink
Fix allow missing for the AnySyntax parse methods, issue gh-1
Browse files Browse the repository at this point in the history
This fix could in theory go further and Parseable.relativeTo
could return a ParseableNotFound instead of null, but for now
eliminate null from within ConfigImpl at least.
  • Loading branch information
havocp committed Dec 7, 2011
1 parent 002fd53 commit b13f1fb
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 25 deletions.
63 changes: 40 additions & 23 deletions config/src/main/java/com/typesafe/config/impl/ConfigImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,36 +51,46 @@ private static ConfigObject fromBasename(NameSource source, String name,
ConfigParseable jsonHandle = source.nameToParseable(name + ".json");
ConfigParseable propsHandle = source.nameToParseable(name
+ ".properties");

if (!options.getAllowMissing() && confHandle == null
&& jsonHandle == null && propsHandle == null) {
throw new ConfigException.IO(SimpleConfigOrigin.newSimple(name),
"No config files {.conf,.json,.properties} found");
}
boolean gotSomething = false;

ConfigSyntax syntax = options.getSyntax();

obj = SimpleConfigObject.empty(SimpleConfigOrigin.newSimple(name));
if (confHandle != null
&& (syntax == null || syntax == ConfigSyntax.CONF)) {
obj = confHandle.parse(confHandle.options()
.setAllowMissing(true).setSyntax(ConfigSyntax.CONF));
if (syntax == null || syntax == ConfigSyntax.CONF) {
try {
obj = confHandle.parse(confHandle.options().setAllowMissing(false)
.setSyntax(ConfigSyntax.CONF));
gotSomething = true;
} catch (ConfigException.IO e) {

}
}

if (syntax == null || syntax == ConfigSyntax.JSON) {
try {
ConfigObject parsed = jsonHandle.parse(jsonHandle.options()
.setAllowMissing(false).setSyntax(ConfigSyntax.JSON));
obj = obj.withFallback(parsed);
gotSomething = true;
} catch (ConfigException.IO e) {

}
}

if (jsonHandle != null
&& (syntax == null || syntax == ConfigSyntax.JSON)) {
ConfigObject parsed = jsonHandle.parse(jsonHandle
.options().setAllowMissing(true)
.setSyntax(ConfigSyntax.JSON));
obj = obj.withFallback(parsed);
if (syntax == null || syntax == ConfigSyntax.PROPERTIES) {
try {
ConfigObject parsed = propsHandle.parse(propsHandle.options()
.setAllowMissing(false).setSyntax(ConfigSyntax.PROPERTIES));
obj = obj.withFallback(parsed);
gotSomething = true;
} catch (ConfigException.IO e) {

}
}

if (propsHandle != null
&& (syntax == null || syntax == ConfigSyntax.PROPERTIES)) {
ConfigObject parsed = propsHandle.parse(propsHandle.options()
.setAllowMissing(true)
.setSyntax(ConfigSyntax.PROPERTIES));
obj = obj.withFallback(parsed);
if (!options.getAllowMissing() && !gotSomething) {
throw new ConfigException.IO(SimpleConfigOrigin.newSimple(name), String.format(
"None of %s.conf, %s.json, %s.properties were found", name, name, name));
}
}

Expand Down Expand Up @@ -269,7 +279,14 @@ public ConfigObject include(final ConfigIncludeContext context,
NameSource source = new NameSource() {
@Override
public ConfigParseable nameToParseable(String name) {
return context.relativeTo(name);
ConfigParseable p = context.relativeTo(name);
if (p == null) {
// avoid returning null
return Parseable.newNotFound(name, "include was not found: '" + name + "'",
ConfigParseOptions.defaults());
} else {
return p;
}
}
};

Expand Down
29 changes: 29 additions & 0 deletions config/src/main/java/com/typesafe/config/impl/Parseable.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilterReader;
import java.io.IOException;
import java.io.InputStream;
Expand Down Expand Up @@ -261,6 +262,34 @@ static File relativeTo(File file, String filename) {
return new File(parent, filename);
}

// this is a parseable that doesn't exist and just throws when you try to
// parse it
private final static class ParseableNotFound extends Parseable {
final private String what;
final private String message;

ParseableNotFound(String what, String message, ConfigParseOptions options) {
this.what = what;
this.message = message;
postConstruct(options);
}

@Override
protected Reader reader() throws IOException {
throw new FileNotFoundException(message);
}

@Override
protected ConfigOrigin createOrigin() {
return SimpleConfigOrigin.newSimple(what);
}
}

public static Parseable newNotFound(String whatNotFound, String message,
ConfigParseOptions options) {
return new ParseableNotFound(whatNotFound, message, options);
}

private final static class ParseableReader extends Parseable {
final private Reader reader;

Expand Down
32 changes: 30 additions & 2 deletions config/src/test/scala/com/typesafe/config/impl/PublicApiTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -229,15 +229,43 @@ class PublicApiTest extends TestUtils {
assertNull(d.getSyntax())
}

private def assertNotFound(e: ConfigException) {
assertTrue("Message text: " + e.getMessage, e.getMessage.contains("No such") ||
e.getMessage.contains("not found") ||
e.getMessage.contains("were found"))
}

@Test
def allowMissing() {
val e = intercept[ConfigException.IO] {
ConfigFactory.parseFile(resourceFile("nonexistent.conf"), ConfigParseOptions.defaults().setAllowMissing(false))
}
assertTrue(e.getMessage.contains("No such"))
assertNotFound(e)

val conf = ConfigFactory.parseFile(resourceFile("nonexistent.conf"), ConfigParseOptions.defaults().setAllowMissing(true))
assertTrue(conf.isEmpty())
assertTrue("is empty", conf.isEmpty())
}

@Test
def allowMissingFileAnySyntax() {
val e = intercept[ConfigException.IO] {
ConfigFactory.parseFileAnySyntax(resourceFile("nonexistent"), ConfigParseOptions.defaults().setAllowMissing(false))
}
assertNotFound(e)

val conf = ConfigFactory.parseFileAnySyntax(resourceFile("nonexistent"), ConfigParseOptions.defaults().setAllowMissing(true))
assertTrue("is empty", conf.isEmpty())
}

@Test
def allowMissingResourcesAnySyntax() {
val e = intercept[ConfigException.IO] {
ConfigFactory.parseResourcesAnySyntax(classOf[PublicApiTest], "nonexistent", ConfigParseOptions.defaults().setAllowMissing(false))
}
assertNotFound(e)

val conf = ConfigFactory.parseResourcesAnySyntax(classOf[PublicApiTest], "nonexistent", ConfigParseOptions.defaults().setAllowMissing(true))
assertTrue("is empty", conf.isEmpty())
}

@Test
Expand Down

0 comments on commit b13f1fb

Please sign in to comment.