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

it.uniroma2.art.sheet2rdf.cfg.GraphApplicationConfigurationParser Maven / Gradle / Ivy

There is a newer version: 6.0.6
Show newest version
package it.uniroma2.art.sheet2rdf.cfg;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import org.eclipse.rdf4j.rio.ntriples.NTriplesUtil;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

import it.uniroma2.art.coda.interfaces.annotations.converters.RDFCapabilityType;
import it.uniroma2.art.sheet2rdf.coda.CODAConverter;
import it.uniroma2.art.sheet2rdf.header.AdvancedGraphApplication;
import it.uniroma2.art.sheet2rdf.header.NodeConversion;
import it.uniroma2.art.sheet2rdf.utils.S2RDFUtils;

public class GraphApplicationConfigurationParser {
	
	private ObjectNode cfgJson;
	private ObjectMapper mapper;
	private String placeholderPrefix;
	
	private Map nodeIdReplacementMap;
	
	public GraphApplicationConfigurationParser(ObjectNode cfgJson, String placeholderPrefix) {
		this.cfgJson = cfgJson;
		mapper = new ObjectMapper();
		this.placeholderPrefix = placeholderPrefix;
		nodeIdReplacementMap = new HashMap();
	}

	public List getNodeConversions() {
		JsonNode nodesJson = cfgJson.get("nodes");
		List nodes = new ArrayList();
		for (int i = 0; i < nodesJson.size(); i++) {
			NodeConversion node = new NodeConversion();
			JsonNode nodeJson = nodesJson.get(i);
			//id
			String nodeId = nodeJson.get("nodeId").asText();
			String prefixedNodeId = placeholderPrefix + "_" + nodeId;
			nodeIdReplacementMap.put(nodeId, prefixedNodeId);
			node.setNodeId(prefixedNodeId);
			//converter
			CODAConverter converter = new CODAConverter();
			JsonNode converterJson = nodeJson.get("converter");
			converter.setType(RDFCapabilityType.valueOf(converterJson.get("type").asText()));
			converter.setContractUri(converterJson.get("contractUri").asText());
			JsonNode langJson = converterJson.get("language");
			if (!langJson.isNull()) {
				converter.setLanguage(langJson.asText());
			}
			JsonNode dtUriJson = converterJson.get("datatypeUri");
			if (!dtUriJson.isNull()) {
				converter.setDatatypeUri(dtUriJson.asText());
			}
			JsonNode paramsJson = converterJson.get("params"); 
			Map paramsMap = mapper.convertValue(paramsJson, new TypeReference>(){});
			Map params = resolveConverterParamsMap(paramsMap);
			//set the params as it is in the configuration file. The node id references will be replaced later
			converter.setParams(params);
			node.setConverter(converter);
			//memoize
			node.setMemoize(nodeJson.get("memoize").asBoolean());
			
			nodes.add(node);
		}
		//parameters replaced after each node has been copied, so the nodeIdReplacementMap is complete
		for (NodeConversion n: nodes) {
			CODAConverter converter = n.getConverter();
			Map replacedParamMap = S2RDFUtils.replaceNodesIdInConverterParams(converter.getParams(), nodeIdReplacementMap);
			converter.setParams(replacedParamMap);
		}
		return nodes;
	}
	
	
	public AdvancedGraphApplication getAdvancedGraphApplication(List nodes) {
		AdvancedGraphApplication g = new AdvancedGraphApplication();
		//graph pattern
		JsonNode graphPatternJson = cfgJson.get("graphPattern");
		String graphPattern = graphPatternJson.asText();
		String prefixedGraphPattern = S2RDFUtils.replaceNodesIdInGraphPattern(graphPattern, nodeIdReplacementMap);
		g.setPattern(prefixedGraphPattern);
		//referenced nodes ID
		List nodeIds = new ArrayList();
		for (NodeConversion n: nodes) {
			nodeIds.add(n.getNodeId()); 
		}
		g.setNodeIds(nodeIds);
		//prefix mapping
		JsonNode prefixMappingJson = cfgJson.get("prefixMapping");
		Map prefixMapping = mapper.convertValue(prefixMappingJson, new TypeReference>(){});
		g.setPrefixMapping(prefixMapping);
		
		return g;
	}
	
	/**
	 * The converter parameters object should be a map key-value where the key are string and the values could be:
	 * - String
	 * - List: (e.g args of TurtleCollection converter)
	 * 		actually it should be List but value can be represented by a rdf4j Value or by a nodeId (string).
	 * - Map (e.g. args parameter of random converter)
	 * 		actually it should be Map but value can be represented by a rdf4j Value or by a nodeId (string).
	 * 
	 * Unfortunately the Map, where Object could be a Map or a List, cannot be parsed, by a spring converter.
	 * So as a workaround I get a Map and here I manually parse the values.
	 */
	private Map resolveConverterParamsMap(Map convParamsMap) {
		Map resolvedConvParams = new LinkedHashMap<>();
		Iterator> itEntries = convParamsMap.entrySet().iterator();
		while (itEntries.hasNext()) {
			Entry entry = itEntries.next();
			Object value = entry.getValue();
			if (value instanceof Map) { //value is a map => convert it
				//resolve in turn the map value
				Map nestedResolvedMap = resolveConverterParamsMap((Map) value);
				resolvedConvParams.put(entry.getKey(), nestedResolvedMap);
			} else if (value instanceof List) { //value is a list
				ListvalueAsList = (List) value;
				//resolve in turn the list value
				List nestedResolvedList = new ArrayList<>();
				for (String v: valueAsList) {
					nestedResolvedList.add(parseStringOrValue(v));
				}
				resolvedConvParams.put(entry.getKey(), nestedResolvedList);
			} else if (value instanceof String) { //simple string or rdf4j Ntriples serialization?
				Object resolvedValue = parseStringOrValue((String) value);
				resolvedConvParams.put(entry.getKey(), resolvedValue);					
			}
		}
		return resolvedConvParams;
	}
	
	/**
	 * Try to parse a string as a rdf4j Value. If the parsing fails, returns it as a plain String.
	 * @param s
	 * @return
	 */
	private Object parseStringOrValue(String s) {
		try {
			Value rdf4jValue = NTriplesUtil.parseValue(s, SimpleValueFactory.getInstance());
			return rdf4jValue;
		} catch (IllegalArgumentException e) {
			return s;
		}
	}
	
	
	
}