org.etlunit.feature.ResourceFeatureMetaInfo Maven / Gradle / Ivy
package org.etlunit.feature;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.node.ObjectNode;
import org.etlunit.json.validator.*;
import org.etlunit.util.IOUtils;
import java.io.IOException;
import java.net.URL;
import java.util.*;
public class ResourceFeatureMetaInfo implements FeatureMetaInfo
{
protected final Feature describing;
private final Class describingCl;
private final String simpleName;
public ResourceFeatureMetaInfo(Feature describing)
{
this.describing = describing;
describingCl = describing.getClass();
simpleName = describingCl.getName().replace('.', '/');
getSimpleClassName();
}
@Override
public String getFeatureConfiguration()
{
return getResource("configuration");
}
@Override
public JsonSchema getFeatureConfigurationValidator()
{
String schema = getResource("configuration.validator.jsonSchema");
if (schema != null)
{
try
{
return new JsonSchema(schema);
}
catch (JsonSchemaValidationException e)
{
throw new RuntimeException("Invalid schema for feature configuration ["
+ describing.getFeatureName()
+ "]: "
+ e.toString());
}
}
return null;
}
protected String getResource(String id)
{
String name = simpleName + "." + id;
URL res = describingCl.getClassLoader().getResource(name);
if (res == null)
{
return null;
}
try
{
String desc = IOUtils.readURLToString(res);
return desc;
}
catch (IOException e)
{
throw new UnsupportedOperationException();
}
}
private String getSimpleClassName()
{
String name = describingCl.getName();
int index = name.lastIndexOf('.');
if (index != -1)
{
return name.substring(index + 1);
}
else
{
return name;
}
}
@Override
public Map getExportedOperations()
{
ObjectNode obj = getResourceObject("operations");
if (obj == null)
{
return null;
}
// validate against the schema
try
{
JsonValidator
vlad =
new JsonValidator("org/etlunit/featureOperations.jsonSchema", new ClasspathSchemaResolver(this));
vlad.validate(obj);
}
catch (JsonSchemaValidationException e)
{
throw new IllegalArgumentException("Bad operations descriptor", e);
}
Map map = new HashMap();
Iterator> fields = obj.getFields();
while (fields.hasNext())
{
Map.Entry field = fields.next();
String key = field.getKey();
String description = field.getValue().get("description").asText();
map.put(key, new ResourceFeatureOperation(this, key, description));
}
return map;
}
@Override
public Map getExportedAnnotations()
{
ObjectNode obj = getResourceObject("annotations");
if (obj == null)
{
return null;
}
// validate against the schema
try
{
JsonValidator
vlad =
new JsonValidator("org/etlunit/featureAnnotations.jsonSchema", new ClasspathSchemaResolver(this));
vlad.validate(obj);
}
catch (JsonSchemaValidationException e)
{
throw new IllegalArgumentException("Bad annotations descriptor", e);
}
Map map = new HashMap();
Iterator> fields = obj.getFields();
while (fields.hasNext())
{
Map.Entry field = fields.next();
String key = field.getKey();
String description = field.getValue().get("description").asText();
String sType = field.getValue().get("propertyType").asText();
FeatureAnnotation.propertyType type = FeatureAnnotation.propertyType.none;
if (sType.equals("none"))
{
}
else if (sType.equals("required"))
{
type = FeatureAnnotation.propertyType.required;
}
else if (sType.equals("optional"))
{
type = FeatureAnnotation.propertyType.optional;
}
map.put(key, new ResourceFeatureAnnotation(this, key, description, type));
}
return map;
}
@Override
public boolean isInternalFeature()
{
ObjectNode obj = getResourceObject("meta");
if (obj == null)
{
return true;
}
// all we care about here is the one entry feature-type
JsonNode type = JsonUtils.query(obj, "feature-type");
if (type == null)
{
return true;
}
String typeString = type.asText();
if (typeString.equals("external"))
{
return false;
}
else if (typeString.equals("internal"))
{
return true;
}
else
{
throw new IllegalArgumentException("Unknown feature type: " + typeString);
}
}
@Override
public String getFeatureUsage()
{
String res = getResource("usage");
return res;
}
@Override
public List getOptions()
{
String res = getResource("options");
if (res == null)
{
return Collections.emptyList();
}
List list = new ArrayList();
// we have json, now load the schema for options and verify
try
{
JsonNode node = JsonUtils.loadJson(res);
JsonValidator
vlad =
new JsonValidator("org/etlunit/featureOptions.jsonSchema", new ClasspathSchemaResolver(this));
vlad.validate(node);
Iterator names = node.getFieldNames();
while (names.hasNext())
{
String optionName = names.next();
JsonNode descNode = node.get(optionName);
// get the description
String description = descNode.get("description").asText();
// check first for a bool property
JsonNode bn = descNode.get("enabled");
if (bn != null)
{
list.add(new RuntimeOptionDescriptorImpl(
optionName,
description,
bn.asBoolean()
));
}
else
{
// check next for integer
bn = descNode.get("integer-value");
if (bn != null)
{
list.add(new RuntimeOptionDescriptorImpl(
optionName,
description,
bn.asInt()
));
}
else
{
// this must be a string
bn = descNode.get("string-value");
list.add(new RuntimeOptionDescriptorImpl(
optionName,
description,
bn.asText()
));
}
}
}
return list;
}
catch (JsonSchemaValidationException e)
{
throw new IllegalArgumentException("Bad operations descriptor", e);
}
}
public ObjectNode getResourceObject(String id)
{
String src = getResource(id);
if (src == null)
{
return null;
}
try
{
JsonNode node = JsonUtils.loadJson(src);
if (!node.isObject())
{
throw new IllegalArgumentException("Bad json. Root not an object");
}
return (ObjectNode) node;
}
catch (Exception e)
{
throw new UnsupportedOperationException(simpleName + "." + id, e);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy