rewritten list view queries with UNIONs plus various and sundry other bugfixes and improvements; also probably new bugs
This commit is contained in:
parent
881c3ca4fa
commit
b5777a60ad
14 changed files with 238 additions and 61 deletions
|
@ -15,6 +15,7 @@ import org.openrdf.model.URI;
|
|||
import org.openrdf.model.impl.URIImpl;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Portal;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||
|
@ -259,7 +260,7 @@ public class UrlBuilder {
|
|||
}
|
||||
|
||||
public static String getIndividualProfileUrl(String individualUri, WebappDaoFactory wadf) {
|
||||
Individual individual = wadf.getIndividualDao().getIndividualByURI(individualUri);
|
||||
Individual individual = new IndividualImpl(individualUri);
|
||||
return getIndividualProfileUrl(individual, individualUri, wadf);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.IndividualImpl;
|
|||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.IndividualSDB.IndividualNotFoundException;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB.SDBDatasetMode;
|
||||
|
||||
public class IndividualDaoSDB extends IndividualDaoJena {
|
||||
|
@ -66,7 +67,12 @@ public class IndividualDaoSDB extends IndividualDaoJena {
|
|||
}
|
||||
|
||||
protected Individual makeIndividual(String individualURI) {
|
||||
return new IndividualSDB(individualURI, this.dwf, datasetMode, getWebappDaoFactory());
|
||||
try {
|
||||
return new IndividualSDB(individualURI, this.dwf, datasetMode, getWebappDaoFactory());
|
||||
} catch (IndividualNotFoundException e) {
|
||||
// If the individual does not exist, return null.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Log log = LogFactory.getLog(IndividualDaoSDB.class.getName());
|
||||
|
|
|
@ -137,21 +137,21 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
|||
"CONSTRUCT " +
|
||||
"{ <"+individualURI+"> <" + RDFS.label.getURI() +
|
||||
"> ?ooo. \n" +
|
||||
"<"+individualURI+"> a ?type . \n" +
|
||||
// "<"+individualURI+"> a ?type . \n" +
|
||||
"<"+individualURI+"> <" + VitroVocabulary.MONIKER +
|
||||
"> ?moniker \n" +
|
||||
"} WHERE {" +
|
||||
"{ GRAPH ?g { \n" +
|
||||
"} WHERE { GRAPH <urn:x-arq:UnionGraph> {" +
|
||||
"{ \n" +
|
||||
"{ <"+individualURI+"> <" + RDFS.label.getURI() +
|
||||
"> ?ooo } \n" +
|
||||
"UNION { GRAPH ?h { <" +
|
||||
"UNION { <" +
|
||||
individualURI+"> <" + VitroVocabulary.MONIKER +
|
||||
"> ?moniker } } \n" +
|
||||
"} } \n" +
|
||||
"UNION { GRAPH ?i { <"
|
||||
+ individualURI + "> a ?type } } \n" +
|
||||
WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
||||
"}";
|
||||
"> ?moniker } \n" +
|
||||
"} \n" +
|
||||
// "UNION { <"
|
||||
// + individualURI + "> a ?type } \n" +
|
||||
// WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
||||
"} }";
|
||||
model = QueryExecutionFactory.create(
|
||||
QueryFactory.create(getStatements), dataset)
|
||||
.execConstruct();
|
||||
|
@ -163,6 +163,10 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
|||
OntModel ontModel = ModelFactory.createOntologyModel(
|
||||
OntModelSpec.OWL_MEM, model);
|
||||
|
||||
if (model.isEmpty()) {
|
||||
throw new IndividualNotFoundException();
|
||||
}
|
||||
|
||||
this.ind = ontModel.createOntResource(individualURI);
|
||||
}
|
||||
setUpURIParts(ind);
|
||||
|
@ -182,6 +186,8 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
|||
!SKIP_INITIALIZATION);
|
||||
}
|
||||
|
||||
public class IndividualNotFoundException extends RuntimeException {}
|
||||
|
||||
private void setUpURIParts(OntResource ind) {
|
||||
if (ind != null) {
|
||||
if (ind.isAnon()) {
|
||||
|
@ -304,8 +310,8 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
|||
int portalid = FlagMathUtils.numeric2Portalid(numericPortal);
|
||||
String portalTypeUri = VitroVocabulary.vitroURI +
|
||||
"Flag1Value" + portalid + "Thing";
|
||||
String Ask = "ASK { GRAPH ?g { <" + this.individualURI +
|
||||
"> <" +RDF.type+ "> <" + portalTypeUri +">} }";
|
||||
String Ask = "ASK { <" + this.individualURI +
|
||||
"> <" +RDF.type+ "> <" + portalTypeUri +">} ";
|
||||
if(!QueryExecutionFactory.create(
|
||||
QueryFactory.create(Ask), dataset).execAsk()) {
|
||||
return false;
|
||||
|
@ -334,8 +340,8 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
|||
getObjects =
|
||||
"CONSTRUCT{<" + this.individualURI + "> <" +
|
||||
RDF.type + "> ?object}" +
|
||||
"WHERE{ GRAPH ?g { <" + this.individualURI + "> <" +
|
||||
RDF.type + "> ?object} }";
|
||||
"WHERE{ <" + this.individualURI + "> <" +
|
||||
RDF.type + "> ?object }";
|
||||
tempModel = QueryExecutionFactory.create(
|
||||
QueryFactory.create(
|
||||
getObjects), dataset).execConstruct();
|
||||
|
@ -394,8 +400,8 @@ public class IndividualSDB extends IndividualImpl implements Individual {
|
|||
getObjects =
|
||||
"CONSTRUCT{<" + this.individualURI + "> <" +
|
||||
RDF.type + "> ?object}" +
|
||||
"WHERE{ GRAPH ?g { <" + this.individualURI + "> <" +
|
||||
RDF.type + "> ?object} }";
|
||||
"WHERE{ <" + this.individualURI + "> <" +
|
||||
RDF.type + "> ?object }";
|
||||
tempModel = QueryExecutionFactory.create(
|
||||
QueryFactory.create(
|
||||
getObjects), dataset).execConstruct();
|
||||
|
|
|
@ -50,19 +50,19 @@ public class ObjectPropertyStatementDaoSDB extends
|
|||
return entity;
|
||||
else {
|
||||
Map<String, ObjectProperty> uriToObjectProperty = new HashMap<String,ObjectProperty>();
|
||||
String[] graphVars = { "?g", "?h", "?i", "?j" };
|
||||
//String[] graphVars = { "?g", "?h", "?i", "?j" };
|
||||
String query = "CONSTRUCT { \n" +
|
||||
" <" + entity.getURI() + "> ?p ?o . \n" +
|
||||
" ?o a ?oType . \n" +
|
||||
// " ?o a ?oType . \n" +
|
||||
" ?o <" + RDFS.label.getURI() + "> ?oLabel . \n" +
|
||||
" ?o <" + VitroVocabulary.MONIKER + "> ?oMoniker \n" +
|
||||
"} WHERE { GRAPH ?g { \n" +
|
||||
"} WHERE { GRAPH <urn:x-arq:UnionGraph> { \n" +
|
||||
" <" + entity.getURI() + "> ?p ?o \n" +
|
||||
" OPTIONAL { GRAPH ?h { ?o a ?oType } } \n" +
|
||||
" OPTIONAL { GRAPH ?i { ?o <" + RDFS.label.getURI() + "> ?oLabel } } \n" +
|
||||
" OPTIONAL { GRAPH ?j { ?o <" + VitroVocabulary.MONIKER + "> ?oMoniker } } \n" +
|
||||
//" OPTIONAL { GRAPH ?h { ?o a ?oType } } \n" +
|
||||
// " OPTIONAL { { ?o <" + RDFS.label.getURI() + "> ?oLabel } } \n" +
|
||||
// " OPTIONAL { { ?o <" + VitroVocabulary.MONIKER + "> ?oMoniker } } \n" +
|
||||
"} \n" +
|
||||
WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
||||
//WebappDaoFactorySDB.getFilterBlock(graphVars, datasetMode) +
|
||||
"}";
|
||||
long startTime = System.currentTimeMillis();
|
||||
Model m = null;
|
||||
|
|
|
@ -15,7 +15,9 @@ import org.apache.commons.logging.LogFactory;
|
|||
import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
|
||||
import com.hp.hpl.jena.ontology.Individual;
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.ontology.OntModelSpec;
|
||||
import com.hp.hpl.jena.rdf.model.Literal;
|
||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||
import com.hp.hpl.jena.rdf.model.Resource;
|
||||
import com.hp.hpl.jena.rdf.model.Statement;
|
||||
import com.hp.hpl.jena.shared.Lock;
|
||||
|
@ -129,26 +131,44 @@ public class PropertyGroupDaoJena extends JenaBaseDao implements PropertyGroupDa
|
|||
groupInd.setURI(group.getURI());
|
||||
|
||||
String groupURI = null;
|
||||
try {
|
||||
groupURI = (new WebappDaoFactoryJena(getOntModelSelector().getApplicationMetadataModel())).getIndividualDao().insertNewIndividual(groupInd);
|
||||
|
||||
OntModel unionForURIGeneration = ModelFactory.createOntologyModel(
|
||||
OntModelSpec.OWL_MEM, ModelFactory.createUnion(
|
||||
getOntModelSelector().getApplicationMetadataModel(),
|
||||
getOntModelSelector().getFullModel()));
|
||||
|
||||
try {
|
||||
groupURI = (new WebappDaoFactoryJena(unionForURIGeneration)).
|
||||
getIndividualDao().insertNewIndividual(groupInd);
|
||||
} catch (InsertException ie) {
|
||||
throw new RuntimeException(InsertException.class.getName() + "Unable to insert property group "+groupURI, ie);
|
||||
throw new RuntimeException(InsertException.class.getName() +
|
||||
"Unable to insert property group " + groupURI, ie);
|
||||
}
|
||||
|
||||
if (groupURI != null) {
|
||||
getOntModel().enterCriticalSection(Lock.WRITE);
|
||||
try {
|
||||
com.hp.hpl.jena.ontology.Individual groupJenaInd = getOntModel().getIndividual(groupURI);
|
||||
com.hp.hpl.jena.ontology.Individual groupJenaInd =
|
||||
getOntModel().getIndividual(groupURI);
|
||||
try {
|
||||
groupJenaInd.addProperty(DISPLAY_RANK, Integer.toString(group.getDisplayRank()), XSDDatatype.XSDint);
|
||||
groupJenaInd.addProperty(DISPLAY_RANK, Integer.toString(
|
||||
group.getDisplayRank()), XSDDatatype.XSDint);
|
||||
} catch (Exception e) {
|
||||
log.error("error setting displayRank for "+groupInd.getURI());
|
||||
log.error(
|
||||
"error setting displayRank for "
|
||||
+ groupInd.getURI());
|
||||
}
|
||||
if (group.getPublicDescription() != null && group.getPublicDescription().length()>0) {
|
||||
if (group.getPublicDescription() != null
|
||||
&& group.getPublicDescription().length()>0) {
|
||||
try {
|
||||
groupJenaInd.addProperty(PUBLIC_DESCRIPTION_ANNOT, group.getPublicDescription(), XSDDatatype.XSDstring);
|
||||
groupJenaInd.addProperty(
|
||||
PUBLIC_DESCRIPTION_ANNOT,
|
||||
group.getPublicDescription(),
|
||||
XSDDatatype.XSDstring);
|
||||
} catch (Exception ex) {
|
||||
log.error("error setting public description for "+groupInd.getURI());
|
||||
log.error(
|
||||
"error setting public description for "
|
||||
+ groupInd.getURI());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
|
|
@ -216,8 +216,15 @@ public class VClassGroupDaoJena extends JenaBaseDao implements VClassGroupDao {
|
|||
groupInd.setVClassURI(CLASSGROUP.getURI());
|
||||
|
||||
String groupURI = null;
|
||||
|
||||
OntModel unionForURIGeneration = ModelFactory.createOntologyModel(
|
||||
OntModelSpec.OWL_MEM, ModelFactory.createUnion(
|
||||
getOntModelSelector().getApplicationMetadataModel(),
|
||||
getOntModelSelector().getFullModel()));
|
||||
|
||||
try {
|
||||
groupURI = (new WebappDaoFactoryJena(ontModel)).getIndividualDao().insertNewIndividual(groupInd);
|
||||
groupURI = (new WebappDaoFactoryJena(unionForURIGeneration)).
|
||||
getIndividualDao().insertNewIndividual(groupInd);
|
||||
} catch (InsertException ie) {
|
||||
throw new RuntimeException(InsertException.class.getName() + "Unable to insert class group "+groupURI, ie);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.hp.hpl.jena.iri.IRIFactory;
|
|||
import com.hp.hpl.jena.iri.Violation;
|
||||
import com.hp.hpl.jena.ontology.OntClass;
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.ontology.OntModelSpec;
|
||||
import com.hp.hpl.jena.ontology.OntResource;
|
||||
import com.hp.hpl.jena.query.DataSource;
|
||||
import com.hp.hpl.jena.query.Dataset;
|
||||
|
@ -175,22 +176,38 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
|
|||
if (languageUniversalsModel.size()>0) {
|
||||
this.ontModelSelector.getTBoxModel().addSubModel(languageUniversalsModel);
|
||||
}
|
||||
DataSource dataset = DatasetFactory.create();
|
||||
|
||||
dataset.addNamedModel(JenaDataSourceSetupBase.JENA_DB_MODEL,
|
||||
(baseOntModelSelector != null)
|
||||
? baseOntModelSelector.getFullModel()
|
||||
: ontModelSelector.getFullModel());
|
||||
if (inferenceOntModelSelector != null) {
|
||||
dataset.addNamedModel(JenaDataSourceSetupBase.JENA_INF_MODEL,
|
||||
inferenceOntModelSelector.getFullModel());
|
||||
}
|
||||
Model assertions = (baseOntModelSelector != null)
|
||||
? baseOntModelSelector.getFullModel()
|
||||
: ontModelSelector.getFullModel();
|
||||
Model inferences = (inferenceOntModelSelector != null)
|
||||
? inferenceOntModelSelector.getFullModel()
|
||||
: null;
|
||||
|
||||
Dataset dataset = makeInMemoryDataset(assertions, inferences);
|
||||
this.dwf = new StaticDatasetFactory(dataset);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static Dataset makeInMemoryDataset(Model assertions, Model inferences) {
|
||||
DataSource dataset = DatasetFactory.create();
|
||||
|
||||
OntModel union = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
||||
|
||||
if (assertions != null) {
|
||||
dataset.addNamedModel(JenaDataSourceSetupBase.JENA_DB_MODEL, assertions);
|
||||
union.addSubModel(assertions);
|
||||
}
|
||||
if (inferences != null) {
|
||||
dataset.addNamedModel(JenaDataSourceSetupBase.JENA_INF_MODEL,
|
||||
inferences);
|
||||
union.addSubModel(inferences);
|
||||
}
|
||||
dataset.setDefaultModel(union);
|
||||
dataset.addNamedModel("urn:x-arq:UnionGraph", union);
|
||||
return dataset;
|
||||
}
|
||||
|
||||
public WebappDaoFactoryJena(OntModelSelector ontModelSelector,
|
||||
String defaultNamespace,
|
||||
HashSet<String> nonuserNamespaces,
|
||||
|
|
|
@ -39,6 +39,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.FilterFactory;
|
|||
import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.HiddenFromDisplayBelowRoleLevelFilter;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilterUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
|
||||
import edu.cornell.mannlib.vitro.webapp.flags.AuthFlag;
|
||||
import edu.cornell.mannlib.vitro.webapp.flags.FlagException;
|
||||
import edu.cornell.mannlib.vitro.webapp.flags.PortalFlag;
|
||||
|
@ -203,9 +204,8 @@ public class VitroRequestPrep implements Filter {
|
|||
|
||||
// support for Dataset interface if using Jena in-memory model
|
||||
if (vreq.getDataset() == null) {
|
||||
DataSource dataset = DatasetFactory.create();
|
||||
dataset.addNamedModel(JenaDataSourceSetupBase.JENA_DB_MODEL, vreq.getAssertionsOntModel());
|
||||
dataset.addNamedModel(JenaDataSourceSetupBase.JENA_INF_MODEL, vreq.getInferenceOntModel());
|
||||
Dataset dataset = WebappDaoFactoryJena.makeInMemoryDataset(
|
||||
vreq.getAssertionsOntModel(), vreq.getInferenceOntModel());
|
||||
vreq.setDataset(dataset);
|
||||
}
|
||||
|
||||
|
|
|
@ -206,13 +206,16 @@ public class JenaDataSourceSetupSDB extends JenaDataSourceSetupBase implements j
|
|||
log.error("Unable to load application metadata model cache from DB", e);
|
||||
}
|
||||
|
||||
log.info("Adding vitro application ontology");
|
||||
|
||||
// add the vitro ontologies to the tbox models
|
||||
// add the vitroontologies to the tbox models
|
||||
OntModel vitroTBoxModel = (new JenaBaseDaoCon()).getConstModel();
|
||||
baseOms.getTBoxModel().addSubModel(vitroTBoxModel);
|
||||
inferenceOms.getTBoxModel().addSubModel(vitroTBoxModel);
|
||||
unionOms.getTBoxModel().addSubModel(vitroTBoxModel);
|
||||
|
||||
log.error("Setting up union models and DAO factories");
|
||||
|
||||
// create TBox + ABox union models and set up webapp DAO factories
|
||||
OntModel baseUnion = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM,
|
||||
ModelFactory.createUnion(baseOms.getABoxModel(), baseOms.getTBoxModel()));
|
||||
|
@ -262,6 +265,8 @@ public class JenaDataSourceSetupSDB extends JenaDataSourceSetupBase implements j
|
|||
// loadDataFromFilesystem(unionOms.getFullModel(), sce.getServletContext());
|
||||
//}
|
||||
|
||||
log.info("Checking for user account data");
|
||||
|
||||
if (userAccountsModel.size() == 0) {
|
||||
readOntologyFilesInPathSet(AUTHPATH, sce.getServletContext(), userAccountsModel);
|
||||
if (userAccountsModel.size() == 0) {
|
||||
|
@ -269,20 +274,28 @@ public class JenaDataSourceSetupSDB extends JenaDataSourceSetupBase implements j
|
|||
}
|
||||
}
|
||||
|
||||
log.info("Checking for minimal interface metadata");
|
||||
|
||||
ensureEssentialInterfaceData(unionOms.getApplicationMetadataModel(), sce, wadf);
|
||||
|
||||
//log.info("Setting up namespace mapper");
|
||||
|
||||
NamespaceMapper namespaceMapper = new NamespaceMapperJena(masterUnion, masterUnion, defaultNamespace);
|
||||
sce.getServletContext().setAttribute("NamespaceMapper", namespaceMapper);
|
||||
unionOms.getFullModel().getBaseModel().register(namespaceMapper);
|
||||
|
||||
sce.getServletContext().setAttribute("defaultNamespace", defaultNamespace);
|
||||
|
||||
log.info("SDB store ready for use");
|
||||
|
||||
makeModelMakerFromConnectionProperties(TripleStoreType.RDB);
|
||||
VitroJenaModelMaker vjmm = getVitroJenaModelMaker();
|
||||
setVitroJenaModelMaker(vjmm,sce);
|
||||
makeModelMakerFromConnectionProperties(TripleStoreType.SDB);
|
||||
VitroJenaSDBModelMaker vsmm = getVitroJenaSDBModelMaker();
|
||||
setVitroJenaSDBModelMaker(vsmm,sce);
|
||||
|
||||
log.info("Model makers set up");
|
||||
|
||||
} catch (Throwable t) {
|
||||
log.error("Throwable in " + this.getClass().getName(), t);
|
||||
|
@ -587,7 +600,9 @@ public class JenaDataSourceSetupSDB extends JenaDataSourceSetupBase implements j
|
|||
SimpleReasonerSetup.setRecomputeRequired(ctx);
|
||||
|
||||
} finally {
|
||||
log.info("Adding indexes to SDB database tables.");
|
||||
store.getTableFormatter().addIndexes();
|
||||
log.info("Indexes created.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.hp.hpl.jena.ontology.Individual;
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.rdf.listeners.StatementListener;
|
||||
|
@ -26,6 +29,8 @@ import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapper;
|
|||
public class NamespaceMapperJena extends StatementListener implements
|
||||
NamespaceMapper {
|
||||
|
||||
private static final Log log = LogFactory.getLog(NamespaceMapperJena.class);
|
||||
|
||||
private HashMap<String,String> prefixToNamespaceMap;
|
||||
private HashMap<String,List<String>> namespaceToPrefixMap;
|
||||
|
||||
|
@ -60,15 +65,23 @@ public class NamespaceMapperJena extends StatementListener implements
|
|||
|
||||
}
|
||||
|
||||
private static int LARGE_NS = 200;
|
||||
|
||||
private void rebuildNamespaceCache() {
|
||||
HashMap<String,String> tempPrefixToNamespaceMap = new HashMap<String,String>();
|
||||
HashMap<String,List<String>> tempNamespaceToPrefixMap = new HashMap<String,List<String>>();
|
||||
metadataModel.enterCriticalSection(Lock.READ);
|
||||
int nsCount = 0;
|
||||
try {
|
||||
// Iterate through all the namespace objects
|
||||
ClosableIterator closeIt = metadataModel.listIndividuals(metadataModel.getResource(VitroVocabulary.NAMESPACE));
|
||||
try {
|
||||
for (Iterator namespaceIt = closeIt; namespaceIt.hasNext();) {
|
||||
nsCount++;
|
||||
if (nsCount == LARGE_NS) {
|
||||
log.warn("Unusually large number of different namespaces encountered; " +
|
||||
"namespace mapper setup may take some time.");
|
||||
}
|
||||
Individual namespaceInd = (Individual) namespaceIt.next();
|
||||
String namespaceURI = null;
|
||||
RDFNode node = namespaceInd.getPropertyValue(metadataModel.getProperty(VitroVocabulary.NAMESPACE_NAMESPACEURI));
|
||||
|
|
|
@ -44,6 +44,7 @@ public abstract class BaseObjectPropertyDataPostProcessor implements
|
|||
|
||||
/** Postprocessing that applies to the list as a whole - reordering, removing duplicates, etc. */
|
||||
protected void processList(List<Map<String, String>> data) {
|
||||
objectPropertyTemplateModel.removeLessSpecificSolutions(data);
|
||||
objectPropertyTemplateModel.removeDuplicates(data);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import java.util.ArrayList;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -229,6 +230,67 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For performance reasons, we've had to rewrite SPARQL queries that would
|
||||
* naturally use OPTIONAL blocks to use UNIONs instead. These UNION queries
|
||||
* return a superset of the solutions returned by the originals. This
|
||||
* method filters out the unwanted solutions with extra null values.
|
||||
*
|
||||
* This operation is polynomial time in the worst case, but should be linear
|
||||
* with the actual queries used for list views. The ORDER BY clauses
|
||||
* should minimize the seek distance for solution elimination.
|
||||
*
|
||||
* @param List<Map<String, String>> data
|
||||
*/
|
||||
protected void removeLessSpecificSolutions(List<Map<String, String>> data) {
|
||||
List<Map<String, String>> redundantSolns =
|
||||
new ArrayList<Map<String, String>>();
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
Map<String,String> soln = data.get(i);
|
||||
boolean redundantSoln = false;
|
||||
// seek forward
|
||||
int j = i + 1;
|
||||
while (!redundantSoln && (j < data.size())) {
|
||||
redundantSoln = isEqualToOrLessSpecificThan(soln, data.get(j));
|
||||
j++;
|
||||
}
|
||||
// loop back around
|
||||
j = 0;
|
||||
while (!redundantSoln && (j < i)) {
|
||||
redundantSoln = isEqualToOrLessSpecificThan(soln, data.get(j));
|
||||
j++;
|
||||
}
|
||||
if (redundantSoln) {
|
||||
redundantSolns.add(soln);
|
||||
}
|
||||
}
|
||||
data.removeAll(redundantSolns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if soln1 is equal to or less specific (i.e., has more null
|
||||
* values) than soln2
|
||||
* @param List<Map<String, String>> soln1
|
||||
* @param List<Map<String, String>> soln2
|
||||
*/
|
||||
private boolean isEqualToOrLessSpecificThan (Map<String, String> soln1,
|
||||
Map<String, String> soln2) {
|
||||
if (soln1.keySet().size() < soln2.keySet().size()) {
|
||||
return true;
|
||||
}
|
||||
for (String key : soln1.keySet()) {
|
||||
String value1 = soln1.get(key);
|
||||
String value2 = soln2.get(key);
|
||||
if (value2 == null && value1 != null) {
|
||||
return false;
|
||||
}
|
||||
if (value1 != null && value2 != null && !value1.equals(value2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** The SPARQL query results may contain duplicate rows for a single object, if there are multiple solutions
|
||||
* to the entire query. Remove duplicates here by arbitrarily selecting only the first row returned.
|
||||
|
|
|
@ -11,9 +11,21 @@
|
|||
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
||||
|
||||
SELECT ?object ?name ?moniker {
|
||||
GRAPH ?g1 { ?subject ?property ?object }
|
||||
OPTIONAL { GRAPH ?g2 { ?object rdfs:label ?name } }
|
||||
OPTIONAL { GRAPH ?g3 { ?object vitro:moniker ?moniker } }
|
||||
{
|
||||
?subject ?property ?object .
|
||||
}
|
||||
UNION {
|
||||
?subject ?property ?object .
|
||||
?object rdfs:label ?name
|
||||
}
|
||||
UNION {
|
||||
?subject ?property ?object .
|
||||
?object vitro:moniker ?moniker
|
||||
} UNION {
|
||||
?subject ?property ?object .
|
||||
?object rdfs:label ?name .
|
||||
?object vitro:moniker ?moniker .
|
||||
}
|
||||
}
|
||||
</query-base>
|
||||
|
||||
|
@ -22,11 +34,28 @@
|
|||
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
||||
|
||||
SELECT ?subclass ?object ?name ?moniker {
|
||||
GRAPH ?g1 { ?subject ?property ?object
|
||||
OPTIONAL { ?object a ?subclass }
|
||||
|
||||
{
|
||||
?subject ?property ?object .
|
||||
?object a ?subclass .
|
||||
}
|
||||
OPTIONAL { GRAPH ?g2 { ?object rdfs:label ?name } }
|
||||
OPTIONAL { GRAPH ?g3 { ?object vitro:moniker ?moniker } }
|
||||
UNION {
|
||||
?subject ?property ?object .
|
||||
?object a ?subclass .
|
||||
?object rdfs:label ?name
|
||||
}
|
||||
UNION {
|
||||
?subject ?property ?object .
|
||||
?object a ?subclass .
|
||||
?object vitro:moniker ?moniker
|
||||
} UNION {
|
||||
?subject ?property ?object .
|
||||
?object a ?subclass .
|
||||
?object rdfs:label ?name .
|
||||
?object vitro:moniker ?moniker .
|
||||
}
|
||||
|
||||
|
||||
} ORDER BY ?subclass
|
||||
</query-collated>
|
||||
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
(afn:localname(?link) AS ?linkName)
|
||||
?anchor
|
||||
?url WHERE {
|
||||
GRAPH ?g1 { ?subject ?property ?link }
|
||||
OPTIONAL { GRAPH ?g2 { ?link vitro:linkAnchor ?anchor } }
|
||||
OPTIONAL { GRAPH ?g3 { ?link vitro:linkURL ?url } }
|
||||
OPTIONAL { GRAPH ?g4 { ?link vitro:linkDisplayRank ?rank } }
|
||||
?subject ?property ?link
|
||||
OPTIONAL { ?link vitro:linkAnchor ?anchor }
|
||||
OPTIONAL { ?link vitro:linkURL ?url }
|
||||
OPTIONAL { ?link vitro:linkDisplayRank ?rank }
|
||||
} ORDER BY ?rank
|
||||
</query-base>
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue