VIVO-907 Create the TripleStoreQuirks interface
Use it to handle the odd behavior that a particular triple store might have. In this case, the odd behavior is that TDB mangles XMLSchema#nonNegativeInteger to XMLSchema#integer in literal types.
This commit is contained in:
parent
546e27c15a
commit
61eb57ca5d
9 changed files with 137 additions and 3 deletions
|
@ -24,4 +24,7 @@ public interface TripleSource extends Application.Module{
|
|||
|
||||
OntModelCache getShortTermOntModels(RDFService shortTermRdfService,
|
||||
OntModelCache longTermOntModelCache);
|
||||
|
||||
/** Ways in which this TripleSource behaves oddly. */
|
||||
TripleStoreQuirks getQuirks();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
/* $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);
|
||||
|
||||
}
|
|
@ -218,12 +218,15 @@ public class FileGraphSetup implements ServletContextListener {
|
|||
path.getFileName(), dbModel.size(), fileModel.size()));
|
||||
|
||||
|
||||
boolean isIsomorphic = dbModel.isIsomorphicWith(fileModel);
|
||||
// Isomorphism has some quirky issues with TDB, and perhaps also with Virtuoso.
|
||||
boolean isChanged = ApplicationUtils.instance()
|
||||
.getContentTripleSource().getQuirks()
|
||||
.hasFileGraphChanged(fileModel, dbModel, graphURI);
|
||||
|
||||
if (dbModel.isEmpty() && !fileModel.isEmpty()) {
|
||||
dbModel.add(fileModel);
|
||||
modelChanged = true;
|
||||
} else if (!isIsomorphic) {
|
||||
} else if (isChanged) {
|
||||
log.info("Updating " + path + " because graphs are not isomorphic");
|
||||
log.info("dbModel: " + dbModel.size() + " ; fileModel: " + fileModel.size());
|
||||
dbModel.removeAll();
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/* $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 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) {
|
||||
return !fromFile.isIsomorphicWith(previous);
|
||||
}
|
||||
|
||||
}
|
|
@ -38,11 +38,13 @@ import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.UnionModelsOntMode
|
|||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||
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.TripleStoreQuirks;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
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.logging.LoggingRDFServiceFactory;
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -77,6 +79,8 @@ public class ContentTripleSourceSDB extends ContentTripleSource {
|
|||
static final boolean DEFAULT_TESTONBORROW = true;
|
||||
static final boolean DEFAULT_TESTONRETURN = true;
|
||||
|
||||
private final TripleStoreQuirks quirks = new DefaultTripleStoreQuirks();
|
||||
|
||||
private ServletContext ctx;
|
||||
private ComboPooledDataSource ds;
|
||||
private RDFServiceFactory rdfServiceFactory;
|
||||
|
@ -205,6 +209,11 @@ public class ContentTripleSourceSDB extends ContentTripleSource {
|
|||
return new UnionModelsOntModelsCache(combinedCache, CONTENT_UNIONS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TripleStoreQuirks getQuirks() {
|
||||
return quirks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ContentTripleSourceSDB[" + ToString.hashHex(this) + "]";
|
||||
|
|
|
@ -13,11 +13,13 @@ import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.OntModelCache;
|
|||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||
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.TripleStoreQuirks;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
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.logging.LoggingRDFServiceFactory;
|
||||
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.Validation;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString;
|
||||
|
@ -36,6 +38,8 @@ public class ContentTripleSourceSPARQL extends ContentTripleSource {
|
|||
private String endpointURI;
|
||||
private String updateEndpointURI; // Optional
|
||||
|
||||
private final TripleStoreQuirks quirks = new DefaultTripleStoreQuirks();
|
||||
|
||||
private RDFService rdfService;
|
||||
private RDFServiceFactory rdfServiceFactory;
|
||||
private Dataset dataset;
|
||||
|
@ -132,6 +136,11 @@ public class ContentTripleSourceSPARQL extends ContentTripleSource {
|
|||
return longTermOntModelCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TripleStoreQuirks getQuirks() {
|
||||
return quirks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ContentTripleSourceSPARQL[" + ToString.hashHex(this)
|
||||
|
|
|
@ -18,6 +18,7 @@ import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.OntModelCache;
|
|||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||
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.TripleStoreQuirks;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceFactorySingle;
|
||||
|
@ -39,9 +40,10 @@ import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString;
|
|||
* Memory-map all of the configuration models, and add the standard decorators.
|
||||
*/
|
||||
public class ConfigurationTripleSourceTDB extends ConfigurationTripleSource {
|
||||
|
||||
private static final String DIRECTORY_TDB = "tdbModels";
|
||||
|
||||
private final TripleStoreQuirks quirks = new TDBTripleStoreQuirks();
|
||||
|
||||
private volatile RDFService rdfService;
|
||||
private RDFServiceFactory rdfServiceFactory;
|
||||
private RDFService unclosableRdfService;
|
||||
|
@ -112,6 +114,11 @@ public class ConfigurationTripleSourceTDB extends ConfigurationTripleSource {
|
|||
return longTermOntModelCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TripleStoreQuirks getQuirks() {
|
||||
return quirks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConfigurationTripleSourceTDB[" + ToString.hashHex(this) + "]";
|
||||
|
|
|
@ -16,6 +16,7 @@ import edu.cornell.mannlib.vitro.webapp.modelaccess.ontmodels.OntModelCache;
|
|||
import edu.cornell.mannlib.vitro.webapp.modules.Application;
|
||||
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.TripleStoreQuirks;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceFactorySingle;
|
||||
|
@ -39,6 +40,8 @@ import edu.cornell.mannlib.vitro.webapp.utils.logging.ToString;
|
|||
* Memory-map the small content models, and add the standard decorators.
|
||||
*/
|
||||
public class ContentTripleSourceTDB extends ContentTripleSource {
|
||||
private final TripleStoreQuirks quirks = new TDBTripleStoreQuirks();
|
||||
|
||||
private String tdbPath;
|
||||
|
||||
private volatile RDFService rdfService;
|
||||
|
@ -124,6 +127,11 @@ public class ContentTripleSourceTDB extends ContentTripleSource {
|
|||
return longTermOntModelCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TripleStoreQuirks getQuirks() {
|
||||
return quirks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ContentTripleSourceTDB[" + ToString.hashHex(this) + "]";
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/* $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 !mangled.isIsomorphicWith(previous);
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to test for changes in filegraph. "
|
||||
+ "Change assumed.", e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue