All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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