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

com.futuresight.util.mystique.JsonMystique Maven / Gradle / Ivy

There is a newer version: 1.0.8
Show newest version
/*
 * Copyright (c) Balajee TM 2016.
 * All rights reserved.
 * License -  @see 
 */

/*
 * Created on 25 Aug, 2016 by balajeetm
 */
package com.futuresight.util.mystique;

import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Component;

import com.futuresight.util.mystique.lever.MysCon;
import com.google.common.reflect.TypeToken;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;

/**
 * The Class JsonMystique.
 *
 * @author balajeetm
 */
@Component
public class JsonMystique {

	/** The logger. */
	private Logger logger = Logger.getLogger(this.getClass());

	/** The factory. */
	@Autowired
	private MystiqueFactory factory;

	/** The json lever. */
	@Autowired
	private JsonLever jsonLever;

	/** The tarots. */
	private Map> tarots;

	/**
	 * Instantiates a new json genie.
	 */
	private JsonMystique() {
		tarots = new HashMap>();
	}

	/**
	 * Inits the.
	 */
	@PostConstruct
	protected void init() {
		String locationPattern = "classpath:jsonmystique/**/*.mys";
		ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
		Resource[] resources = null;
		try {
			resources = resourceResolver.getResources(locationPattern);
		}
		catch (IOException e) {
			logger.error(String.format("Error loading mystiques from %s - %s", locationPattern, e.getMessage()), e);
			return;
		}

		if (!ArrayUtils.isEmpty(resources)) {
			for (Resource resource : resources) {
				if (resource.exists()) {
					String specName = FilenameUtils.removeExtension(resource.getFilename());
					try {
						@SuppressWarnings("serial")
						Type type = new TypeToken>() {
						}.getType();
						List fromJson = jsonLever.getGson().fromJson(
								new InputStreamReader(resource.getInputStream()), type);
						tarots.put(specName, fromJson);
					}
					catch (JsonSyntaxException | IllegalArgumentException | IOException exception) {
						logger.error(String.format(
								"Unable to load mystiques %s from %s - %s. Trying to load other mystiques if any",
								specName, locationPattern, exception.getMessage()), exception);
						continue;
					}
				}
			}
		}
		else {
			logger.warn(String.format("No mystiques found @ %s for transformation", locationPattern));
		}
	}

	/**
	 * Transform.
	 *
	 * @param inputJson the input json
	 * @param specName the spec name
	 * @return the json element
	 */
	public JsonElement transform(String inputJson, String specName) {
		JsonElement source = jsonLever.getJsonParser().parse(inputJson);
		return transform(source, specName);
	}

	/**
	 * Transform.
	 *
	 * @param source the source
	 * @param specName the spec name
	 * @return the json element
	 */
	public JsonElement transform(JsonElement source, String specName) {
		return transform(source, specName, new JsonObject());
	}

	/**
	 * Transform.
	 *
	 * @param inputJson the input json
	 * @param specName the spec name
	 * @param deps the deps
	 * @return the json element
	 */
	public JsonElement transform(String inputJson, String specName, JsonObject deps) {
		JsonElement source = jsonLever.getJsonParser().parse(inputJson);
		return transform(source, specName, deps);
	}

	/**
	 * Transform.
	 *
	 * @param source the source
	 * @param specName the spec name
	 * @param deps the deps
	 * @return the json element
	 */
	public JsonElement transform(JsonElement source, String specName, JsonObject deps) {
		return transform(source, specName, deps, null);
	}

	/**
	 * Transform.
	 *
	 * @param source the source
	 * @param specName the spec name
	 * @param deps the deps
	 * @param aces the aces
	 * @return the json element
	 */
	protected JsonElement transform(JsonElement source, String specName, JsonObject deps, JsonObject aces) {
		List tarotList = tarots.get(specName);
		JsonObject dependencies = null == deps ? new JsonObject() : deps;
		JsonElement transform = transform(source, tarotList, dependencies, aces);
		if (jsonLever.isNull(transform)) {
			logger.info(String.format("Transformed value for spec %s is null", specName));
		}
		return transform;
	}

	/**
	 * Transform to string.
	 *
	 * @param inputJson the input json
	 * @param specName the spec name
	 * @return the string
	 */
	public String transformToString(String inputJson, String specName) {
		return String.valueOf(transform(inputJson, specName));
	}

	/**
	 * Transform to string.
	 *
	 * @param inputJson the input json
	 * @param specName the spec name
	 * @param deps the deps
	 * @return the string
	 */
	public String transformToString(String inputJson, String specName, JsonObject deps) {
		return String.valueOf(transform(inputJson, specName, deps));
	}

	/**
	 * Transform to string.
	 *
	 * @param source the source
	 * @param specName the spec name
	 * @return the string
	 */
	public String transformToString(JsonElement source, String specName) {
		return String.valueOf(transform(source, specName));
	}

	/**
	 * Transform to string.
	 *
	 * @param source the source
	 * @param specName the spec name
	 * @param deps the deps
	 * @return the string
	 */
	public String transformToString(JsonElement source, String specName, JsonObject deps) {
		return String.valueOf(transform(source, specName, deps));
	}

	/**
	 * Transform.
	 *
	 * @param source the source
	 * @param tarotList the tarot list
	 * @param dependencies the dependencies
	 * @return the json element
	 */
	private JsonElement transform(JsonElement source, List tarotList, JsonObject dependencies) {
		return transform(source, tarotList, dependencies, null);
	}

	/**
	 * Transform.
	 *
	 * @param source the source
	 * @param tarotList the tarot list
	 * @param dependencies the dependencies
	 * @param parentAces the parent aces
	 * @return the json element
	 */
	private JsonElement transform(JsonElement source, List tarotList, JsonObject dependencies,
			JsonObject parentAces) {
		JsonObject resultWrapper = new JsonObject();
		resultWrapper.add(MysCon.RESULT, JsonNull.INSTANCE);
		if (CollectionUtils.isNotEmpty(tarotList)) {
			for (Tarot tarot : tarotList) {
				updateDependencies(source, tarot.getDeps(), dependencies);
				JsonObject aces = tarot.getAces();
				jsonLever.getUpdatedAces(source, aces, dependencies);
				jsonLever.simpleMerge(parentAces, aces);
				JsonObject turn = tarot.getTurn();
				try {
					MystTurn mystique = factory.getMystTurn(turn);
					Spell spell = getSpell(source, tarot.getFrom(), dependencies, aces, turn, resultWrapper);
					JsonElement transform = spell.cast(mystique);
					resultWrapper = jsonLever.setField(resultWrapper, tarot.getTo(), transform, aces,
							tarot.getOptional());
				}
				catch (RuntimeException e) {
					logger.info(
							String.format("Error transforming input with specification for turn %s - %s", turn,
									e.getMessage()), e);
					continue;
				}
			}
		}
		else {
			logger.info(String.format("Invalid tarots. Tarots cannot be empty"));
		}
		return resultWrapper.get(MysCon.RESULT);
	}

	/**
	 * Gets the spell.
	 *
	 * @param source the source
	 * @param from the from
	 * @param dependencies the dependencies
	 * @param aces the aces
	 * @param turn the turn
	 * @param resultWrapper the result wrapper
	 * @return the spell
	 */
	private Spell getSpell(JsonElement source, JsonArray from, JsonObject dependencies, JsonObject aces,
			JsonObject turn, JsonObject resultWrapper) {
		List fields = new ArrayList<>();
		Boolean isFromLoopy = getFields(source, dependencies, aces, from, fields);
		//Ideally isDeps should never be loopy
		Spell spell = isFromLoopy ? new LoopySpell(fields, dependencies, aces, turn, resultWrapper) : new SimpleSpell(
				fields, dependencies, aces, turn, resultWrapper);
		return spell;
	}

	/**
	 * Gets the fields.
	 *
	 * @param source the source
	 * @param dependencies the dependencies
	 * @param aces the aces
	 * @param path the path
	 * @param fields the fields
	 * @return the fields
	 */
	private Boolean getFields(JsonElement source, JsonObject dependencies, JsonObject aces, JsonArray path,
			List fields) {
		Boolean isLoopy = Boolean.FALSE;
		if (null != path) {
			if (path.size() > 0) {
				for (JsonElement jsonElement : path) {
					if (jsonElement.isJsonArray()) {
						JsonArray fromArray = jsonElement.getAsJsonArray();
						isLoopy = isLoopy || jsonLever.updateFields(source, dependencies, aces, fields, fromArray);
						//Once isloopy, the loop doesn't execute anymore
					}
					else {
						isLoopy = isLoopy || jsonLever.updateFields(source, dependencies, aces, fields, path);
						break;
					}
				}
			}
			else {
				isLoopy = isLoopy || jsonLever.updateFields(source, dependencies, aces, fields, path);
			}
		}
		return isLoopy;
	}

	/**
	 * Update dependencies.
	 *
	 * @param source the source
	 * @param deps the deps
	 * @param dependencies the dependencies
	 */
	private void updateDependencies(JsonElement source, List deps, JsonObject dependencies) {
		if (CollectionUtils.isNotEmpty(deps)) {
			try {
				JsonObject transformJson = jsonLever.getAsJsonObject(transform(source, deps, dependencies),
						new JsonObject());
				jsonLever.simpleMerge(transformJson, dependencies);
			}
			catch (RuntimeException e) {
				logger.info(String.format("Could not update dependencies : %s", e.getMessage()));
			}
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy