if ((type == null)
|| Modifier.isAbstract(type.getModifiers()) || Modifier.isInterface(type.getModifiers())) {
if (configValue.valueType() == ConfigValueType.LIST) {
Class<?> arrayType = pluginMap.arraySugar();
if (arrayType != null) {
ConfigObject aliasDefaults = pluginMap.aliasDefaults("_array");
String arrayFieldName = aliasDefaults.toConfig().getString("_primary");
String arraySugarName = pluginMap.getLastAlias("_array");
return ConfigFactory.empty().root().withValue(
classField, ConfigValueFactory.fromAnyRef(
arraySugarName, pluginMap.category() + " array sugar : " +
pluginMap.config().root().get("_array").origin().description()))
.withValue(arrayFieldName, configValue)
.withFallback(aliasDefaults);
} else {
throw new ConfigException.WrongType(configValue.origin(),
"found an array instead of an object, but no array type set");
}
}
} else {
if (ValueCodable.class.isAssignableFrom(type)) {
return ConfigValueFactory.fromAnyRef(configValue.unwrapped(),
"unchanged for ValueCodable"
+ configValue.origin().description());
}
}
throw new ConfigException.WrongType(configValue.origin(),
"invalid config type of " + configValue.valueType() +
" for " + pluginMap);
}
ConfigObject root = (ConfigObject) configValue;
ConfigValue classValue = root.get(classField);
// normal, explicit typing
if ((classValue != null) && (classValue.valueType() == ConfigValueType.STRING)) {
String classValueString = (String) classValue.unwrapped();
ConfigObject aliasDefaults = pluginMap.aliasDefaults(classValueString);
return root.withFallback(aliasDefaults);
}
if ((type == null) || Modifier.isAbstract(type.getModifiers()) || Modifier.isInterface(type.getModifiers())) {
// single key as type
if (root.size() == 1) {
String onlyKey = root.keySet().iterator().next();
try {
pluginMap.getClass(onlyKey); // make sure key is a valid type
ConfigValue onlyKeyValue = root.values().iterator().next();
ConfigObject aliasDefaults = pluginMap.aliasDefaults(onlyKey);
if (onlyKeyValue.valueType() != ConfigValueType.OBJECT) {
if (aliasDefaults.get("_primary") != null) {
onlyKeyValue = onlyKeyValue.atPath((String) aliasDefaults.get("_primary").unwrapped()).root();
} else {
throw new ConfigException.WrongType(onlyKeyValue.origin(), onlyKey,
"OBJECT", onlyKeyValue.valueType().toString());
}
}
ConfigObject fieldValues = (ConfigObject) onlyKeyValue;
return fieldValues.withValue(classField, ConfigValueFactory.fromAnyRef(
onlyKey, "single key to type from " + root.origin().description()))
.withFallback(aliasDefaults);
} catch (ClassNotFoundException ignored) {
}
}
// inlined type
String matched = null;
for (String alias : pluginMap.inlinedAliases()) {
if (root.get(alias) != null) {
if (matched != null) {
String message = String.format(
"no type specified, more than one key, and both %s and %s match for inlined types.",
matched, alias);
throw new ConfigException.Parse(root.origin(), message);
}
matched = alias;
}
}
if (matched != null) {
ConfigObject aliasDefaults = pluginMap.aliasDefaults(matched);
ConfigValue inlinedValue = root.get(matched);
String primaryField = (String) aliasDefaults.get("_primary").unwrapped();
ConfigObject fieldValues = root.toConfig().withValue(primaryField, inlinedValue).root()
.withoutKey(matched)
.withFallback(aliasDefaults);
return fieldValues.withValue(classField, ConfigValueFactory.fromAnyRef(
matched, "inlined key to type from " + root.origin().description()));
}
// default type
ConfigValue defaultObject = pluginMap.config().root().get("_default");
if (defaultObject != null) {
String defaultName = pluginMap.getLastAlias("_default");
ConfigObject aliasDefaults = pluginMap.aliasDefaults("_default");
return root.withValue(classField, ConfigValueFactory.fromAnyRef(
defaultName, pluginMap.category() + " default type : "
+ defaultObject.origin().description()))
.withFallback(aliasDefaults);
}