VIVO-909 add isEquivalentGraph() to the RDFService interface.

Moves the test for isIsomorpic() to within the RDFService implementation,
so we can handle the "broken" cases like Virtuoso and TDB. This way seems
to be cleaner than the TripleStoreQuirks approach that I was fooling around with.
This commit is contained in:
Jim Blake 2015-02-16 14:32:57 -05:00
parent 13334cdc80
commit e2912bd79e
16 changed files with 95 additions and 176 deletions

View file

@ -24,7 +24,4 @@ public interface TripleSource extends Application.Module{
OntModelCache getShortTermOntModels(RDFService shortTermRdfService, OntModelCache getShortTermOntModels(RDFService shortTermRdfService,
OntModelCache longTermOntModelCache); OntModelCache longTermOntModelCache);
/** Ways in which this TripleSource behaves oddly. */
TripleStoreQuirks getQuirks();
} }

View file

@ -1,18 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.modules.tripleSource;
import com.hp.hpl.jena.rdf.model.Model;
/**
* TODO
*/
public interface TripleStoreQuirks {
/**
* Test to see whether the FileGraph must be updated to reflect the current
* state of the file.
*/
boolean hasFileGraphChanged(Model fromFile, Model previous, String graphURI);
}

View file

@ -159,6 +159,18 @@ public interface RDFService {
*/ */
public void serializeGraph(String graphURI, OutputStream outputStream) throws RDFServiceException; public void serializeGraph(String graphURI, OutputStream outputStream) throws RDFServiceException;
/**
* Tests to see whether the supplied serialization is equivalent to the
* named graph, as it exists in the store. Equivalence means that if this
* serialization were written to the store, the resulting graph would be
* isomorphic to the existing named graph.
*
* @param graphURI - the URI of the graph to test against. May not be null.
* @param serializedGraph - the contents to be compared with the existing graph. May not be null.
* @param serializationFormat - May not be null.
*/
public boolean isEquivalentGraph(String graphURI, InputStream serializedGraph, ModelSerializationFormat serializationFormat);
/** /**
* Registers a listener to listen to changes in any graph in * Registers a listener to listen to changes in any graph in
* the RDF store. * the RDF store.

View file

@ -335,6 +335,13 @@ public class LanguageFilteringRDFService implements RDFService {
s.serializeGraph(graphURI, outputStream); s.serializeGraph(graphURI, outputStream);
} }
@Override
public boolean isEquivalentGraph(String graphURI,
InputStream serializedGraph,
ModelSerializationFormat serializationFormat) {
return s.isEquivalentGraph(graphURI, serializedGraph, serializationFormat);
}
@Override @Override
public void registerListener(ChangeListener changeListener) public void registerListener(ChangeListener changeListener)
throws RDFServiceException { throws RDFServiceException {

View file

@ -252,6 +252,13 @@ public class SameAsFilteringRDFServiceFactory implements RDFServiceFactory {
s.serializeGraph(graphURI, outputStream); s.serializeGraph(graphURI, outputStream);
} }
@Override
public boolean isEquivalentGraph(String graphURI,
InputStream serializedGraph,
ModelSerializationFormat serializationFormat) {
return s.isEquivalentGraph(graphURI, serializedGraph, serializationFormat);
}
@Override @Override
public void close() { public void close() {
s.close(); s.close();

View file

@ -125,6 +125,13 @@ public class RDFServiceFactorySingle implements RDFServiceFactory {
s.serializeGraph(graphURI, outputStream); s.serializeGraph(graphURI, outputStream);
} }
@Override
public boolean isEquivalentGraph(String graphURI,
InputStream serializedGraph,
ModelSerializationFormat serializationFormat) {
return s.isEquivalentGraph(graphURI, serializedGraph, serializationFormat);
}
@Override @Override
public void registerListener(ChangeListener changeListener) public void registerListener(ChangeListener changeListener)
throws RDFServiceException { throws RDFServiceException {

View file

@ -39,12 +39,15 @@ import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.sparql.core.Quad; import com.hp.hpl.jena.sparql.core.Quad;
import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetWrapper; import edu.cornell.mannlib.vitro.webapp.dao.jena.DatasetWrapper;
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset;
import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlGraph; import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlGraph;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange; import edu.cornell.mannlib.vitro.webapp.rdfservice.ModelChange;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat;
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;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString;
import edu.cornell.mannlib.vitro.webapp.utils.sparql.ResultSetIterators.ResultSetQuadsIterator; import edu.cornell.mannlib.vitro.webapp.utils.sparql.ResultSetIterators.ResultSetQuadsIterator;
import edu.cornell.mannlib.vitro.webapp.utils.sparql.ResultSetIterators.ResultSetTriplesIterator; import edu.cornell.mannlib.vitro.webapp.utils.sparql.ResultSetIterators.ResultSetTriplesIterator;
@ -553,6 +556,19 @@ public abstract class RDFServiceJena extends RDFServiceImpl implements RDFServic
} }
} }
/**
* The basic version. Parse the model from the file, read the model from the
* tripleStore, and ask whether they are isomorphic.
*/
@Override
public boolean isEquivalentGraph(String graphURI, InputStream serializedGraph,
ModelSerializationFormat serializationFormat) {
Model fileModel = RDFServiceUtils.parseModel(serializedGraph, serializationFormat);
Model tripleStoreModel = new RDFServiceDataset(this).getNamedModel(graphURI);
Model fromTripleStoreModel = ModelFactory.createDefaultModel().add(tripleStoreModel);
return fileModel.isIsomorphicWith(fromTripleStoreModel);
}
@Override @Override
public void close() { public void close() {
// nothing // nothing

View file

@ -83,6 +83,16 @@ public class LoggingRDFService implements RDFService {
} }
} }
@Override
public boolean isEquivalentGraph(String graphURI,
InputStream serializedGraph,
ModelSerializationFormat serializationFormat) {
try (RDFServiceLogger l = new RDFServiceLogger(graphURI)) {
return innerService.isEquivalentGraph(graphURI, serializedGraph,
serializationFormat);
}
}
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Untimed methods // Untimed methods
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------

View file

@ -46,6 +46,7 @@ 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.sparql.core.Quad; import com.hp.hpl.jena.sparql.core.Quad;
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset;
import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlGraph; import edu.cornell.mannlib.vitro.webapp.dao.jena.SparqlGraph;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener; import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeListener;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
@ -54,6 +55,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.RDFServiceUtils;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.ListeningGraph; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.ListeningGraph;
import edu.cornell.mannlib.vitro.webapp.utils.sparql.ResultSetIterators.ResultSetQuadsIterator; import edu.cornell.mannlib.vitro.webapp.utils.sparql.ResultSetIterators.ResultSetQuadsIterator;
import edu.cornell.mannlib.vitro.webapp.utils.sparql.ResultSetIterators.ResultSetTriplesIterator; import edu.cornell.mannlib.vitro.webapp.utils.sparql.ResultSetIterators.ResultSetTriplesIterator;
@ -628,8 +630,6 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService {
Model blankNodeModel = ModelFactory.createDefaultModel(); Model blankNodeModel = ModelFactory.createDefaultModel();
blankNodeModel.add(blankNodeStatements); blankNodeModel.add(blankNodeStatements);
log.debug("update model size " + model.size()); log.debug("update model size " + model.size());
log.debug("blank node model size " + blankNodeModel.size()); log.debug("blank node model size " + blankNodeModel.size());
@ -843,4 +843,17 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService {
} }
} }
/**
* The basic version. Parse the model from the file, read the model from the
* tripleStore, and ask whether they are isomorphic.
*/
@Override
public boolean isEquivalentGraph(String graphURI, InputStream serializedGraph,
ModelSerializationFormat serializationFormat) {
Model fileModel = RDFServiceUtils.parseModel(serializedGraph, serializationFormat);
Model tripleStoreModel = new RDFServiceDataset(this).getNamedModel(graphURI);
Model fromTripleStoreModel = ModelFactory.createDefaultModel().add(tripleStoreModel);
return fileModel.isIsomorphicWith(fromTripleStoreModel);
}
} }

View file

@ -4,9 +4,12 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup;
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONTENT; import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONTENT;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.nio.file.DirectoryStream; import java.nio.file.DirectoryStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@ -37,6 +40,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceDataset;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat;
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
// This ContextListener must run after the JenaDataSourceSetup ContextListener // This ContextListener must run after the JenaDataSourceSetup ContextListener
@ -204,30 +208,26 @@ public class FileGraphSetup implements ServletContextListener {
*/ */
public boolean updateGraphInDB(RDFService rdfService, Model fileModel, String type, Path path) { public boolean updateGraphInDB(RDFService rdfService, Model fileModel, String type, Path path) {
String graphURI = pathToURI(path,type); String graphURI = pathToURI(path,type);
Model dbModel = new RDFServiceDataset(rdfService).getNamedModel(graphURI);
boolean modelChanged = false;
log.debug(String.format(
"%s %s dbModel size is %d, fileModel size is %d", type,
path.getFileName(), dbModel.size(), fileModel.size()));
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
fileModel.write(buffer, "N-TRIPLE");
InputStream inStream = new ByteArrayInputStream(buffer.toByteArray());
if (rdfService.isEquivalentGraph(graphURI, inStream, ModelSerializationFormat.NTRIPLE)) {
return false;
}
// Isomorphism has some quirky issues with TDB, and perhaps also with Virtuoso. Model dbModel = new RDFServiceDataset(rdfService).getNamedModel(graphURI);
boolean isChanged = ApplicationUtils.instance() if (log.isDebugEnabled()) {
.getContentTripleSource().getQuirks() log.debug(String.format(
.hasFileGraphChanged(fileModel, dbModel, graphURI); "%s %s dbModel size is %d, fileModel size is %d", type,
path.getFileName(), dbModel.size(), fileModel.size()));
}
if (dbModel.isEmpty() && !fileModel.isEmpty()) { log.info("Updating " + path + " because graphs are not isomorphic");
dbModel.add(fileModel); log.info("dbModel: " + dbModel.size() + " ; fileModel: " + fileModel.size());
modelChanged = true; dbModel.removeAll();
} else if (isChanged) { dbModel.add(fileModel);
log.info("Updating " + path + " because graphs are not isomorphic"); return true;
log.info("dbModel: " + dbModel.size() + " ; fileModel: " + fileModel.size());
dbModel.removeAll();
dbModel.add(fileModel);
modelChanged = true;
}
return modelChanged;
} }
/* /*

View file

@ -1,27 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.triplesource.impl;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.TripleStoreQuirks;
/**
* The behavior for non-quirky TripleSource implementations.
*/
public class DefaultTripleStoreQuirks implements TripleStoreQuirks {
@Override
public boolean hasFileGraphChanged(Model fromFile, Model previous,
String graphURI) {
/**
* The test for isomorphism involves a large number of ASK queries. It
* appears to be faster to read the previous graph data into memory than
* to run those queries against the RDFService.
*/
return !fromFile.isIsomorphicWith(ModelFactory.createDefaultModel()
.add(previous));
}
}

View file

@ -38,13 +38,11 @@ import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.UnionModelsOntMode
import edu.cornell.mannlib.vitro.webapp.modules.Application; import edu.cornell.mannlib.vitro.webapp.modules.Application;
import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus; import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus;
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource; import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource;
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.TripleStoreQuirks;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; 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.jena.sdb.RDFServiceFactorySDB; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.sdb.RDFServiceFactorySDB;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging.LoggingRDFServiceFactory; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging.LoggingRDFServiceFactory;
import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase; import edu.cornell.mannlib.vitro.webapp.servlet.setup.JenaDataSourceSetupBase;
import edu.cornell.mannlib.vitro.webapp.triplesource.impl.DefaultTripleStoreQuirks;
import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString;
/** /**
@ -79,8 +77,6 @@ public class ContentTripleSourceSDB extends ContentTripleSource {
static final boolean DEFAULT_TESTONBORROW = true; static final boolean DEFAULT_TESTONBORROW = true;
static final boolean DEFAULT_TESTONRETURN = true; static final boolean DEFAULT_TESTONRETURN = true;
private final TripleStoreQuirks quirks = new DefaultTripleStoreQuirks();
private ServletContext ctx; private ServletContext ctx;
private ComboPooledDataSource ds; private ComboPooledDataSource ds;
private RDFServiceFactory rdfServiceFactory; private RDFServiceFactory rdfServiceFactory;
@ -209,11 +205,6 @@ public class ContentTripleSourceSDB extends ContentTripleSource {
return new UnionModelsOntModelsCache(combinedCache, CONTENT_UNIONS); return new UnionModelsOntModelsCache(combinedCache, CONTENT_UNIONS);
} }
@Override
public TripleStoreQuirks getQuirks() {
return quirks;
}
@Override @Override
public String toString() { public String toString() {
return "ContentTripleSourceSDB[" + ToString.hashHex(this) + "]"; return "ContentTripleSourceSDB[" + ToString.hashHex(this) + "]";

View file

@ -13,13 +13,11 @@ import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.OntModelCache;
import edu.cornell.mannlib.vitro.webapp.modules.Application; import edu.cornell.mannlib.vitro.webapp.modules.Application;
import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus; import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus;
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource; import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource;
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.TripleStoreQuirks;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; 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.logging.LoggingRDFServiceFactory; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.logging.LoggingRDFServiceFactory;
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.triplesource.impl.DefaultTripleStoreQuirks;
import edu.cornell.mannlib.vitro.webapp.utils.configuration.Property; import edu.cornell.mannlib.vitro.webapp.utils.configuration.Property;
import edu.cornell.mannlib.vitro.webapp.utils.configuration.Validation; import edu.cornell.mannlib.vitro.webapp.utils.configuration.Validation;
import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString; import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString;
@ -38,8 +36,6 @@ public class ContentTripleSourceSPARQL extends ContentTripleSource {
private String endpointURI; private String endpointURI;
private String updateEndpointURI; // Optional private String updateEndpointURI; // Optional
private final TripleStoreQuirks quirks = new DefaultTripleStoreQuirks();
private RDFService rdfService; private RDFService rdfService;
private RDFServiceFactory rdfServiceFactory; private RDFServiceFactory rdfServiceFactory;
private Dataset dataset; private Dataset dataset;
@ -136,11 +132,6 @@ public class ContentTripleSourceSPARQL extends ContentTripleSource {
return longTermOntModelCache; return longTermOntModelCache;
} }
@Override
public TripleStoreQuirks getQuirks() {
return quirks;
}
@Override @Override
public String toString() { public String toString() {
return "ContentTripleSourceSPARQL[" + ToString.hashHex(this) return "ContentTripleSourceSPARQL[" + ToString.hashHex(this)

View file

@ -18,7 +18,6 @@ import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.OntModelCache;
import edu.cornell.mannlib.vitro.webapp.modules.Application; import edu.cornell.mannlib.vitro.webapp.modules.Application;
import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus; import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus;
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ConfigurationTripleSource; import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ConfigurationTripleSource;
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.TripleStoreQuirks;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; 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;
@ -42,8 +41,6 @@ import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString;
public class ConfigurationTripleSourceTDB extends ConfigurationTripleSource { public class ConfigurationTripleSourceTDB extends ConfigurationTripleSource {
private static final String DIRECTORY_TDB = "tdbModels"; private static final String DIRECTORY_TDB = "tdbModels";
private final TripleStoreQuirks quirks = new TDBTripleStoreQuirks();
private volatile RDFService rdfService; private volatile RDFService rdfService;
private RDFServiceFactory rdfServiceFactory; private RDFServiceFactory rdfServiceFactory;
private RDFService unclosableRdfService; private RDFService unclosableRdfService;
@ -114,11 +111,6 @@ public class ConfigurationTripleSourceTDB extends ConfigurationTripleSource {
return longTermOntModelCache; return longTermOntModelCache;
} }
@Override
public TripleStoreQuirks getQuirks() {
return quirks;
}
@Override @Override
public String toString() { public String toString() {
return "ConfigurationTripleSourceTDB[" + ToString.hashHex(this) + "]"; return "ConfigurationTripleSourceTDB[" + ToString.hashHex(this) + "]";

View file

@ -16,7 +16,6 @@ import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.OntModelCache;
import edu.cornell.mannlib.vitro.webapp.modules.Application; import edu.cornell.mannlib.vitro.webapp.modules.Application;
import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus; import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus;
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource; import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.ContentTripleSource;
import edu.cornell.mannlib.vitro.webapp.modules.tripleSource.TripleStoreQuirks;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; 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;
@ -40,8 +39,6 @@ import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString;
* Memory-map the small content models, and add the standard decorators. * Memory-map the small content models, and add the standard decorators.
*/ */
public class ContentTripleSourceTDB extends ContentTripleSource { public class ContentTripleSourceTDB extends ContentTripleSource {
private final TripleStoreQuirks quirks = new TDBTripleStoreQuirks();
private String tdbPath; private String tdbPath;
private volatile RDFService rdfService; private volatile RDFService rdfService;
@ -127,11 +124,6 @@ public class ContentTripleSourceTDB extends ContentTripleSource {
return longTermOntModelCache; return longTermOntModelCache;
} }
@Override
public TripleStoreQuirks getQuirks() {
return quirks;
}
@Override @Override
public String toString() { public String toString() {
return "ContentTripleSourceTDB[" + ToString.hashHex(this) + "]"; return "ContentTripleSourceTDB[" + ToString.hashHex(this) + "]";

View file

@ -1,71 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.triplesource.impl.tdb;
import static com.hp.hpl.jena.datatypes.xsd.XSDDatatype.XSDinteger;
import static com.hp.hpl.jena.datatypes.xsd.XSDDatatype.XSDnonNegativeInteger;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import edu.cornell.mannlib.vitro.webapp.triplesource.impl.DefaultTripleStoreQuirks;
/**
* TDB has some odd behaviors to deal with.
*/
public class TDBTripleStoreQuirks extends DefaultTripleStoreQuirks {
private static final Log log = LogFactory
.getLog(TDBTripleStoreQuirks.class);
/**
* When the file graph was previously written to the TDB store, TDB mangled
* some of the literal types: any type of XMLSchema#nonNegativeInteger was
* changed to XMLSchema#integer.
*
* We need to mangle our new model in the same way before comparing to the
* previous one.
*/
@Override
public boolean hasFileGraphChanged(Model fromFile, Model previous,
String graphURI) {
try {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
fromFile.write(buffer, "N-TRIPLE");
String fromString = buffer.toString("UTF-8");
String mangleString = fromString.replace(
XSDnonNegativeInteger.getURI(), XSDinteger.getURI());
InputStream mangleStream = new ByteArrayInputStream(
mangleString.getBytes("UTF-8"));
Model mangled = ModelFactory.createDefaultModel();
mangled.read(mangleStream, null, "N-TRIPLE");
return !isIsomorphic(previous, mangled);
} catch (Exception e) {
log.warn("Failed to test for changes in filegraph. "
+ "Change assumed.", e);
return true;
}
}
/**
* If we check isomorphism with a dbModel directly, we issue many ASK
* queries against the underlying RDFService.
*
* It's faster to read the entire model from the RDFService and then issue
* all of those ASKs against a memory-resident model.
*/
private boolean isIsomorphic(Model previous, Model mangled) {
Model previousInMemory = ModelFactory.createDefaultModel()
.add(previous);
return mangled.isIsomorphicWith(previousInMemory);
}
}