package com.oracle.svm.core.configure;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import com.oracle.svm.core.util.json.JSONParser;
import com.oracle.svm.core.util.json.JSONParserException;
public class ResourceConfigurationParser extends ConfigurationParser {
private final ResourcesRegistry registry;
public <T> ResourceConfigurationParser(ResourcesRegistry registry) {
this.registry = registry;
}
@Override
public void parseAndRegister(Reader reader) throws IOException {
JSONParser parser = new JSONParser(reader);
Object json = parser.parse();
parseTopLevelObject(asMap(json, "first level of document must be an object"));
}
@SuppressWarnings("unchecked")
private void parseTopLevelObject(Map<String, Object> obj) {
Object resourcesObject = null;
Object bundlesObject = null;
for (Map.Entry<String, Object> pair : obj.entrySet()) {
if ("resources".equals(pair.getKey())) {
resourcesObject = pair.getValue();
} else if ("bundles".equals(pair.getKey())) {
bundlesObject = pair.getValue();
} else {
throw new JSONParserException("Unknown attribute '" + pair.getKey() + "' (supported attributes: name) in resource definition");
}
}
if (resourcesObject != null) {
if (resourcesObject instanceof Map) {
Object includesObject = null;
Object excludesObject = null;
for (Map.Entry<String, Object> pair : ((Map<String, Object>) resourcesObject).entrySet()) {
if ("includes".equals(pair.getKey())) {
includesObject = pair.getValue();
} else if ("excludes".equals(pair.getKey())) {
excludesObject = pair.getValue();
} else {
throw new JSONParserException("Unknown attribute '" + pair.getKey() + "' (supported attributes: name) in resource definition");
}
}
List<Object> includes = asList(includesObject, "Attribute 'includes' must be a list of resources");
for (Object object : includes) {
parseEntry(object, "pattern", registry::addResources, "resource descriptor object", "'includes' list");
}
if (excludesObject != null) {
List<Object> excludes = asList(excludesObject, "Attribute 'excludes' must be a list of resources");
for (Object object : excludes) {
parseEntry(object, "pattern", registry::ignoreResources, "resource descriptor object", "'excludes' list");
}
}
} else {
List<Object> resources = asList(resourcesObject, "Attribute 'resources' must be a list of resources");
for (Object object : resources) {
parseEntry(object, "pattern", registry::addResources, "resource descriptor object", "'resources' list");
}
}
}
if (bundlesObject != null) {
List<Object> bundles = asList(bundlesObject, "Attribute 'bundles' must be a list of bundles");
for (Object object : bundles) {
parseEntry(object, "name", registry::addResourceBundles, "bundle descriptor object", "'bundles' list");
}
}
}
private static void parseEntry(Object data, String valueKey, Consumer<String> registry, String expectedType, String parentType) {
Map<String, Object> resource = asMap(data, "Elements of " + parentType + " must be a " + expectedType);
Object valueObject = null;
for (Map.Entry<String, Object> pair : resource.entrySet()) {
if (valueKey.equals(pair.getKey())) {
valueObject = pair.getValue();
} else {
throw new JSONParserException("Unknown attribute '" + pair.getKey() + "' (supported attributes: '" + valueKey + "') in " + expectedType);
}
}
if (valueObject == null) {
throw new JSONParserException("Missing attribute '" + valueKey + "' in " + expectedType);
}
String value = asString(valueObject, valueKey);
registry.accept(value);
}
}