VIVO-1016 Avoid crashing on ABox.isEmpty()

1) Don't ask whether the ABox is empty, if you don't need to
2) If you must ask, ask the graph of the base model, to avoid SDB layers
3) change contains() to use SELECT instead of ASK, because SDB implements ASK very poorly.
This commit is contained in:
Jim Blake 2015-04-13 10:25:58 -04:00
parent d8aaecd4fd
commit dc726d2600
7 changed files with 27 additions and 14 deletions

View file

@ -36,7 +36,7 @@ log4j.rootLogger=INFO, AllAppender
# These classes are too chatty to display INFO messages.
log4j.logger.edu.cornell.mannlib.vitro.webapp.startup.StartupStatus=WARN
log4j.logger.edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase=WARN
log4j.logger.org.semanticweb.owlapi.rdf.rdfxml.parser.OWLRDFConsumer=WARN
log4j.logger.org.semanticweb.owlapi.rdf.rdfxml.parser=WARN
# Spring as a whole is too chatty to display INFO messages.
log4j.logger.org.springframework=WARN

View file

@ -145,10 +145,12 @@ public class RDFServiceGraph implements GraphWithPerform {
@Override
public boolean contains(Node subject, Node predicate, Node object) {
if (subject.isBlank() || predicate.isBlank() || object.isBlank()) {
if ((subject != null && subject.isBlank())
|| (predicate != null && predicate.isBlank())
|| (object != null && object.isBlank())) {
return false;
}
StringBuffer containsQuery = new StringBuffer("ASK { \n");
StringBuffer containsQuery = new StringBuffer("SELECT * WHERE { \n");
if (graphURI != null) {
containsQuery.append(" GRAPH <" + graphURI + "> { ");
}
@ -160,9 +162,9 @@ public class RDFServiceGraph implements GraphWithPerform {
if (graphURI != null) {
containsQuery.append(" } \n");
}
containsQuery.append("\n}");
boolean result = execAsk(containsQuery.toString());
return result;
containsQuery.append("} \nLIMIT 1 ");
ResultSet result = execSelect(containsQuery.toString());
return result.hasNext();
}
@Override
@ -319,7 +321,7 @@ public class RDFServiceGraph implements GraphWithPerform {
@Override
public boolean isEmpty() {
return (size() == 0);
return !contains(null, null, null);
}
@Override

View file

@ -170,7 +170,9 @@ public class SparqlGraph implements GraphWithPerform {
@Override
public boolean contains(Node subject, Node predicate, Node object) {
if (subject.isBlank() || predicate.isBlank() || object.isBlank()) {
if ((subject != null && subject.isBlank())
|| (predicate != null && predicate.isBlank())
|| (object != null && object.isBlank())) {
return false;
}
StringBuffer containsQuery = new StringBuffer("ASK { \n");
@ -357,7 +359,7 @@ public class SparqlGraph implements GraphWithPerform {
@Override
public boolean isEmpty() {
return (size() == 0);
return !contains(null, null, null);
}
@Override

View file

@ -113,6 +113,8 @@ public class FileServingServlet extends VitroHttpServlet {
while (-1 != (howMany = in.read(buffer))) {
out.write(buffer, 0, howMany);
}
} catch (IOException e) {
log.warn("Failed to serve the file", e);
} finally {
try {
in.close();

View file

@ -163,7 +163,7 @@ public class ListeningGraph implements GraphWithPerform {
@Override
public boolean isEmpty() {
return (size() == 0);
return !contains(null, null, null);
}
@Override

View file

@ -32,6 +32,11 @@ import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
/**
* Sets up the content models, OntModelSelectors and webapp DAO factories.
*
* Why the firstTimeStartup flag? Because you can't ask a large SDB model
* whether it is empty. SDB translates this into a call to size(), which
* in turn becomes find(null, null, null) and a count, and this gives an
* OutOfMemoryError because it tries to read the entire model into memory.
*/
public class ContentModelSetup extends JenaDataSourceSetupBase
implements javax.servlet.ServletContextListener {
@ -50,22 +55,24 @@ public class ContentModelSetup extends JenaDataSourceSetupBase
private void setUpJenaDataSource(ServletContext ctx) {
ContextModelAccess models = ModelAccess.on(ctx);
boolean firstTimeStartup = false;
Model applicationMetadataModel = models.getOntModel(APPLICATION_METADATA);
if (applicationMetadataModel.size()== 0) {
if (applicationMetadataModel.isEmpty()) {
firstTimeStartup = true;
initializeApplicationMetadata(ctx, applicationMetadataModel);
} else {
checkForNamespaceMismatch( applicationMetadataModel, ctx );
}
OntModel baseABoxModel = models.getOntModel(ABOX_ASSERTIONS);
if (baseABoxModel.size() == 0) {
if (firstTimeStartup) {
RDFFilesLoader.loadFirstTimeFiles("abox", baseABoxModel, true);
}
RDFFilesLoader.loadEveryTimeFiles("abox", baseABoxModel);
OntModel baseTBoxModel = models.getOntModel(TBOX_ASSERTIONS);
if (baseTBoxModel.size() == 0) {
if (firstTimeStartup) {
RDFFilesLoader.loadFirstTimeFiles("tbox", baseTBoxModel, true);
}
RDFFilesLoader.loadEveryTimeFiles("tbox", baseTBoxModel);

View file

@ -106,7 +106,7 @@ public class ContentTripleSourceTDB extends ContentTripleSource {
}
private void checkForFirstTimeStartup() {
if (this.dataset.getNamedModel(ModelNames.TBOX_ASSERTIONS).size() == 0) {
if (this.dataset.getNamedModel(ModelNames.TBOX_ASSERTIONS).getGraph().isEmpty()) {
JenaDataSourceSetupBase.thisIsFirstStartup();
}
}