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

com.regnosys.rosetta.translate.util.JsonProcessor Maven / Gradle / Ivy

There is a newer version: 11.35.2
Show newest version
package com.regnosys.rosetta.translate.util;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.net.URL;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.regnosys.rosetta.common.util.UrlUtils;

/**
 * Unintelligent pre-processor of ISDA CREATE JSON documents
 *
 * @author nikos
 */
public class JsonProcessor {

	private final String baseNodeName;
	private final ObjectMapper mapper;

	public JsonProcessor(String baseNode, ObjectMapper mapper) {
		this.baseNodeName = baseNode;
		this.mapper = mapper;
	}

	/**
	 * Takes advantage of the fact that all likely work happens at one level
	 * When there is a partyA_xxx entry, ensure that there is a corresponding partyB_xxx entry
	 * and that partyA_xxx values come before partyB_xxx values
	 *
	 * @param input the JSON URL
	 * @return
	 * @throws IOException
	 */
	public Reader process(URL input) throws IOException {
		return process(UrlUtils.openURL(input));
	}
	
	
	public Reader process(Reader input) throws IOException {
		Map jsonMap = mapper.readValue(input, new TypeReference>() {
		});
		if (!isMap(jsonMap.get(baseNodeName))) {
			throw new IllegalArgumentException("Invalid base node name (should be a map)" + baseNodeName);
		}
		// TODO: make recursive at this level, in case we do get subsequent nested levels of partyA/partyB
		@SuppressWarnings("unchecked")
		Map baseNode = (Map) jsonMap.get(baseNodeName);
		for (String childNodeName : baseNode.keySet()) {
			if (!isMap(baseNode.get(childNodeName))) {
				throw new IllegalArgumentException("JSON contains unexpected data");
			}
			@SuppressWarnings("unchecked")
			Map childNode = (Map) baseNode.get(childNodeName);
			Map symmetricalSorted = makePartiesSymmetrical(childNode);
			baseNode.put(childNodeName, symmetricalSorted);
		}
		return new StringReader(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonMap));
	}

	// 
	// inefficient, it might double check values, but will do
	//
	private Map makePartiesSymmetrical(Map map) {
		SortedMap sortedMap = new TreeMap<>();
		Set> entries = map.entrySet();
		boolean mustSort = entries.stream().anyMatch(k -> k.getKey().startsWith("partyA") | k.getKey().startsWith("partyB"));
		for (Entry entry : entries) {
			if (entry.getKey().startsWith("partyA") || entry.getKey().startsWith("partyB")) {
				sortedMap.put(entry.getKey(), entry.getValue());
				ensureSymmetry(entry, "partyA", "partyB", map, sortedMap);
				ensureSymmetry(entry, "partyB", "partyA", map, sortedMap);
			} else {
				if (mustSort) {
					// just copy over
					sortedMap.put(entry.getKey(), entry.getValue());
				}
			}
		}
		if (mustSort) {
			return sortedMap;
		}
		// if no need to do anything, just return the original!
		return map;
	}

	private void ensureSymmetry(Entry entry, String one, String other, Map originMap, SortedMap sortedMap) {
		if (entry.getKey().startsWith(one)) {
			String key = entry.getKey().replace(one, other);
			if (originMap.containsKey(key)) {
				// fine, just copy over
				sortedMap.put(key, originMap.get(key));
			} else {
				// create "empty" entry
				sortedMap.put(key, "");
			}
		}
	}

	private boolean isMap(Object obj) {
		return obj instanceof Map;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy