Commit 2ec34c1e authored by bseeger's avatar bseeger
Browse files

Merge branch 'entailment2' into 'master'

Simplify entailment code

See merge request !97
parents 73cb8992 da378e90
# Comma separated list of ontologies that should pulled in for entailment to be done on them
rdfs.ontologies=http://purl.org/dc/terms/,http://purl.org/dc/elements/1.1/,http://id.loc.gov/ontologies/bibframe/,http://www.w3.org/2004/02/skos/core#,http://www.w3.org/2000/01/rdf-schema#
rdfs.ontologies= \
http://purl.org/dc/terms/, \
http://www.w3.org/2004/02/skos/core#
......@@ -15,8 +15,8 @@
*/
package edu.amherst.acdc.services.entailment;
import static java.util.Arrays.stream;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toMap;
import static org.apache.http.impl.client.HttpClientBuilder.create;
import static org.apache.jena.rdf.model.ModelFactory.createDefaultModel;
import static org.apache.jena.rdf.model.ModelFactory.createRDFSModel;
......@@ -30,19 +30,16 @@ import static org.slf4j.LoggerFactory.getLogger;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.jena.rdf.model.InfModel;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.rdf.model.Statement;
import org.apache.jena.riot.Lang;
import org.apache.jena.riot.RDFLanguages;
import org.apache.jena.vocabulary.RDF;
import org.apache.jena.vocabulary.RDFS;
import org.slf4j.Logger;
/**
......@@ -55,7 +52,7 @@ public class EntailmentServiceImpl implements EntailmentService {
private static final Lang DEFAULT_LANG = TURTLE;
private InfModel rdfsModel = createRDFSModel(createDefaultModel());
private InfModel schema = createRDFSModel(createDefaultModel());
static {
setDefaultHttpClient(create().setRedirectStrategy(new LaxRedirectStrategy()).build());
......@@ -71,71 +68,40 @@ public class EntailmentServiceImpl implements EntailmentService {
public EntailmentServiceImpl(final String ontologies) {
LOGGER.info("EntailmentServiceImpl: ontologies: {}", ontologies);
Arrays.stream(ontologies.split(","))
.peek(ont -> LOGGER.info("adding to rdfs model: {}", ont))
.map(String::trim)
.forEach(ont -> read(rdfsModel, ont));
stream(ontologies.split(",")).peek(ont -> LOGGER.info("adding to rdfs model: {}", ont))
.map(String::trim).forEach(ont -> read(schema, ont));
}
@Override
public InputStream getEntailedTriples(final String subject, final InputStream input,
final String contentType, final String acceptType) {
final String contentType, final String acceptType) {
final Model model = createDefaultModel();
read(model, input, contentTypeToLang(contentType.split(";")[0]));
// perform RDFS entailment over it by creating a RDFSModel
final InfModel fullModel = createRDFSModel(model);
// add the requested ontologies to the model, which does RDFS entailment over them.
fullModel.add(rdfsModel);
final Model entailed = fullModel.difference(rdfsModel);
final Model entailed = createDefaultModel();
entailed.setNsPrefixes(model);
final Resource subjectResource = entailed.getResource(subject);
final List<Statement> props = subjectResource.listProperties().toList();
createRDFSModel(schema, model).listStatements()
// We don't care about rdfs:Class and rdfs:Resource types
.filterDrop(s -> isRdfsClass(s) || isRdfsResource(s))
.filterDrop(t -> schema.contains(t.getSubject(), null))
.forEachRemaining(entailed::add);
final Model newResourceModel = createDefaultModel();
newResourceModel.add(subjectResource.listProperties().toList());
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
write(baos, entailed, getRdfLanguage(acceptType.split(";")[0]).orElse(DEFAULT_LANG));
return new ByteArrayInputStream(baos.toByteArray());
}
final Map<String,String> prefixMap = getPrefixMap(newResourceModel, entailed.getNsPrefixMap());
newResourceModel.setNsPrefixes(prefixMap);
private boolean isRdfsClass(final Statement stmt) {
return stmt.getPredicate().equals(RDF.type) && stmt.getResource().equals(RDFS.Class);
}
final ByteArrayOutputStream nbs = new ByteArrayOutputStream();
write(nbs, newResourceModel, getRdfLanguage(acceptType.split(";")[0]).orElse(DEFAULT_LANG));
return new ByteArrayInputStream(nbs.toByteArray());
private boolean isRdfsResource(final Statement stmt) {
return stmt.getPredicate().equals(RDF.type) && stmt.getResource().equals(RDFS.Resource);
}
private Optional<Lang> getRdfLanguage(final String contentType) {
return ofNullable(contentType).map(RDFLanguages::contentTypeToLang);
}
private Map<String,String> getPrefixMap(final Model model, final Map<String,String> prefixes) {
final List<Statement> props = model.listStatements().toList();
final Map<String,String> modelPrefixes = new HashMap<>();
final Map<String,String> flip_prefixes =
prefixes.entrySet().stream().collect(toMap(Map.Entry::getValue, Map.Entry::getKey, (key1, key2) -> key1));
LOGGER.debug("There are {} properties on resource", props.size());
props.forEach(statement -> {
final String pred_prefix = statement.getPredicate().getNameSpace();
if (flip_prefixes.containsKey(pred_prefix)) {
modelPrefixes.put(flip_prefixes.get(pred_prefix), pred_prefix);
}
if (statement.getObject().isResource()) {
final String obj_prefix = statement.getResource().getNameSpace();
if (flip_prefixes.containsKey(obj_prefix)) {
modelPrefixes.put(flip_prefixes.get(obj_prefix), obj_prefix);
}
}
});
return modelPrefixes;
}
}
......@@ -9,7 +9,7 @@
<cm:property-placeholder persistent-id="edu.amherst.acdc.services.entailment" update-strategy="reload" >
<cm:default-properties>
<cm:property name="rdfs.ontologies" value=""/>
<cm:property name="rdfs.ontologies" value="http://purl.org/dc/terms/,http://www.w3.org/2004/02/skos/core#"/>
</cm:default-properties>
</cm:property-placeholder>
......
......@@ -19,15 +19,17 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import static org.apache.jena.rdf.model.ModelFactory.createDefaultModel;
import static org.apache.jena.riot.RDFDataMgr.read;
import static org.apache.jena.riot.Lang.JSONLD;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.slf4j.LoggerFactory.getLogger;
import java.io.InputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.Resource;
import org.junit.Test;
import org.slf4j.Logger;
/**
......@@ -59,9 +61,9 @@ public class EntailmentServiceTest {
final String str = sw.toString();
LOGGER.debug("string is : '{}'", str);
assertFalse(str.equals(""));
assertTrue(str.contains("rdfs:Resource") && str.contains("skos:Concept"));
assertTrue(str.contains("skos:broaderTransitive") && str.contains("skos:semanticRelation"));
assertTrue(str.contains("skos:Concept"));
assertTrue(str.contains("skos:broaderTransitive"));
assertTrue(str.contains("skos:semanticRelation"));
}
@Test
......@@ -73,8 +75,7 @@ public class EntailmentServiceTest {
final String str = sw.toString();
LOGGER.debug("string is : '{}'", str);
assertFalse(str.equals(""));
assertTrue(str.contains("rdfs:Resource") && str.contains("rdfs:label"));
assertTrue(str.contains("rdfs:label"));
}
@Test
......@@ -86,9 +87,11 @@ public class EntailmentServiceTest {
final String str = sw.toString();
LOGGER.debug("string is : '{}'", str);
assertFalse(str.equals(""));
assertTrue(str.contains("dc:rights") && str.contains("dc:title") && str.contains("dc:description"));
assertFalse(str.contains("dcterms:rights") && str.contains("dcterms:title"));
assertTrue(str.contains("http://purl.org/dc/elements/1.1/rights"));
assertTrue(str.contains("http://purl.org/dc/elements/1.1/title"));
assertTrue(str.contains("http://purl.org/dc/elements/1.1/description"));
assertTrue(str.contains("dcterms:rights"));
assertTrue(str.contains("dcterms:title"));
}
@Test
......@@ -100,7 +103,6 @@ public class EntailmentServiceTest {
final String str = sw.toString();
LOGGER.debug("string is : '{}'", str);
assertFalse(str.equals(""));
assertTrue(str.contains("@prefix ex:"));
}
......@@ -112,7 +114,7 @@ public class EntailmentServiceTest {
final Model model = createDefaultModel();
read(model, is, JSONLD);
final String res = model.listSubjects().next().getURI();
assertTrue(res.equals("http://localhost:8080/fcrepo/rest/test"));
final List<String> res = model.listSubjects().mapWith(Resource::getURI).toList();
assertTrue(res.contains("http://localhost:8080/fcrepo/rest/test"));
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment