split SimpleIncluder and fromBasename out of ConfigImpl.java

Just to have less stuff in one big file.
This commit is contained in:
Havoc Pennington 2012-04-06 19:41:30 -04:00
parent 69e6164b30
commit 3e46429871
2 changed files with 147 additions and 138 deletions

View File

@ -14,14 +14,13 @@ import java.util.concurrent.Callable;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigException;
import com.typesafe.config.ConfigIncludeContext;
import com.typesafe.config.ConfigIncluder;
import com.typesafe.config.ConfigObject;
import com.typesafe.config.ConfigOrigin;
import com.typesafe.config.ConfigParseOptions;
import com.typesafe.config.ConfigParseable;
import com.typesafe.config.ConfigSyntax;
import com.typesafe.config.ConfigValue;
import com.typesafe.config.impl.SimpleIncluder.NameSource;
/** This is public but is only supposed to be used by the "config" package */
public class ConfigImpl {
@ -78,87 +77,6 @@ public class ConfigImpl {
return cache.getOrElseUpdate(loader, key, updater);
}
private interface NameSource {
ConfigParseable nameToParseable(String name);
}
// this function is a little tricky because there are three places we're
// trying to use it; for 'include "basename"' in a .conf file, for
// loading app.{conf,json,properties} from classpath, and for
// loading app.{conf,json,properties} from the filesystem.
private static ConfigObject fromBasename(NameSource source, String name,
ConfigParseOptions options) {
ConfigObject obj;
if (name.endsWith(".conf") || name.endsWith(".json")
|| name.endsWith(".properties")) {
ConfigParseable p = source.nameToParseable(name);
obj = p.parse(p.options().setAllowMissing(options.getAllowMissing()));
} else {
ConfigParseable confHandle = source.nameToParseable(name + ".conf");
ConfigParseable jsonHandle = source.nameToParseable(name + ".json");
ConfigParseable propsHandle = source.nameToParseable(name
+ ".properties");
boolean gotSomething = false;
List<String> failMessages = new ArrayList<String>();
ConfigSyntax syntax = options.getSyntax();
obj = SimpleConfigObject.empty(SimpleConfigOrigin.newSimple(name));
if (syntax == null || syntax == ConfigSyntax.CONF) {
try {
obj = confHandle.parse(confHandle.options().setAllowMissing(false)
.setSyntax(ConfigSyntax.CONF));
gotSomething = true;
} catch (ConfigException.IO e) {
failMessages.add(e.getMessage());
}
}
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) {
failMessages.add(e.getMessage());
}
}
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) {
failMessages.add(e.getMessage());
}
}
if (!options.getAllowMissing() && !gotSomething) {
String failMessage;
if (failMessages.isEmpty()) {
// this should not happen
throw new ConfigException.BugOrBroken(
"should not be reached: nothing found but no exceptions thrown");
} else {
StringBuilder sb = new StringBuilder();
for (String msg : failMessages) {
sb.append(msg);
sb.append(", ");
}
sb.setLength(sb.length() - 2);
failMessage = sb.toString();
}
throw new ConfigException.IO(SimpleConfigOrigin.newSimple(name), failMessage);
}
}
return obj;
}
/** For use ONLY by library internals, DO NOT TOUCH not guaranteed ABI */
public static ConfigObject parseResourcesAnySyntax(final Class<?> klass,
String resourceBasename, final ConfigParseOptions baseOptions) {
@ -168,7 +86,7 @@ public class ConfigImpl {
return Parseable.newResources(klass, name, baseOptions);
}
};
return fromBasename(source, resourceBasename, baseOptions);
return SimpleIncluder.fromBasename(source, resourceBasename, baseOptions);
}
/** For use ONLY by library internals, DO NOT TOUCH not guaranteed ABI */
@ -180,7 +98,7 @@ public class ConfigImpl {
return Parseable.newResources(loader, name, baseOptions);
}
};
return fromBasename(source, resourceBasename, baseOptions);
return SimpleIncluder.fromBasename(source, resourceBasename, baseOptions);
}
/** For use ONLY by library internals, DO NOT TOUCH not guaranteed ABI */
@ -192,7 +110,7 @@ public class ConfigImpl {
return Parseable.newFile(new File(name), baseOptions);
}
};
return fromBasename(source, basename.getPath(), baseOptions);
return SimpleIncluder.fromBasename(source, basename.getPath(), baseOptions);
}
static AbstractConfigObject emptyObject(String originDescription) {
@ -339,58 +257,6 @@ public class ConfigImpl {
}
}
private static class SimpleIncluder implements ConfigIncluder {
private ConfigIncluder fallback;
SimpleIncluder(ConfigIncluder fallback) {
this.fallback = fallback;
}
@Override
public ConfigObject include(final ConfigIncludeContext context,
String name) {
NameSource source = new NameSource() {
@Override
public ConfigParseable nameToParseable(String 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;
}
}
};
ConfigObject obj = fromBasename(source, name, ConfigParseOptions
.defaults().setAllowMissing(true));
// now use the fallback includer if any and merge
// its result.
if (fallback != null) {
return obj.withFallback(fallback.include(context, name));
} else {
return obj;
}
}
@Override
public ConfigIncluder withFallback(ConfigIncluder fallback) {
if (this == fallback) {
throw new ConfigException.BugOrBroken(
"trying to create includer cycle");
} else if (this.fallback == fallback) {
return this;
} else if (this.fallback != null) {
return new SimpleIncluder(this.fallback.withFallback(fallback));
} else {
return new SimpleIncluder(fallback);
}
}
}
private static class DefaultIncluderHolder {
static final ConfigIncluder defaultIncluder = new SimpleIncluder(null);
}

View File

@ -0,0 +1,143 @@
/**
* Copyright (C) 2011-2012 Typesafe Inc. <http://typesafe.com>
*/
package com.typesafe.config.impl;
import java.util.ArrayList;
import java.util.List;
import com.typesafe.config.ConfigException;
import com.typesafe.config.ConfigIncludeContext;
import com.typesafe.config.ConfigIncluder;
import com.typesafe.config.ConfigObject;
import com.typesafe.config.ConfigParseOptions;
import com.typesafe.config.ConfigParseable;
import com.typesafe.config.ConfigSyntax;
class SimpleIncluder implements ConfigIncluder {
private ConfigIncluder fallback;
SimpleIncluder(ConfigIncluder fallback) {
this.fallback = fallback;
}
@Override
public ConfigObject include(final ConfigIncludeContext context, String name) {
NameSource source = new NameSource() {
@Override
public ConfigParseable nameToParseable(String 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;
}
}
};
ConfigObject obj = fromBasename(source, name, ConfigParseOptions.defaults()
.setAllowMissing(true));
// now use the fallback includer if any and merge
// its result.
if (fallback != null) {
return obj.withFallback(fallback.include(context, name));
} else {
return obj;
}
}
@Override
public ConfigIncluder withFallback(ConfigIncluder fallback) {
if (this == fallback) {
throw new ConfigException.BugOrBroken("trying to create includer cycle");
} else if (this.fallback == fallback) {
return this;
} else if (this.fallback != null) {
return new SimpleIncluder(this.fallback.withFallback(fallback));
} else {
return new SimpleIncluder(fallback);
}
}
interface NameSource {
ConfigParseable nameToParseable(String name);
}
// this function is a little tricky because there are three places we're
// trying to use it; for 'include "basename"' in a .conf file, for
// loading app.{conf,json,properties} from classpath, and for
// loading app.{conf,json,properties} from the filesystem.
static ConfigObject fromBasename(NameSource source, String name, ConfigParseOptions options) {
ConfigObject obj;
if (name.endsWith(".conf") || name.endsWith(".json") || name.endsWith(".properties")) {
ConfigParseable p = source.nameToParseable(name);
obj = p.parse(p.options().setAllowMissing(options.getAllowMissing()));
} else {
ConfigParseable confHandle = source.nameToParseable(name + ".conf");
ConfigParseable jsonHandle = source.nameToParseable(name + ".json");
ConfigParseable propsHandle = source.nameToParseable(name + ".properties");
boolean gotSomething = false;
List<String> failMessages = new ArrayList<String>();
ConfigSyntax syntax = options.getSyntax();
obj = SimpleConfigObject.empty(SimpleConfigOrigin.newSimple(name));
if (syntax == null || syntax == ConfigSyntax.CONF) {
try {
obj = confHandle.parse(confHandle.options().setAllowMissing(false)
.setSyntax(ConfigSyntax.CONF));
gotSomething = true;
} catch (ConfigException.IO e) {
failMessages.add(e.getMessage());
}
}
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) {
failMessages.add(e.getMessage());
}
}
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) {
failMessages.add(e.getMessage());
}
}
if (!options.getAllowMissing() && !gotSomething) {
String failMessage;
if (failMessages.isEmpty()) {
// this should not happen
throw new ConfigException.BugOrBroken(
"should not be reached: nothing found but no exceptions thrown");
} else {
StringBuilder sb = new StringBuilder();
for (String msg : failMessages) {
sb.append(msg);
sb.append(", ");
}
sb.setLength(sb.length() - 2);
failMessage = sb.toString();
}
throw new ConfigException.IO(SimpleConfigOrigin.newSimple(name), failMessage);
}
}
return obj;
}
}