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

it.uniroma2.art.sheet2rdf.coda.CODAConverter Maven / Gradle / Ivy

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

import java.util.ArrayList;
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.rio.ntriples.NTriplesUtil;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.base.Joiner;

import it.uniroma2.art.coda.converters.contracts.ContractConstants;
import it.uniroma2.art.coda.converters.contracts.DefaultConverter;
import it.uniroma2.art.coda.interfaces.annotations.converters.RDFCapabilityType;

public class CODAConverter {
	
	private RDFCapabilityType type;
	private String contractUri;
	private String language; //in case type is "literal" this represents the language in "literal@it"
	private String datatypeUri; //in case type is "literal" this represents the datatype in "literal^^xsd:string"
	private String datatypeCapability; //datatype capability that the converter can produce (e.g. coda:date produces xsd:date)
	private Map params;
	/*
	 * A value of the params map can 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).
	 */
	
	public CODAConverter() {
		this(RDFCapabilityType.uri, DefaultConverter.CONTRACT_URI);
	}
	
	public CODAConverter(RDFCapabilityType type) {
		this(type, DefaultConverter.CONTRACT_URI);
	}
	
	public CODAConverter(RDFCapabilityType type, String contractUri) {
		this.type = type;
		this.contractUri = contractUri;
		this.params = new LinkedHashMap<>();
	}
	
	public RDFCapabilityType getType() {
		return type;
	}

	public void setType(RDFCapabilityType type) {
		this.type = type;
	}

	public String getContractUri() {
		return contractUri;
	}

	public void setContractUri(String contractUri) {
		this.contractUri = contractUri;
	}
	
	@JsonIgnore
	public String getContractQname() {
		return contractUri.replace(ContractConstants.CODA_CONTRACTS_BASE_URI, "coda:");
	}
	
	public String getLanguage() {
		return language;
	}
	
	public void setLanguage(String language) {
		this.language = language;
	}
	
	public String getDatatypeUri() {
		return datatypeUri;
	}
	
	public void setDatatypeUri(String datatypeUri) {
		this.datatypeUri = datatypeUri;
	}

	public String getDatatypeCapability() {
		return datatypeCapability;
	}

	public void setDatatypeCapability(String datatypeCapability) {
		this.datatypeCapability = datatypeCapability;
	}
	
	public Map getParams() {
		return params;
	}
	
	public void addParam(String name, Object value) {
		this.params.put(name, value);
	}
	
	public void setParams(Map params) {
		this.params = params;
	}
	
	public void removeParam(String name) {
		this.params.remove(name);
	}

	public String serialize(Map prefixMapping) {
		String convString = type.name();
		
		if (type.equals(RDFCapabilityType.literal)) {
			if (language != null) {
				convString += "@" + language;
			} else if (datatypeUri != null) { //language and datatype are mutual exclusive
				String datatypeSerialization = "<" + datatypeUri + ">";
				for (Entry mapEntry : prefixMapping.entrySet()) { //try to QName-ing the datatype
					String prefix = mapEntry.getKey();
					String ns = mapEntry.getValue();
					if (datatypeUri.startsWith(ns)) {
						datatypeSerialization = datatypeUri.replace(ns, prefix + ":");
						break;
					}
				}
				convString += "^^" + datatypeSerialization;
			}
		}
		
		if (!contractUri.equals(DefaultConverter.CONTRACT_URI)) {//if it's not the default converter
			convString += "("; //open round brackets of contract uri 
			convString += getContractQname();
			convString += "("; //open round brackets of converter parameters
			
			if (!params.isEmpty()) {
				Iterator> it = params.entrySet().iterator();
				List convParams = new ArrayList<>(); //list of parameters serialization to be joined later
				while (it.hasNext()) {
					Entry entry = it.next();
					Object value = entry.getValue();
					if (value instanceof String) {
						convParams.add("'" + value + "'");
					} else if (value instanceof Map) {
						Map valueAsMap = (Map)value;
						Map valueAsStringMap = new LinkedHashMap();
						for (Entry e : valueAsMap.entrySet()) {
							Object v = e.getValue();
							if (v instanceof Value) {
								valueAsStringMap.put(e.getKey(), NTriplesUtil.toNTriplesString((Value)v)); //value represents a rdf4j Values => serialize to NT 
							} else { //string
								valueAsStringMap.put(e.getKey(), "$" + v); //value represents a nodeId => serialize as $
							}
						}
						String mapSerialization = "{";
						mapSerialization += Joiner.on(",").withKeyValueSeparator(" = ").join(valueAsStringMap);
						mapSerialization += "}";
						convParams.add(mapSerialization);
					} else if (value instanceof List) {
						List valueAsList = (List)value;
						List valueAsStringList = new ArrayList<>();
						for (Object v: valueAsList) {
							if (v instanceof Value) {//value represents a rdf4j Values => serialize to NT
								valueAsStringList.add(NTriplesUtil.toNTriplesString((Value)v)); 
							} else { //string, value represents a nodeId => serialize as $
								valueAsStringList.add("$" + v); 
							}
						}
						String listSerialization = String.join(",", valueAsStringList);
						convParams.add(listSerialization);
					}
				}
				convString += String.join(",", convParams);
			}
			convString += ")"; //closes round brackets of converter parameters
			convString += ")"; //closes round brackets of contract uri
		}
		return convString;
	}
	
	/**
	 * Check if the converter params contain a reference to another node id.
	 * This is useful in order to avoid the serialization in the pearl of a node definition that contains a reference
	 * to another node still not defined
	 * @return
	 */
	public boolean containsNodeReference() {
		if (!params.isEmpty()) {
			Iterator> it = params.entrySet().iterator();
			while (it.hasNext()) {
				Entry entry = it.next();
				Object value = entry.getValue();
				if (value instanceof Map) {
					Map valueAsMap = (Map)value;
					for (Entry e : valueAsMap.entrySet()) {
						Object v = e.getValue();
						if (v instanceof String) { //reference to a nodeId
							return true;
						}
					}
				} else if (value instanceof List) {
					List valueAsList = (List)value;
					for (Object v: valueAsList) {
						if (v instanceof String) { //reference to a nodeId
							return true; 
						}
					}
				}
			}
		}
		return false;
	}
	
	public String toString() {
		String s = "";
		s += "type:\t\t" + this.type + "\n";
		s += "contract:\t" + this.contractUri + "\n";
		s += "lang:\t\t" + this.language + "\n";
		s += "dt:\t\t" + this.datatypeUri + "\n";
		s += "params:\t\t" + this.params;
		return s;
	}
}