NIHVIVO-2416 Handle properties declared as both object and data properties in individual property display without throwing an error.

This commit is contained in:
ryounes 2011-04-04 20:02:35 +00:00
parent b8d07dc9a8
commit a5ef0e4f0b
8 changed files with 88 additions and 72 deletions

View file

@ -31,7 +31,7 @@ public interface ObjectPropertyStatementDao {
int insertNewObjectPropertyStatement(ObjectPropertyStatement objPropertyStmt ); int insertNewObjectPropertyStatement(ObjectPropertyStatement objPropertyStmt );
public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(String subjectUri, String propertyUri, String query); public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(String subjectUri, String propertyUri, String objectKey, String query);
public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(String subjectUri, String propertyUri, String query, Set<String> constructQueries); public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(String subjectUri, String propertyUri, String objectKey, String query, Set<String> constructQueries);
} }

View file

@ -86,15 +86,15 @@ class ObjectPropertyStatementDaoFiltering extends BaseFiltering implements Objec
@Override @Override
// RY What about filtering? // RY What about filtering?
public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty( public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(
String subjectUri, String propertyUri, String query) { String subjectUri, String propertyUri, String objectKey, String query) {
return innerObjectPropertyStatementDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, query); return innerObjectPropertyStatementDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, objectKey, query);
} }
@Override @Override
// RY What about filtering? // RY What about filtering?
public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty( public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(
String subjectUri, String propertyUri, String query, Set<String> queryStrings) { String subjectUri, String propertyUri, String objectKey, String query, Set<String> queryStrings) {
return innerObjectPropertyStatementDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, query, queryStrings); return innerObjectPropertyStatementDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, objectKey, query, queryStrings);
} }

View file

@ -27,6 +27,7 @@ import com.hp.hpl.jena.query.Query;
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.query.Syntax;
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;
@ -75,30 +76,13 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
* This is a hack to throw out properties in the vitro, rdf, rdfs, and owl namespaces. * This is a hack to throw out properties in the vitro, rdf, rdfs, and owl namespaces.
* It will be implemented in a better way in v1.3 (Editing and Display Configuration). * It will be implemented in a better way in v1.3 (Editing and Display Configuration).
*/ */
protected static String propertyFilters = null; protected static final String PROPERTY_FILTERS;
static { static {
List<String> namespaceFilters = new ArrayList<String>(); List<String> namespaceFilters = new ArrayList<String>();
for (String s : EXCLUDED_NAMESPACES) { for (String namespace : EXCLUDED_NAMESPACES) {
namespaceFilters.add("(afn:namespace(?property) != \"" + s + "\")"); namespaceFilters.add("( afn:namespace(?property) != \"" + namespace + "\" )");
}
propertyFilters = "FILTER (" + StringUtils.join(namespaceFilters, " && ") + ")\n";
}
protected static final String DATA_PROPERTY_QUERY_STRING =
prefixes + "\n" +
"SELECT DISTINCT ?property WHERE { \n" +
" ?subject ?property ?object . \n" +
" ?property rdf:type owl:DatatypeProperty . \n" +
propertyFilters +
"}";
protected static Query dataPropertyQuery;
static {
try {
dataPropertyQuery = QueryFactory.create(DATA_PROPERTY_QUERY_STRING);
} catch(Throwable th){
log.error("could not create SPARQL query for DATA_PROPERTY_QUERY_STRING " + th.getMessage());
log.error(DATA_PROPERTY_QUERY_STRING);
} }
PROPERTY_FILTERS = StringUtils.join(namespaceFilters, " && ");
} }
private class DataPropertyRanker implements Comparator { private class DataPropertyRanker implements Comparator {
@ -767,9 +751,32 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
* into the new one in a future release. * into the new one in a future release.
*/ */
public List<DataProperty> getDataPropertyList(String subjectUri) { public List<DataProperty> getDataPropertyList(String subjectUri) {
log.debug("Data property query string:\n" + DATA_PROPERTY_QUERY_STRING);
log.debug("Data property query:\n" + dataPropertyQuery); // Due to a Jena bug, prebinding on ?subject combined with the isLiteral()
Iterator<QuerySolution> results = getPropertyQueryResults(subjectUri, dataPropertyQuery); // filter causes the query to fail. Using string concatenation to insert the
// subject uri instead.
String queryString =
prefixes + "\n" +
"SELECT DISTINCT ?property WHERE { \n" +
" <" + subjectUri + "> ?property ?object . \n" +
" ?property a owl:DatatypeProperty . \n" +
" FILTER ( \n" +
" isLiteral(?object) && \n" +
PROPERTY_FILTERS + "\n" +
" ) \n" +
"}";
Query query = null;
try {
query = QueryFactory.create(queryString);
} catch(Throwable th){
log.error("could not create SPARQL query for query string " + th.getMessage());
log.error(queryString);
return null;
}
log.debug("Data property query string:\n" + query);
Iterator<QuerySolution> results = getPropertyQueryResults(subjectUri, query);
List<DataProperty> properties = new ArrayList<DataProperty>(); List<DataProperty> properties = new ArrayList<DataProperty>();
while (results.hasNext()) { while (results.hasNext()) {
QuerySolution sol = results.next(); QuerySolution sol = results.next();

View file

@ -26,6 +26,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.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.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;
@ -55,44 +56,23 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
private static final Log log = LogFactory.getLog(ObjectPropertyDaoJena.class.getName()); private static final Log log = LogFactory.getLog(ObjectPropertyDaoJena.class.getName());
protected static final List<String> EXCLUDED_NAMESPACES = Arrays.asList( protected static final List<String> EXCLUDED_NAMESPACES = Arrays.asList(
// Don't need to exclude these, because they are not owl:ObjectProperty
//"http://www.w3.org/1999/02/22-rdf-syntax-ns#",
//"http://www.w3.org/2000/01/rdf-schema#",
"http://www.w3.org/2002/07/owl#" "http://www.w3.org/2002/07/owl#"
); );
/* /*
* This is a hack to throw out properties in the vitro, rdf, rdfs, and owl namespaces. * This is a hack to throw out properties in the vitro, rdf, rdfs, and owl namespaces.
* It will be implemented in a better way in v1.3 (Editing and Display Configuration). * It will be implemented in a better way in v1.3 (Editing and Display Configuration).
*/ */
protected static String propertyFilters = ""; protected static final String PROPERTY_FILTERS;
static { static {
List<String> namespaceFilters = new ArrayList<String>(); List<String> namespaceFilters = new ArrayList<String>();
for (String s : EXCLUDED_NAMESPACES) { for (String namespace : EXCLUDED_NAMESPACES) {
namespaceFilters.add("(afn:namespace(?property) != \"" + s + "\")"); namespaceFilters.add("( afn:namespace(?property) != \"" + namespace + "\" )");
} }
// A hack to include the vitro:primaryLink and vitro:additionalLink properties in the list // A hack to include the vitro:primaryLink and vitro:additionalLink properties in the list
namespaceFilters.add("( ?property = vitro:primaryLink ||" + namespaceFilters.add("( ?property = vitro:primaryLink ||" +
"?property = vitro:additionalLink ||" + "?property = vitro:additionalLink ||" +
"afn:namespace(?property) != \"http://vitro.mannlib.cornell.edu/ns/vitro/0.7#\" )"); "afn:namespace(?property) != \"http://vitro.mannlib.cornell.edu/ns/vitro/0.7#\" )");
propertyFilters = "FILTER (" + StringUtils.join(namespaceFilters, " && ") + ")\n"; PROPERTY_FILTERS = StringUtils.join(namespaceFilters, " && ");
}
protected static final String OBJECT_PROPERTY_QUERY_STRING =
prefixes + "\n" +
"SELECT DISTINCT ?property WHERE { \n" +
" ?subject ?property ?object . \n" +
" ?property rdf:type owl:ObjectProperty . \n" +
propertyFilters +
"}";
protected static Query objectPropertyQuery;
static {
try {
objectPropertyQuery = QueryFactory.create(OBJECT_PROPERTY_QUERY_STRING);
} catch(Throwable th){
log.error("could not create SPARQL query for OBJECT_PROPERTY_QUERY_STRING " + th.getMessage());
log.error(OBJECT_PROPERTY_QUERY_STRING);
}
} }
protected static final String LIST_VIEW_CONFIG_FILE_QUERY_STRING = protected static final String LIST_VIEW_CONFIG_FILE_QUERY_STRING =
@ -101,7 +81,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
" ?property display:listViewConfigFile ?filename . \n" + " ?property display:listViewConfigFile ?filename . \n" +
"}"; "}";
protected static Query listViewConfigFileQuery; protected static Query listViewConfigFileQuery = null;
static { static {
try { try {
listViewConfigFileQuery = QueryFactory.create(LIST_VIEW_CONFIG_FILE_QUERY_STRING); listViewConfigFileQuery = QueryFactory.create(LIST_VIEW_CONFIG_FILE_QUERY_STRING);
@ -884,9 +864,32 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
* into the new one in a future release. * into the new one in a future release.
*/ */
public List<ObjectProperty> getObjectPropertyList(String subjectUri) { public List<ObjectProperty> getObjectPropertyList(String subjectUri) {
log.debug("Object property query string:\n" + OBJECT_PROPERTY_QUERY_STRING);
log.debug("Object property query:\n" + objectPropertyQuery); // Due to a Jena bug, prebinding on ?subject combined with the isURI()
Iterator<QuerySolution> results = getPropertyQueryResults(subjectUri, objectPropertyQuery); // filter causes the query to fail. Using string concatenation to insert the
// subject uri instead.
String queryString =
prefixes + "\n" +
"SELECT DISTINCT ?property WHERE { \n" +
" <" + subjectUri + "> ?property ?object . \n" +
" ?property a owl:ObjectProperty . \n" +
" FILTER ( \n" +
" isURI(?object) && \n" +
PROPERTY_FILTERS + "\n" +
" ) \n" +
"}";
Query query = null;
try {
query = QueryFactory.create(queryString);
} catch(Throwable th){
log.error("could not create SPARQL query for query string " + th.getMessage());
log.error(queryString);
return null;
}
log.debug("Object property query:\n" + query);
Iterator<QuerySolution> results = getPropertyQueryResults(subjectUri, query);
List<ObjectProperty> properties = new ArrayList<ObjectProperty>(); List<ObjectProperty> properties = new ArrayList<ObjectProperty>();
while (results.hasNext()) { while (results.hasNext()) {
QuerySolution soln = results.next(); QuerySolution soln = results.next();

View file

@ -25,6 +25,7 @@ import com.hp.hpl.jena.query.Syntax;
import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ModelFactory;
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.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;
@ -254,10 +255,10 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty( public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(
String subjectUri, String subjectUri,
String propertyUri, String propertyUri,
String queryString) { String objectKey, String queryString) {
return getObjectPropertyStatementsForIndividualByProperty( return getObjectPropertyStatementsForIndividualByProperty(
subjectUri, propertyUri, null); subjectUri, propertyUri, objectKey, objectKey, null);
} }
@ -272,8 +273,8 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty( public List<Map<String, String>> getObjectPropertyStatementsForIndividualByProperty(
String subjectUri, String subjectUri,
String propertyUri, String propertyUri,
String queryString, String objectKey,
Set<String> constructQueryStrings ) { String queryString, Set<String> constructQueryStrings ) {
Model constructedModel = constructModelForSelectQueries( Model constructedModel = constructModelForSelectQueries(
subjectUri, propertyUri, constructQueryStrings); subjectUri, propertyUri, constructQueryStrings);
@ -313,8 +314,11 @@ public class ObjectPropertyStatementDaoJena extends JenaBaseDao implements Objec
while (results.hasNext()) { while (results.hasNext()) {
QuerySolution soln = results.nextSolution(); QuerySolution soln = results.nextSolution();
RDFNode node = soln.get(objectKey);
if (node.isResource()) {
list.add(QueryUtils.querySolutionToStringValueMap(soln)); list.add(QueryUtils.querySolutionToStringValueMap(soln));
} }
}
} finally { } finally {
dataset.getLock().leaveCriticalSection(); dataset.getLock().leaveCriticalSection();

View file

@ -404,10 +404,12 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
protected Iterator<QuerySolution> getPropertyQueryResults(String subjectUri, Query query) { protected Iterator<QuerySolution> getPropertyQueryResults(String subjectUri, Query query) {
log.debug("SPARQL query:\n" + query.toString()); log.debug("SPARQL query:\n" + query.toString());
// Bind the subject's uri to the ?subject query term
QuerySolutionMap subjectBinding = new QuerySolutionMap(); // RY Removing prebinding due to Jena bug: when isLiteral(?object) or
subjectBinding.add("subject", // isURI(?object) is added to the query as a filter, the query fails with prebinding
ResourceFactory.createResource(subjectUri)); // but succeeds when the subject uri is concatenated into the query string.
//QuerySolutionMap subjectBinding = new QuerySolutionMap();
//subjectBinding.add("subject", ResourceFactory.createResource(subjectUri));
// Run the SPARQL query to get the properties // Run the SPARQL query to get the properties
DatasetWrapper w = dwf.getDatasetWrapper(); DatasetWrapper w = dwf.getDatasetWrapper();
@ -415,7 +417,7 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
dataset.getLock().enterCriticalSection(Lock.READ); dataset.getLock().enterCriticalSection(Lock.READ);
try { try {
QueryExecution qexec = QueryExecutionFactory.create( QueryExecution qexec = QueryExecutionFactory.create(
query, dataset, subjectBinding); query, dataset); //, subjectBinding);
try { try {
ResultSet rs = qexec.execSelect(); ResultSet rs = qexec.execSelect();
// consume iterator before wrapper w is closed in finally block // consume iterator before wrapper w is closed in finally block

View file

@ -61,7 +61,7 @@ public class CollatedObjectPropertyTemplateModel extends ObjectPropertyTemplateM
String subjectUri = subject.getURI(); String subjectUri = subject.getURI();
String propertyUri = op.getURI(); String propertyUri = op.getURI();
List<Map<String, String>> statementData = List<Map<String, String>> statementData =
opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, getSelectQuery(), getConstructQueries()); opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, getObjectKey(), getSelectQuery(), getConstructQueries());
/* Apply post-processing */ /* Apply post-processing */
postprocess(statementData, wdf); postprocess(statementData, wdf);

View file

@ -37,7 +37,7 @@ public class UncollatedObjectPropertyTemplateModel extends ObjectPropertyTemplat
String subjectUri = subject.getURI(); String subjectUri = subject.getURI();
String propertyUri = op.getURI(); String propertyUri = op.getURI();
List<Map<String, String>> statementData = List<Map<String, String>> statementData =
opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, getSelectQuery(), getConstructQueries()); opDao.getObjectPropertyStatementsForIndividualByProperty(subjectUri, propertyUri, getObjectKey(), getSelectQuery(), getConstructQueries());
/* Apply postprocessing */ /* Apply postprocessing */
postprocess(statementData, wdf); postprocess(statementData, wdf);