diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.java index 46d884fc9..2fbcbed88 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/RDFService.java @@ -253,6 +253,8 @@ public interface RDFService { public long countTriples(RDFNode subject, RDFNode predicate, RDFNode object) throws RDFServiceException; public Model getTriples(RDFNode subject, RDFNode predicate, RDFNode object, long limit, long offset) throws RDFServiceException; + + public boolean preferPreciseOptionals(); /** * Frees any resources held by this RDFService object diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringRDFService.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringRDFService.java index 944589aea..73bb9913f 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringRDFService.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/LanguageFilteringRDFService.java @@ -470,6 +470,11 @@ public class LanguageFilteringRDFService implements RDFService { return s.getTriples(subject, predicate, object, limit, offset); } + @Override + public boolean preferPreciseOptionals() { + return s.preferPreciseOptionals(); + } + @Override public void close() { s.close(); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/SameAsFilteringRDFServiceFactory.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/SameAsFilteringRDFServiceFactory.java index f40f60585..9e6f4c7b1 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/SameAsFilteringRDFServiceFactory.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/filter/SameAsFilteringRDFServiceFactory.java @@ -306,6 +306,11 @@ public class SameAsFilteringRDFServiceFactory implements RDFServiceFactory { return s.isEquivalentGraph(graphURI, graph); } + @Override + public boolean preferPreciseOptionals() { + return s.preferPreciseOptionals(); + } + @Override public void close() { s.close(); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceFactorySingle.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceFactorySingle.java index e12ab571f..e611bc8fd 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceFactorySingle.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/RDFServiceFactorySingle.java @@ -203,6 +203,11 @@ public class RDFServiceFactorySingle implements RDFServiceFactory { return s.getTriples(subject, predicate, object, limit, offset); } + @Override + public boolean preferPreciseOptionals() { + return s.preferPreciseOptionals(); + } + @Override public void close() { // Don't close s. It's being used by everybody. diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java index 582c4f918..986295a0a 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/RDFServiceJena.java @@ -692,6 +692,10 @@ public abstract class RDFServiceJena extends RDFServiceImpl implements RDFServic } } + @Override + public boolean preferPreciseOptionals() { + return false; + } @Override public void close() { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/sdb/RDFServiceSDB.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/sdb/RDFServiceSDB.java index 3da53123d..e26ef5a6a 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/sdb/RDFServiceSDB.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/jena/sdb/RDFServiceSDB.java @@ -273,6 +273,11 @@ public class RDFServiceSDB extends RDFServiceJena implements RDFService { return super.getTriples(subject, predicate, object, limit, offset); } + @Override + public boolean preferPreciseOptionals() { + return true; + } + @Override public void close() { if (conn != null) { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/logging/LoggingRDFService.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/logging/LoggingRDFService.java index c4c4304e7..861a1384b 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/logging/LoggingRDFService.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/logging/LoggingRDFService.java @@ -193,6 +193,11 @@ public class LoggingRDFService implements RDFService { return innerService.getTriples(subject, predicate, object, limit, offset); } + @Override + public boolean preferPreciseOptionals() { + return innerService.preferPreciseOptionals(); + } + @Override public void close() { innerService.close(); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sparql/RDFServiceSparql.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sparql/RDFServiceSparql.java index 1451be017..db7e22237 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sparql/RDFServiceSparql.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/rdfservice/impl/sparql/RDFServiceSparql.java @@ -909,6 +909,11 @@ public class RDFServiceSparql extends RDFServiceImpl implements RDFService { return graph.isIsomorphicWith(fromTripleStoreModel); } + @Override + public boolean preferPreciseOptionals() { + return false; + } + protected HttpContext getContext(HttpRequestBase request) { UsernamePasswordCredentials credentials = getCredentials(); if (credentials != null) { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/CustomListViewConfigFile.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/CustomListViewConfigFile.java index 3aecc74ca..cf8e0ea4c 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/CustomListViewConfigFile.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/CustomListViewConfigFile.java @@ -20,6 +20,8 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.Document; @@ -56,6 +58,7 @@ public class CustomListViewConfigFile { private static final String TAG_POSTPROCESSOR = "postprocessor"; private static final String TAG_COLLATED = "collated"; private static final String TAG_CRITICAL = "critical-data-required"; + private static final String TAG_PRECISE = "precise-subquery"; // Will not be null. This is mutable, but don't modify it. Clone it and // modify the clone. @@ -198,7 +201,7 @@ public class CustomListViewConfigFile { } } - public String getSelectQuery(boolean collated, boolean editing) { + public String getSelectQuery(boolean collated, boolean editing, boolean usePreciseSubquery) { Element cloned = (Element) selectQueryElement.cloneNode(true); if (!collated) { @@ -207,6 +210,9 @@ public class CustomListViewConfigFile { if (editing) { removeChildElements(cloned, TAG_CRITICAL); } + if (!usePreciseSubquery) { + removeChildElements(cloned, TAG_PRECISE); + } return cloned.getTextContent(); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/DataPropertyListConfig.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/DataPropertyListConfig.java index d7f95c660..3e5e9d5d1 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/DataPropertyListConfig.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/DataPropertyListConfig.java @@ -7,6 +7,7 @@ import java.io.FileReader; import java.io.IOException; import java.util.Set; +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -36,7 +37,7 @@ public class DataPropertyListConfig { private final DataPropertyTemplateModel dptm; private final VitroRequest vreq; private final TemplateLoader templateLoader; - + private boolean isDefaultConfig; private Set constructQueries; private String selectQuery; @@ -45,7 +46,6 @@ public class DataPropertyListConfig { public DataPropertyListConfig(DataPropertyTemplateModel dptm, TemplateLoader templateLoader, VitroRequest vreq, DataProperty dp, boolean editing) throws InvalidConfigurationException { - this.dptm = dptm; this.vreq = vreq; WebappDaoFactory wadf = vreq.getWebappDaoFactory(); @@ -125,7 +125,7 @@ public class DataPropertyListConfig { FileReader reader = new FileReader(configFilePath); CustomListViewConfigFile configFileContents = new CustomListViewConfigFile(reader); - selectQuery = configFileContents.getSelectQuery(false, editing); + selectQuery = configFileContents.getSelectQuery(false, editing, ListConfigUtils.getUsePreciseSubquery(vreq)); templateName = configFileContents.getTemplateName(); constructQueries = configFileContents.getConstructQueries(); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/ListConfigUtils.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/ListConfigUtils.java new file mode 100644 index 000000000..e4ed16e93 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/ListConfigUtils.java @@ -0,0 +1,28 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.web.templatemodels.customlistview; + +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.sdb.RDFServiceSDB; +import org.apache.commons.lang3.StringUtils; + +public final class ListConfigUtils { + private static Boolean usePrecise = null; + + public static final boolean getUsePreciseSubquery(VitroRequest vreq) { + if (usePrecise == null) { + String usePreciseProp = ConfigurationProperties.getBean(vreq).getProperty("listview.usePreciseSubquery"); + if (!StringUtils.isEmpty(usePreciseProp)) { + usePrecise = Boolean.parseBoolean(usePreciseProp); + } else if (vreq != null && vreq.getRDFService() != null) { + usePrecise = vreq.getRDFService().preferPreciseOptionals(); + } else { + usePrecise = false; + } + } + + return usePrecise; + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/PropertyListConfig.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/PropertyListConfig.java index 094be631c..a5889825c 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/PropertyListConfig.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/PropertyListConfig.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.lang.reflect.Constructor; import java.util.Set; +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -40,7 +41,7 @@ public class PropertyListConfig { private final ObjectPropertyTemplateModel optm; private final VitroRequest vreq; private final TemplateLoader templateLoader; - + private boolean isDefaultConfig; private Set constructQueries; private String selectQuery; @@ -140,7 +141,7 @@ public class PropertyListConfig { boolean collated = optm instanceof CollatedObjectPropertyTemplateModel; - selectQuery = configFileContents.getSelectQuery(collated, editing); + selectQuery = configFileContents.getSelectQuery(collated, editing, ListConfigUtils.getUsePreciseSubquery(vreq)); templateName = configFileContents.getTemplateName(); constructQueries = configFileContents.getConstructQueries(); diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/CustomListViewConfigFileTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/CustomListViewConfigFileTest.java index 54c607597..e82e22b07 100644 --- a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/CustomListViewConfigFileTest.java +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/web/templatemodels/customlistview/CustomListViewConfigFileTest.java @@ -236,7 +236,7 @@ public class CustomListViewConfigFileTest extends AbstractTestClass { String selectQuery, String[] constructQueries, String templateName, String postprocessorName) { assertEquals("select query", selectQuery, - configFile.getSelectQuery(collated, editing)); + configFile.getSelectQuery(collated, editing, true)); assertEquals("construct queries", new HashSet(Arrays.asList(constructQueries)), configFile.getConstructQueries());