package com.narphorium.entity_builder;
import com.github.jsonldjava.core.JsonLdError;
import com.github.jsonldjava.core.JsonLdOptions;
import com.github.jsonldjava.core.JsonLdProcessor;
import com.github.jsonldjava.utils.JsonUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
public class EntityFrame {
private static final String RDF_TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
private Object frame;
private Set<String> mappedTypes;
private Set<String> mappedPredicates;
private Map<Integer, Set<String>> pivotsByRank;
private int maxRank;
public void parse(File file) throws IOException {
parse(new FileInputStream(file));
}
public void parse(InputStream inputStream) throws IOException {
frame = JsonUtils.fromInputStream(inputStream);
JsonLdOptions options = new JsonLdOptions();
options.setExplicit(false);
options.setEmbed(true);
options.setExpandContext(frame);
try {
Object expanded = JsonLdProcessor.expand(frame, options);
Object flattened = JsonLdProcessor.flatten(frame, options);
mappedTypes = new TreeSet<String>();
for (Map<String, Object> flatObj : (List<Map<String, Object>>) flattened) {
if (flatObj.containsKey("@type")) {
String type = ((List) flatObj.get("@type")).get(0).toString();
mappedTypes.add(type);
}
}
mappedPredicates = findMappedPredicates(flattened);
mappedPredicates.remove("@id");
mappedPredicates.remove("@type");
mappedPredicates.add(RDF_TYPE);
pivotsByRank = new TreeMap<Integer, Set<String>>();
findPivots(expanded, pivotsByRank);
for (Map.Entry<Integer, Set<String>> entry : pivotsByRank.entrySet()) {
for (String pred : entry.getValue()) {
mappedPredicates.add("!" + pred);
}
}
} catch (JsonLdError e) {
e.printStackTrace();
}
}
private int findPivots(Object node, Map<Integer, Set<String>> pivotsByRank) {
if (node instanceof Map) {
int maxRank = -1;
if (!((Map<String, Object>) node).isEmpty()) {
for (Map.Entry<String, Object> entry : ((Map<String, Object>) node).entrySet()) {
int subRank = findPivots(entry.getValue(), pivotsByRank);
if (subRank >= 0) {
Set<String> pivots;
if (pivotsByRank.containsKey(subRank)) {
pivots = pivotsByRank.get(subRank);
} else {
pivots = new TreeSet<String>();
pivotsByRank.put(subRank, pivots);
}
pivots.add(entry.getKey());
}
maxRank = Math.max(maxRank, subRank);
this.maxRank = Math.max(maxRank, this.maxRank);
}
maxRank++;
}
return maxRank;
} else if (node instanceof List) {
int maxRank = -1;
for (Object element : (List<Object>) node) {
int subRank = findPivots(element, pivotsByRank);
maxRank = Math.max(maxRank, subRank);
this.maxRank = Math.max(maxRank, this.maxRank);
}
return maxRank;
} else {
return -1;
}
}
private Set<String> findMappedPredicates(Object node) {
Set<String> mappedPredicates = new TreeSet<String>();
if (node instanceof Map) {
Map<String, Object> map = (Map<String, Object>) node;
mappedPredicates.addAll(map.keySet());
for (Object value : map.values()) {
mappedPredicates.addAll(findMappedPredicates(value));
}
} else if (node instanceof List) {
for (Object element : (List<Object>) node) {
mappedPredicates.addAll(findMappedPredicates(element));
}
}
return mappedPredicates;
}
public Object getFrame() {
return frame;
}
public Set<String> getMappedTypes() {
return mappedTypes;
}
public Set<String> getMappedPredicates() {
return mappedPredicates;
}
public Set<String> getPivots(int rank) {
return pivotsByRank.containsKey(rank) ? pivotsByRank.get(rank) : new HashSet<String>();
}
public int getMaxRank() {
return maxRank;
}
}