initial work on VIVO-60 application ontology support for property/range combinations

This commit is contained in:
brianjlowe 2013-05-14 15:54:03 -04:00
parent 556af80432
commit 1ab53d0b02
10 changed files with 152 additions and 28 deletions

View file

@ -303,7 +303,7 @@ public class UrlBuilder {
} }
public static String urlEncode(String str) { public static String urlEncode(String str) {
String encoding = "ISO-8859-1"; String encoding = "UTF-8";
String encodedUrl = null; String encodedUrl = null;
try { try {
encodedUrl = URLEncoder.encode(str, encoding); encodedUrl = URLEncoder.encode(str, encoding);
@ -314,7 +314,7 @@ public class UrlBuilder {
} }
public static String urlDecode(String str) { public static String urlDecode(String str) {
String encoding = "ISO-8859-1"; String encoding = "UTF-8";
String decodedUrl = null; String decodedUrl = null;
try { try {
decodedUrl = URLDecoder.decode(str, encoding); decodedUrl = URLDecoder.decode(str, encoding);

View file

@ -41,7 +41,7 @@ public interface ObjectPropertyStatementDao {
public Map<String, String> getMostSpecificTypesInClassgroupsForIndividual(String subjectUri); public Map<String, String> getMostSpecificTypesInClassgroupsForIndividual(String subjectUri);
List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty( List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(
String subjectUri, String propertyUri, String objectKey, String subjectUri, String propertyUri, String objectKey, String rangeUri,
String queryString, Set<String> constructQueryStrings, String queryString, Set<String> constructQueryStrings,
String sortDirection); String sortDirection);

View file

@ -86,12 +86,12 @@ class ObjectPropertyStatementDaoFiltering extends BaseFiltering implements Objec
@Override @Override
public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty( public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(
String subjectUri, String propertyUri, String objectKey, String query, String subjectUri, String propertyUri, String objectKey, String rangeUri,
Set<String> queryStrings, String sortDirection) { String query, Set<String> queryStrings, String sortDirection) {
List<Map<String, String>> data = List<Map<String, String>> data =
innerObjectPropertyStatementDao.getObjectPropertyStatementsForIndividualByProperty( innerObjectPropertyStatementDao.getObjectPropertyStatementsForIndividualByProperty(
subjectUri, propertyUri, objectKey, query, queryStrings,sortDirection); subjectUri, propertyUri, objectKey, rangeUri, query, queryStrings,sortDirection);
/* Filter the data /* Filter the data
* *

View file

@ -27,6 +27,7 @@ import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution; import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Resource;
@ -38,6 +39,7 @@ import com.hp.hpl.jena.util.iterator.ClosableIterator;
import com.hp.hpl.jena.vocabulary.OWL; import com.hp.hpl.jena.vocabulary.OWL;
import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDF;
import com.hp.hpl.jena.vocabulary.RDFS; import com.hp.hpl.jena.vocabulary.RDFS;
import com.hp.hpl.jena.sdb.util.Pair;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean; import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.Individual;
@ -859,12 +861,16 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
} }
} }
Map<ObjectProperty, String> customListViewConfigFileMap = null; //TODO private void addPropertyClassCombinationsToListViewMap(HashMap)
// Map key is pair of object property and range class URI
// If range is unspecified, OWL.Thing.getURI() is used in the key.
Map<Pair<ObjectProperty, String>, String> customListViewConfigFileMap = null;
@Override @Override
public String getCustomListViewConfigFileName(ObjectProperty op) { public String getCustomListViewConfigFileName(ObjectProperty op) {
if (customListViewConfigFileMap == null) { if (customListViewConfigFileMap == null) {
customListViewConfigFileMap = new HashMap<ObjectProperty, String>(); customListViewConfigFileMap = new HashMap<Pair<ObjectProperty, String>, String>();
OntModel displayModel = getOntModelSelector().getDisplayModel(); OntModel displayModel = getOntModelSelector().getDisplayModel();
//Get all property to list view config file mappings in the system //Get all property to list view config file mappings in the system
QueryExecution qexec = QueryExecutionFactory.create(listViewConfigFileQuery, displayModel); QueryExecution qexec = QueryExecutionFactory.create(listViewConfigFileQuery, displayModel);
@ -883,12 +889,18 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
} }
} else { } else {
String filename = soln.getLiteral("filename").getLexicalForm(); String filename = soln.getLiteral("filename").getLexicalForm();
customListViewConfigFileMap.put(prop, filename); customListViewConfigFileMap.put(new Pair<ObjectProperty, String>(prop, OWL.Thing.getURI()), filename);
} }
} }
qexec.close(); qexec.close();
} }
return customListViewConfigFileMap.get(op);
String customListViewConfigFileName = customListViewConfigFileMap.get(new Pair<ObjectProperty, String>(op, op.getRangeVClassURI()));
if (customListViewConfigFileName == null) {
customListViewConfigFileName = customListViewConfigFileMap.get(new Pair<ObjectProperty, String>(op, OWL.Thing.getURI()));
}
return customListViewConfigFileName;
} }
} }

View file

@ -271,6 +271,7 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
String subjectUri, String subjectUri,
String propertyUri, String propertyUri,
String objectKey, String objectKey,
String rangeUri,
String queryString, String queryString,
Set<String> constructQueryStrings, Set<String> constructQueryStrings,
String sortDirection) { String sortDirection) {
@ -296,6 +297,7 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
QuerySolutionMap initialBindings = new QuerySolutionMap(); QuerySolutionMap initialBindings = new QuerySolutionMap();
initialBindings.add("subject", ResourceFactory.createResource(subjectUri)); initialBindings.add("subject", ResourceFactory.createResource(subjectUri));
initialBindings.add("property", ResourceFactory.createResource(propertyUri)); initialBindings.add("property", ResourceFactory.createResource(propertyUri));
initialBindings.add("objectType", ResourceFactory.createResource(rangeUri));
// Run the SPARQL query to get the properties // Run the SPARQL query to get the properties
List<Map<String, String>> list = new ArrayList<Map<String, String>>(); List<Map<String, String>> list = new ArrayList<Map<String, String>>();

View file

@ -2,24 +2,20 @@
package edu.cornell.mannlib.vitro.webapp.dao.jena; package edu.cornell.mannlib.vitro.webapp.dao.jena;
import java.util.List;
import com.hp.hpl.jena.ontology.AnnotationProperty;
import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.query.Query; import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution; import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory; import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory; import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.QuerySolutionMap;
import com.hp.hpl.jena.query.ResultSet; import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.query.Syntax; import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.rdf.model.Literal; import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource; import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.ResourceFactory;
import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.rdf.model.StmtIterator;
import com.hp.hpl.jena.shared.Lock; import com.hp.hpl.jena.shared.Lock;
import com.hp.hpl.jena.util.iterator.ClosableIterator; import com.hp.hpl.jena.util.iterator.ClosableIterator;
import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDF;
@ -57,13 +53,13 @@ public class VClassDaoSDB extends VClassDaoJena {
try { try {
if ((group != null) && (group.getURI() != null)) { if ((group != null) && (group.getURI() != null)) {
Resource groupRes = ResourceFactory.createResource(group.getURI()); Resource groupRes = ResourceFactory.createResource(group.getURI());
AnnotationProperty inClassGroup = getOntModel().getAnnotationProperty(VitroVocabulary.IN_CLASSGROUP); Property inClassGroup = ResourceFactory.createProperty(VitroVocabulary.IN_CLASSGROUP);
if (inClassGroup != null) { if (inClassGroup != null) {
ClosableIterator annotIt = getOntModel().listStatements((OntClass)null,inClassGroup,groupRes); StmtIterator annotIt = getOntModel().listStatements((Resource)null,inClassGroup, groupRes);
try { try {
while (annotIt.hasNext()) { while (annotIt.hasNext()) {
try { try {
Statement annot = (Statement) annotIt.next(); Statement annot = (Statement) annotIt.nextStatement();
Resource cls = (Resource) annot.getSubject(); Resource cls = (Resource) annot.getSubject();
VClass vcw = (VClass) getVClassByURI(cls.getURI()); VClass vcw = (VClass) getVClassByURI(cls.getURI());
if (vcw != null) { if (vcw != null) {
@ -95,7 +91,7 @@ public class VClassDaoSDB extends VClassDaoJena {
Model aboxModel = getOntModelSelector().getABoxModel(); Model aboxModel = getOntModelSelector().getABoxModel();
aboxModel.enterCriticalSection(Lock.READ); aboxModel.enterCriticalSection(Lock.READ);
try { try {
ClosableIterator countIt = aboxModel.listStatements(null,RDF.type,cls); StmtIterator countIt = aboxModel.listStatements(null,RDF.type,cls);
try { try {
if (countIt.hasNext()) { if (countIt.hasNext()) {
classIsInstantiated = true; classIsInstantiated = true;

View file

@ -0,0 +1,99 @@
package edu.cornell.mannlib.vitro.webapp.utils;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Resource;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext;
public class ApplicationConfigurationOntologyUtils {
private static final Log log = LogFactory.getLog(ApplicationConfigurationOntologyUtils.class);
public static List<ObjectProperty> getAdditionalFauxSubpropertiesForList(List<ObjectProperty> propList, VitroRequest vreq) {
Model displayModel = ModelContext.getDisplayModel(vreq.getSession().getServletContext());
Model tboxModel = ModelContext.getUnionOntModelSelector(vreq.getSession().getServletContext()).getTBoxModel();
return getAdditionalFauxSubpropertiesForList(propList, displayModel, tboxModel);
}
public static List<ObjectProperty> getAdditionalFauxSubpropertiesForList(List<ObjectProperty> propList,
Model displayModel,
Model tboxModel) {
List<ObjectProperty> additionalProps = new ArrayList<ObjectProperty>();
Model union = ModelFactory.createUnion(displayModel, tboxModel);
String propQuery = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
"PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" +
"SELECT ?range ?label ?listView ?group WHERE { \n" +
" ?p rdfs:subPropertyOf ?property . \n" +
" ?context config:configContextFor ?p . \n" +
" ?context config:qualifiedBy ?range . \n" +
" ?context config:hasConfiguration ?configuration . \n" +
" OPTIONAL { ?configuration config:propertyGroup ?group } \n" +
" OPTIONAL { ?configuration config:displayName ?label } \n" +
" OPTIONAL { ?configuration config:hasListView ?lv . ?lv config:listViewConfigFile ?listView } \n" +
"}";
for (ObjectProperty op : propList) {
String queryStr = propQuery.replaceAll("\\?property", "<" + op.getURI() + ">");
log.debug(queryStr);
Query q = QueryFactory.create(queryStr);
QueryExecution qe = QueryExecutionFactory.create(q, union);
try {
ResultSet rs = qe.execSelect();
while (rs.hasNext()) {
ObjectProperty newProp = new ObjectProperty();
newProp.setURI(op.getURI());
QuerySolution qsoln = rs.nextSolution();
log.debug(qsoln);
Resource rangeRes = qsoln.getResource("range");
if (rangeRes != null) {
newProp.setRangeVClassURI(rangeRes.getURI());
} else {
newProp.setRangeVClassURI(op.getRangeVClassURI());
}
Resource groupRes = qsoln.getResource("group");
if (groupRes != null) {
newProp.setGroupURI(groupRes.getURI());
} else {
newProp.setGroupURI(op.getURI());
}
Literal labelLit = qsoln.getLiteral("label");
if (labelLit != null) {
newProp.setDomainPublic(labelLit.getLexicalForm());
} else {
newProp.setDomainPublic(op.getDomainPublic());
}
Literal listViewLit = qsoln.getLiteral("listView");
if (listViewLit != null) {
// TODO where do we get the list views from?
} else {
// newProp.set
}
additionalProps.add(newProp);
}
} finally {
qe.close();
}
}
return additionalProps;
}
}

View file

@ -25,6 +25,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao; import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.utils.ApplicationConfigurationOntologyUtils;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
/* /*
@ -72,13 +73,27 @@ public class GroupedPropertyList extends BaseTemplateModel {
// so we cannot just rely on getting that list. // so we cannot just rely on getting that list.
List<ObjectProperty> populatedObjectPropertyList = subject List<ObjectProperty> populatedObjectPropertyList = subject
.getPopulatedObjectPropertyList(); .getPopulatedObjectPropertyList();
List<ObjectProperty> additions = ApplicationConfigurationOntologyUtils
.getAdditionalFauxSubpropertiesForList(
populatedObjectPropertyList, vreq);
if (log.isDebugEnabled()) {
for (ObjectProperty t : additions) {
log.debug(t.getDomainPublic() + " " + t.getGroupURI());
}
log.debug("Added " + additions.size() +
" properties due to application configuration ontology");
}
populatedObjectPropertyList.addAll(additions);
propertyList.addAll(populatedObjectPropertyList); propertyList.addAll(populatedObjectPropertyList);
// If editing this page, merge in object properties applicable to the individual that are currently // If editing this page, merge in object properties applicable to the individual that are currently
// unpopulated, so the properties are displayed to allow statements to be added to these properties. // unpopulated, so the properties are displayed to allow statements to be added to these properties.
// RY In future, we should limit this to properties that the user has permission to add properties to. // RY In future, we should limit this to properties that the user has permission to add properties to.
if (editing) { if (editing) {
mergeAllPossibleObjectProperties(populatedObjectPropertyList, propertyList); mergeAllPossibleObjectProperties(populatedObjectPropertyList, propertyList);
} }
// Now do much the same with data properties: get the list of populated data properties, then add in placeholders for missing ones // Now do much the same with data properties: get the list of populated data properties, then add in placeholders for missing ones
@ -108,7 +123,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
subject, editing, populatedDataPropertyList, subject, editing, populatedDataPropertyList,
populatedObjectPropertyList)); populatedObjectPropertyList));
} }
if (!editing) { if (!editing) {
pruneEmptyProperties(); pruneEmptyProperties();
} }
@ -351,7 +366,6 @@ public class GroupedPropertyList extends BaseTemplateModel {
} else { } else {
String groupUriForProperty = p.getGroupURI(); String groupUriForProperty = p.getGroupURI();
boolean assignedToGroup = false; boolean assignedToGroup = false;
if (groupUriForProperty != null) { if (groupUriForProperty != null) {
for (PropertyGroup pg : groupList) { for (PropertyGroup pg : groupList) {
String groupUri = pg.getURI(); String groupUri = pg.getURI();
@ -359,7 +373,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
pg.getPropertyList().add(p); pg.getPropertyList().add(p);
assignedToGroup = true; assignedToGroup = true;
break; break;
} }
} }
} }

View file

@ -80,6 +80,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
private PropertyListConfig config; private PropertyListConfig config;
private String objectKey; private String objectKey;
private String sortDirection; private String sortDirection;
private String rangeURI;
ObjectPropertyTemplateModel(ObjectProperty op, Individual subject, VitroRequest vreq, ObjectPropertyTemplateModel(ObjectProperty op, Individual subject, VitroRequest vreq,
boolean editing) boolean editing)
@ -89,6 +90,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
setName(op.getDomainPublic()); setName(op.getDomainPublic());
sortDirection = op.getDomainEntitySortDirection(); sortDirection = op.getDomainEntitySortDirection();
rangeURI = op.getRangeVClassURI();
// Get the config for this object property // Get the config for this object property
try { try {
@ -147,8 +149,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
protected List<Map<String, String>> getStatementData() { protected List<Map<String, String>> getStatementData() {
ObjectPropertyStatementDao opDao = vreq.getWebappDaoFactory().getObjectPropertyStatementDao(); ObjectPropertyStatementDao opDao = vreq.getWebappDaoFactory().getObjectPropertyStatementDao();
return opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, objectKey, rangeURI, getSelectQuery(), getConstructQueries(), sortDirection);
return opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, objectKey, getSelectQuery(), getConstructQueries(), sortDirection);
} }
protected abstract boolean isEmpty(); protected abstract boolean isEmpty();

View file

@ -216,7 +216,7 @@ public class ObjectPropertyStatementDaoStub implements
@Override @Override
public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty( public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(
String subjectUri, String propertyUri, String objectKey, String subjectUri, String propertyUri, String objectKey, String rangeUri,
String query, Set<String> constructQueries, String sortDir) { String query, Set<String> constructQueries, String sortDir) {
throw new RuntimeException( throw new RuntimeException(
"ObjectPropertyStatementDaoStub.getObjectPropertyStatementsForIndividualByProperty() not implemented."); "ObjectPropertyStatementDaoStub.getObjectPropertyStatementsForIndividualByProperty() not implemented.");