From a5a7e640d20a8f281e9cfc6f2fbbe9eeed3a99d8 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Tue, 6 Jun 2023 14:07:19 +0200 Subject: [PATCH] Fix for VIVO-3871 (#393) * Fallback to default graph in bulk ontology model update * test added --------- Co-authored-by: Georgy Litvinov --- .../rdfservice/adapters/BulkGraphMem.java | 2 +- .../rdfservice/adapters/BulkOntModelImpl.java | 54 +++++++++--------- .../rdfservice/adapters/GraphUtils.java | 5 +- .../adapters/VitroModelFactoryTest.java | 56 ++++++++++++++++++- .../adapters/vitro_model_factory_test_data.n3 | 5 ++ 5 files changed, 88 insertions(+), 34 deletions(-) create mode 100644 api/src/test/resources/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/vitro_model_factory_test_data.n3 diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/BulkGraphMem.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/BulkGraphMem.java index ef13daa73..707b90a38 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/BulkGraphMem.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/BulkGraphMem.java @@ -10,7 +10,7 @@ public class BulkGraphMem extends GraphMem { performAdd(t); } - public final void deleteWithoutNotify(Triple t) { + public void deleteWithoutNotify(Triple t) { checkOpen(); performDelete(t); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/BulkOntModelImpl.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/BulkOntModelImpl.java index 3d925a4b0..02f57e5df 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/BulkOntModelImpl.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/BulkOntModelImpl.java @@ -7,33 +7,33 @@ import org.apache.jena.rdf.model.Model; public class BulkOntModelImpl extends OntModelImpl { - public BulkOntModelImpl(OntModelSpec spec) { - super(spec); - } - - public BulkOntModelImpl(OntModelSpec owlMem, Model bareModel) { - super(owlMem, bareModel); - } + public BulkOntModelImpl(OntModelSpec spec) { + super(spec); + } - @Override - public Model remove(Model m) { - Graph unwrappedGraph = GraphUtils.unwrapUnionGraphs(graph); - if (unwrappedGraph instanceof BulkGraphMem) { - GraphUtils.deleteFrom((BulkGraphMem) unwrappedGraph, m.getGraph()); - } else { - super.remove(m); - } - return this; - } + public BulkOntModelImpl(OntModelSpec owlMem, Model bareModel) { + super(owlMem, bareModel); + } - @Override - public Model add(Model m) { - Graph unwrappedGraph = GraphUtils.unwrapUnionGraphs(graph); - if (unwrappedGraph instanceof BulkGraphMem) { - GraphUtils.addInto((BulkGraphMem) unwrappedGraph, m.getGraph()); - } else { - super.add(m); - } - return this; - } + @Override + public Model remove(Model m) { + Graph unwrappedGraph = GraphUtils.unwrapUnionGraphs(graph); + if (unwrappedGraph instanceof BulkGraphMem) { + GraphUtils.deleteFrom((BulkGraphMem) unwrappedGraph, m.getGraph()); + } else { + super.remove(m); + } + return this; + } + + @Override + public Model add(Model m) { + Graph unwrappedGraph = GraphUtils.unwrapUnionGraphs(graph); + if (unwrappedGraph instanceof BulkGraphMem) { + GraphUtils.addInto((BulkGraphMem) unwrappedGraph, m.getGraph()); + } else { + super.add(m); + } + return this; + } } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/GraphUtils.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/GraphUtils.java index 978641211..cc04c3b46 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/GraphUtils.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/GraphUtils.java @@ -25,10 +25,7 @@ final public class GraphUtils { public static Graph unwrapUnionGraphs(Graph graph) { if (graph != null && graph instanceof MultiUnion) { - List subGraphs = ((MultiUnion) graph).getSubGraphs(); - if (subGraphs == null || subGraphs.isEmpty()) { - return ((MultiUnion) graph).getBaseGraph(); - } + return unwrapUnionGraphs(((MultiUnion)graph).getBaseGraph()); } return graph; } diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/VitroModelFactoryTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/VitroModelFactoryTest.java index 4724bb361..c4a5aea0f 100644 --- a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/VitroModelFactoryTest.java +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/VitroModelFactoryTest.java @@ -13,10 +13,11 @@ import java.util.Arrays; import java.util.List; import org.junit.Test; - +import org.apache.jena.graph.Triple; import org.apache.jena.graph.impl.GraphWithPerform; import org.apache.jena.mem.GraphMem; import org.apache.jena.ontology.OntModel; +import org.apache.jena.ontology.impl.OntModelImpl; import org.apache.jena.rdf.listeners.StatementListener; import org.apache.jena.rdf.model.Literal; import org.apache.jena.rdf.model.Model; @@ -27,6 +28,8 @@ 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.rdf.model.Statement; +import org.apache.jena.rdf.model.impl.ModelCom; +import org.apache.jena.shared.Lock; import edu.cornell.mannlib.vitro.testing.AbstractTestClass; import edu.cornell.mannlib.vitro.testing.RecordingProxy; @@ -65,6 +68,9 @@ import edu.cornell.mannlib.vitro.testing.RecordingProxy.MethodCallRecorder; * presumably the bulk updaters will be removed completely. */ public class VitroModelFactoryTest extends AbstractTestClass { + + private String testData = "src/test/resources/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/vitro_model_factory_test_data.n3"; + private static final Statement SINGLE_STATEMENT = stmt( resource("http://subject"), property("http://add"), literal("object")); @@ -463,7 +469,53 @@ public class VitroModelFactoryTest extends AbstractTestClass { .test(); } - // ---------------------------------------------------------------------- + @Test + public void testCreateNewBulkOntModel() { + TestBulkGraphMem spyGraph = new TestBulkGraphMem(); + Model baseModel = new ModelCom(spyGraph); + baseModel = wrap(wrap(wrap(baseModel))); + OntModel ontModel = VitroModelFactory.createOntologyModel(baseModel); + Model inputModel = ModelFactory.createDefaultModel(); + try { + inputModel.enterCriticalSection(Lock.WRITE); + inputModel.read(testData); + } finally { + inputModel.leaveCriticalSection(); + } + assertEquals(0, spyGraph.countAddWithoutNotify); + assertEquals(0, spyGraph.countDeleteWithoutNotify); + ontModel.add(inputModel); + assertEquals(5, spyGraph.countAddWithoutNotify); + assertEquals(0, spyGraph.countDeleteWithoutNotify); + + ontModel.remove(inputModel); + assertEquals(5, spyGraph.countAddWithoutNotify); + assertEquals(5, spyGraph.countDeleteWithoutNotify); + } + + private OntModelImpl wrap(Model baseModel) { + return new OntModelImpl(OWL_MEM, baseModel); + } + + private static class TestBulkGraphMem extends BulkGraphMem { + int countDeleteWithoutNotify = 0; + int countAddWithoutNotify = 0; + + @Override + public void addWithoutNotify(Triple t) { + checkOpen(); + performAdd(t); + countAddWithoutNotify++; + } + @Override + public final void deleteWithoutNotify(Triple t) { + checkOpen(); + performDelete(t); + countDeleteWithoutNotify++; + } + } + + // ---------------------------------------------------------------------- // OntModel of Union of Models // // This shouldn't hold any surprises, should it? diff --git a/api/src/test/resources/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/vitro_model_factory_test_data.n3 b/api/src/test/resources/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/vitro_model_factory_test_data.n3 new file mode 100644 index 000000000..383dcc42f --- /dev/null +++ b/api/src/test/resources/edu/cornell/mannlib/vitro/webapp/rdfservice/adapters/vitro_model_factory_test_data.n3 @@ -0,0 +1,5 @@ + . + . + . + . + .