NIHVIVO-3819 RDFService implementation based on jena Model

This commit is contained in:
stellamit 2012-06-26 21:09:58 +00:00
parent 18a532b42c
commit 9ff98d5708
7 changed files with 250 additions and 144 deletions

View file

@ -1,6 +1,6 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */ /* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.sdb; package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View file

@ -1,17 +1,14 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */ /* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.sdb; package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -32,10 +29,6 @@ import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator; import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.sdb.SDBFactory;
import com.hp.hpl.jena.sdb.Store;
import com.hp.hpl.jena.sdb.StoreDesc;
import com.hp.hpl.jena.sdb.sql.SDBConnection;
import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.shared.Lock;
import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetWrapper; import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetWrapper;
@ -46,117 +39,15 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceImpl; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceImpl;
public class RDFServiceSDB extends RDFServiceImpl implements RDFService { public abstract class RDFServiceJena extends RDFServiceImpl implements RDFService {
private final static Log log = LogFactory.getLog(RDFServiceSDB.class); private final static Log log = LogFactory.getLog(RDFServiceJena.class);
private BasicDataSource bds;
private StoreDesc storeDesc;
public RDFServiceSDB(BasicDataSource dataSource, StoreDesc storeDesc) {
this.bds = dataSource;
this.storeDesc = storeDesc;
}
protected DatasetWrapper getDatasetWrapper() {
try {
SDBConnection conn = new SDBConnection(bds.getConnection());
return new DatasetWrapper(getDataset(conn), conn);
} catch (SQLException sqle) {
log.error(sqle, sqle);
throw new RuntimeException(sqle);
}
}
protected Dataset getDataset(SDBConnection conn) {
Store store = SDBFactory.connectStore(conn, storeDesc);
store.getLoader().setUseThreading(false);
return SDBFactory.connectDataset(store);
}
@Override
public boolean changeSetUpdate(ChangeSet changeSet)
throws RDFServiceException {
if (changeSet.getPreconditionQuery() != null
&& !isPreconditionSatisfied(
changeSet.getPreconditionQuery(),
changeSet.getPreconditionQueryType())) {
return false;
}
SDBConnection conn = null;
try {
conn = new SDBConnection(bds.getConnection());
} catch (SQLException sqle) {
log.error(sqle, sqle);
throw new RDFServiceException(sqle);
}
Dataset dataset = getDataset(conn); protected abstract DatasetWrapper getDatasetWrapper();
boolean transaction = conn.getTransactionHandler().transactionsSupported();
try {
if (transaction) {
conn.getTransactionHandler().begin();
}
for (Object o : changeSet.getPreChangeEvents()) {
this.notifyListenersOfEvent(o);
}
Iterator<ModelChange> csIt = changeSet.getModelChanges().iterator();
while (csIt.hasNext()) {
ModelChange modelChange = csIt.next();
if (!modelChange.getSerializedModel().markSupported()) {
byte[] bytes = IOUtils.toByteArray(modelChange.getSerializedModel());
modelChange.setSerializedModel(new ByteArrayInputStream(bytes));
}
modelChange.getSerializedModel().mark(Integer.MAX_VALUE);
dataset.getLock().enterCriticalSection(Lock.WRITE);
try {
Model model = (modelChange.getGraphURI() == null)
? dataset.getDefaultModel()
: dataset.getNamedModel(modelChange.getGraphURI());
operateOnModel(model, modelChange, dataset);
} finally {
dataset.getLock().leaveCriticalSection();
}
}
if (transaction) {
conn.getTransactionHandler().commit();
}
// notify listeners of triple changes
csIt = changeSet.getModelChanges().iterator();
while (csIt.hasNext()) {
ModelChange modelChange = csIt.next();
modelChange.getSerializedModel().reset();
Model model = ModelFactory.createModelForGraph(
new ListeningGraph(modelChange.getGraphURI(), this));
operateOnModel(model, modelChange, null);
}
for (Object o : changeSet.getPostChangeEvents()) {
this.notifyListenersOfEvent(o);
}
} catch (Exception e) {
log.error(e, e);
if (transaction) {
conn.getTransactionHandler().abort();
}
throw new RDFServiceException(e);
} finally {
conn.close();
}
return true;
}
private void operateOnModel(Model model, ModelChange modelChange, Dataset dataset) { public abstract boolean changeSetUpdate(ChangeSet changeSet) throws RDFServiceException;
protected void operateOnModel(Model model, ModelChange modelChange, Dataset dataset) {
model.enterCriticalSection(Lock.WRITE); model.enterCriticalSection(Lock.WRITE);
try { try {
if (modelChange.getOperation() == ModelChange.Operation.ADD) { if (modelChange.getOperation() == ModelChange.Operation.ADD) {

View file

@ -0,0 +1,99 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model;
import java.io.ByteArrayInputStream;
import java.util.Iterator;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.sparql.core.DatasetImpl;
import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetWrapper;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
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.ListeningGraph;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.RDFServiceJena;
public class RDFServiceModel extends RDFServiceJena implements RDFService {
private final static Log log = LogFactory.getLog(RDFServiceModel.class);
private Model model;
public RDFServiceModel(Model model) {
this.model = model;
}
protected DatasetWrapper getDatasetWrapper() {
DatasetWrapper datasetWrapper = new DatasetWrapper(new DatasetImpl(model));
return datasetWrapper;
}
@Override
public boolean changeSetUpdate(ChangeSet changeSet)
throws RDFServiceException {
if (changeSet.getPreconditionQuery() != null
&& !isPreconditionSatisfied(
changeSet.getPreconditionQuery(),
changeSet.getPreconditionQueryType())) {
return false;
}
Dataset dataset = getDatasetWrapper().getDataset();
try {
for (Object o : changeSet.getPreChangeEvents()) {
this.notifyListenersOfEvent(o);
}
Iterator<ModelChange> csIt = changeSet.getModelChanges().iterator();
while (csIt.hasNext()) {
ModelChange modelChange = csIt.next();
if (!modelChange.getSerializedModel().markSupported()) {
byte[] bytes = IOUtils.toByteArray(modelChange.getSerializedModel());
modelChange.setSerializedModel(new ByteArrayInputStream(bytes));
}
modelChange.getSerializedModel().mark(Integer.MAX_VALUE);
dataset.getLock().enterCriticalSection(Lock.WRITE);
try {
Model model = (modelChange.getGraphURI() == null)
? dataset.getDefaultModel()
: dataset.getNamedModel(modelChange.getGraphURI());
operateOnModel(model, modelChange, dataset);
} finally {
dataset.getLock().leaveCriticalSection();
}
}
// notify listeners of triple changes
csIt = changeSet.getModelChanges().iterator();
while (csIt.hasNext()) {
ModelChange modelChange = csIt.next();
modelChange.getSerializedModel().reset();
Model model = ModelFactory.createModelForGraph(
new ListeningGraph(modelChange.getGraphURI(), this));
operateOnModel(model, modelChange, null);
}
for (Object o : changeSet.getPostChangeEvents()) {
this.notifyListenersOfEvent(o);
}
} catch (Exception e) {
log.error(e, e);
throw new RDFServiceException(e);
}
return true;
}
}

View file

@ -0,0 +1,141 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.sdb;
import java.io.ByteArrayInputStream;
import java.sql.SQLException;
import java.util.Iterator;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.sdb.SDBFactory;
import com.hp.hpl.jena.sdb.Store;
import com.hp.hpl.jena.sdb.StoreDesc;
import com.hp.hpl.jena.sdb.sql.SDBConnection;
import com.hp.hpl.jena.shared.Lock;
import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetWrapper;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
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.ListeningGraph;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.RDFServiceJena;
public class RDFServiceSDB extends RDFServiceJena implements RDFService {
private final static Log log = LogFactory.getLog(RDFServiceSDB.class);
private BasicDataSource bds;
private StoreDesc storeDesc;
public RDFServiceSDB(BasicDataSource dataSource, StoreDesc storeDesc) {
this.bds = dataSource;
this.storeDesc = storeDesc;
}
@Override
protected DatasetWrapper getDatasetWrapper() {
try {
SDBConnection conn = new SDBConnection(bds.getConnection());
return new DatasetWrapper(getDataset(conn), conn);
} catch (SQLException sqle) {
log.error(sqle, sqle);
throw new RuntimeException(sqle);
}
}
@Override
public boolean changeSetUpdate(ChangeSet changeSet)
throws RDFServiceException {
if (changeSet.getPreconditionQuery() != null
&& !isPreconditionSatisfied(
changeSet.getPreconditionQuery(),
changeSet.getPreconditionQueryType())) {
return false;
}
SDBConnection conn = null;
try {
conn = new SDBConnection(bds.getConnection());
} catch (SQLException sqle) {
log.error(sqle, sqle);
throw new RDFServiceException(sqle);
}
Dataset dataset = getDataset(conn);
boolean transaction = conn.getTransactionHandler().transactionsSupported();
try {
if (transaction) {
conn.getTransactionHandler().begin();
}
for (Object o : changeSet.getPreChangeEvents()) {
this.notifyListenersOfEvent(o);
}
Iterator<ModelChange> csIt = changeSet.getModelChanges().iterator();
while (csIt.hasNext()) {
ModelChange modelChange = csIt.next();
if (!modelChange.getSerializedModel().markSupported()) {
byte[] bytes = IOUtils.toByteArray(modelChange.getSerializedModel());
modelChange.setSerializedModel(new ByteArrayInputStream(bytes));
}
modelChange.getSerializedModel().mark(Integer.MAX_VALUE);
dataset.getLock().enterCriticalSection(Lock.WRITE);
try {
Model model = (modelChange.getGraphURI() == null)
? dataset.getDefaultModel()
: dataset.getNamedModel(modelChange.getGraphURI());
operateOnModel(model, modelChange, dataset);
} finally {
dataset.getLock().leaveCriticalSection();
}
}
if (transaction) {
conn.getTransactionHandler().commit();
}
// notify listeners of triple changes
csIt = changeSet.getModelChanges().iterator();
while (csIt.hasNext()) {
ModelChange modelChange = csIt.next();
modelChange.getSerializedModel().reset();
Model model = ModelFactory.createModelForGraph(
new ListeningGraph(modelChange.getGraphURI(), this));
operateOnModel(model, modelChange, null);
}
for (Object o : changeSet.getPostChangeEvents()) {
this.notifyListenersOfEvent(o);
}
} catch (Exception e) {
log.error(e, e);
if (transaction) {
conn.getTransactionHandler().abort();
}
throw new RDFServiceException(e);
} finally {
conn.close();
}
return true;
}
protected Dataset getDataset(SDBConnection conn) {
Store store = SDBFactory.connectStore(conn, storeDesc);
store.getLoader().setUseThreading(false);
return SDBFactory.connectDataset(store);
}
}

View file

@ -1,25 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.rdfservice.impl.sdb;
import org.apache.commons.dbcp.BasicDataSource;
import com.hp.hpl.jena.sdb.StoreDesc;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
public class RDFServiceFactorySDB {
private BasicDataSource bds;
private StoreDesc storeDesc;
public RDFServiceFactorySDB(BasicDataSource dataSource, StoreDesc storeDesc) {
this.bds = dataSource;
this.storeDesc = storeDesc;
}
public RDFService getRDFService() {
return new RDFServiceSDB(bds, storeDesc);
}
}

View file

@ -47,7 +47,7 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.ChangeSetImpl; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.ChangeSetImpl;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceImpl; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceImpl;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.sdb.ListeningGraph; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.ListeningGraph;
/* /*
* API to write, read, and update Vitro's RDF store, with support * API to write, read, and update Vitro's RDF store, with support

View file

@ -24,7 +24,7 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceFactorySingle; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceFactorySingle;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.sdb.RDFServiceSDB; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.sdb.RDFServiceSDB;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.sparql.RDFServiceSparql; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.sparql.RDFServiceSparql;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;