From 93bd5183e20552630804ea996e7d816a0414e95d Mon Sep 17 00:00:00 2001 From: Brian Lowe Date: Tue, 6 Apr 2021 17:15:50 +0300 Subject: [PATCH] Move event listening to RDFServiceGraph level to avoid adding a new redundant listener each time a model is made for an existing RDFServiceGraph. Resolve https://jira.lyrasis.org/browse/VIVO-1976 --- .../webapp/dao/jena/RDFServiceGraph.java | 32 +++++----- .../webapp/dao/jena/RDFServiceGraphTest.java | 62 +++++++++++++++++++ 2 files changed, 76 insertions(+), 18 deletions(-) create mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraphTest.java diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraph.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraph.java index ab509c82e..f6c3b4dec 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraph.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraph.java @@ -12,10 +12,10 @@ import java.util.function.Supplier; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.apache.jena.graph.Capabilities; import org.apache.jena.graph.Graph; import org.apache.jena.graph.GraphEventManager; +import org.apache.jena.graph.GraphListener; import org.apache.jena.graph.GraphStatisticsHandler; import org.apache.jena.graph.Node; import org.apache.jena.graph.TransactionHandler; @@ -23,7 +23,6 @@ import org.apache.jena.graph.Triple; import org.apache.jena.graph.impl.GraphWithPerform; import org.apache.jena.graph.impl.SimpleEventManager; import org.apache.jena.query.QuerySolution; -import org.apache.jena.rdf.listeners.StatementListener; import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.rdf.model.StmtIterator; @@ -409,7 +408,18 @@ public class RDFServiceGraph implements GraphWithPerform { @Override public GraphEventManager getEventManager() { if (eventManager == null) { - eventManager = new SimpleEventManager(this); + eventManager = new SimpleEventManager() { + @Override + public void notifyEvent(Graph g, Object event) { + ChangeSet changeSet = rdfService.manufactureChangeSet(); + changeSet.addPreChangeEvent(event); + try { + rdfService.changeSetUpdate(changeSet); + } catch (RDFServiceException e) { + throw new RuntimeException(e); + } + } + }; } return eventManager; } @@ -595,21 +605,7 @@ public class RDFServiceGraph implements GraphWithPerform { } public static Model createRDFServiceModel(final RDFServiceGraph g) { - Model m = VitroModelFactory.createModelForGraph(g); - m.register(new StatementListener() { - @Override - public void notifyEvent(Model m, Object event) { - ChangeSet changeSet = g.getRDFService().manufactureChangeSet(); - changeSet.addPreChangeEvent(event); - try { - g.getRDFService().changeSetUpdate(changeSet); - } catch (RDFServiceException e) { - throw new RuntimeException(e); - } - } - - }); - return m; + return VitroModelFactory.createModelForGraph(g); } @Override diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraphTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraphTest.java new file mode 100644 index 000000000..e5c8a65fa --- /dev/null +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/dao/jena/RDFServiceGraphTest.java @@ -0,0 +1,62 @@ +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import static org.junit.Assert.assertEquals; + +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.ModelFactory; +import org.junit.Test; + +import edu.cornell.mannlib.vitro.testing.AbstractTestClass; +import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener; +import edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel; + + +public class RDFServiceGraphTest extends AbstractTestClass { + + @Test + /** + * Test that creating a new model with the same underlying RDFServiceGraph + * does not result in a new listener registered on that graph. No matter + * how many models have been created using a given RDFServiceGraph, an event + * sent to the last-created model should be heard only once by the + * RDFService. + * @throws RDFServiceException + */ + public void testEventListening() throws RDFServiceException { + Model m = ModelFactory.createDefaultModel(); + RDFService rdfService = new RDFServiceModel(m); + EventsCounter counter = new EventsCounter(); + rdfService.registerListener(counter); + RDFServiceGraph g = new RDFServiceGraph(rdfService); + Model model = null; + for (int i = 0; i < 100; i++) { + model = RDFServiceGraph.createRDFServiceModel(g); + } + model.notifyEvent("event"); + assertEquals(1, counter.getCount()); + } + + private class EventsCounter implements ChangeListener { + + private int count = 0; + + public int getCount() { + return count; + } + + @Override + public void notifyModelChange(ModelChange modelChange) { + // TODO Auto-generated method stub + } + + @Override + public void notifyEvent(String graphURI, Object event) { + count++; + } + + } + +}