package ru.semiot.platform.apigateway.utils;
import org.apache.jena.datatypes.xsd.XSDDatatype;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.Triple;
import org.apache.jena.rdf.model.Literal;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Property;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.rdf.model.ResourceFactory;
import org.apache.jena.riot.Lang;
import org.apache.jena.riot.RDFDataMgr;
import org.apache.jena.riot.system.StreamRDFBase;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class RDFUtils {
public static String toString(Model model, Lang lang) {
StringWriter writer = new StringWriter();
model.write(writer, lang.getName());
return writer.toString();
}
public static Model toModel(String rdf, Lang lang) {
StringReader reader = new StringReader(rdf);
return ModelFactory.createDefaultModel().read(reader, null, lang.getName());
}
public static boolean match(String turtle, Node subject, Node predicate, Node object) {
MatchSinkRDF matcher = new MatchSinkRDF(subject, predicate, object);
RDFDataMgr.parse(matcher,
new StringReader(turtle), Lang.TURTLE);
return matcher.match;
}
public static Literal toLiteral(Object value) {
if (value instanceof String) {
return ResourceFactory.createPlainLiteral(value.toString());
}
if (value instanceof Double) {
return ResourceFactory.createTypedLiteral(value.toString(),
XSDDatatype.XSDdouble);
}
throw new IllegalArgumentException();
}
public static List<Resource> listResourcesWithProperty(Model model, Property p,
RDFNode... objects) {
Map<Resource, Integer> counts = new HashMap<>();
for (RDFNode object : objects) {
List<Resource> resources = model.listResourcesWithProperty(p, object).toList();
resources.stream().forEach((resource) -> {
if (counts.containsKey(resource)) {
counts.put(resource, counts.get(resource) + 1);
} else {
counts.put(resource, 1);
}
});
}
return Arrays.asList(counts.keySet().stream().filter(
(resource) -> (counts.get(resource) == objects.length)).toArray(Resource[]::new));
}
public static Resource subjectWithProperty(Model model, Property property, RDFNode object) {
return model.listSubjectsWithProperty(property, object).next();
}
private static class MatchSinkRDF extends StreamRDFBase {
private final Node subject;
private final Node predicate;
private final Node object;
private boolean match = false;
public MatchSinkRDF(Node subject, Node predicate, Node object) {
this.subject = subject;
this.predicate = predicate;
this.object = object;
}
@Override
public void triple(Triple triple) {
boolean subjectMatch = subject != Node.ANY ? triple.subjectMatches(subject) : true;
boolean predicateMatch = predicate != Node.ANY ? triple.predicateMatches(predicate) : true;
boolean objectMatch = object != Node.ANY ? triple.objectMatches(object) : true;
if (subjectMatch && predicateMatch && objectMatch) {
match = true;
}
}
public boolean matches() {
return match;
}
}
}