NIHVIVO-1228 NIHVIVO-3202 improved selection of editable properties: support for simple union domains and domain inheritance
This commit is contained in:
parent
fc4a22d292
commit
1ec081dcf3
4 changed files with 397 additions and 400 deletions
|
@ -45,6 +45,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
|
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
|
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstance;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
|
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
|
||||||
|
@ -310,107 +311,37 @@ public class DataPropertyDaoJena extends PropertyDaoJena implements
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DataProperty> getDatapropsForClass(String vclassURI) {
|
public List<DataProperty> getDatapropsForClass(String vclassURI) {
|
||||||
// TODO make this more efficient once we figure out our reasoner strategy
|
return filterAndConvertToDataProperties(getAllPropInstByVClass(vclassURI));
|
||||||
List<DataProperty> datapropsForClass = new ArrayList();
|
|
||||||
OntModel ontModel = getOntModelSelector().getTBoxModel();
|
|
||||||
try {
|
|
||||||
VClassDao vcDao = getWebappDaoFactory().getVClassDao();
|
|
||||||
HashSet<String> superclassURIs = new HashSet<String>(vcDao.getAllSuperClassURIs(vclassURI));
|
|
||||||
superclassURIs.add(vclassURI);
|
|
||||||
for (String equivURI : vcDao.getEquivalentClassURIs(vclassURI)) {
|
|
||||||
superclassURIs.add(equivURI);
|
|
||||||
superclassURIs.addAll(vcDao.getAllSuperClassURIs(equivURI));
|
|
||||||
}
|
|
||||||
Iterator superclassURIsIt = superclassURIs.iterator();
|
|
||||||
ontModel.enterCriticalSection(Lock.READ);
|
|
||||||
try {
|
|
||||||
Iterator dataprops = ontModel.listDatatypeProperties();
|
|
||||||
while (dataprops.hasNext()) {
|
|
||||||
Object nextObj = dataprops.next();
|
|
||||||
try {
|
|
||||||
com.hp.hpl.jena.ontology.OntProperty jDataprop = (com.hp.hpl.jena.ontology.OntProperty) nextObj;
|
|
||||||
Resource domainRes = jDataprop.getDomain();
|
|
||||||
if (domainRes != null && !NONUSER_NAMESPACES.contains(jDataprop.getNameSpace()) && superclassURIs.contains(domainRes.getURI())) {
|
|
||||||
datapropsForClass.add(datapropFromOntProperty(jDataprop));
|
|
||||||
}
|
|
||||||
// also check restrictions
|
|
||||||
for (Iterator restStmtIt = ontModel.listStatements(null,OWL.onProperty,jDataprop); restStmtIt.hasNext();) {
|
|
||||||
Statement restStmt = (Statement) restStmtIt.next();
|
|
||||||
Resource restRes = restStmt.getSubject();
|
|
||||||
for (Iterator axStmtIt = ontModel.listStatements(null,null,restRes); axStmtIt.hasNext();) {
|
|
||||||
Statement axStmt = (Statement) axStmtIt.next();
|
|
||||||
OntResource subjOntRes = null;
|
|
||||||
if (axStmt.getSubject().canAs(OntResource.class)) {
|
|
||||||
subjOntRes = (OntResource) axStmt.getSubject().as(OntResource.class);
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
( (subjOntRes!=null) && (superclassURIs.contains(getClassURIStr(subjOntRes))) ) &&
|
|
||||||
(axStmt.getPredicate().equals(RDFS.subClassOf) || (axStmt.getPredicate().equals(OWL.equivalentClass)))
|
|
||||||
) {
|
|
||||||
if (restRes.canAs(AllValuesFromRestriction.class) || restRes.canAs(SomeValuesFromRestriction.class)) {
|
|
||||||
datapropsForClass.add(datapropFromOntProperty(jDataprop));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
ontModel.leaveCriticalSection();
|
|
||||||
}
|
|
||||||
} catch (ProfileException pe) {
|
|
||||||
// TODO language profile doesn't support data properties.
|
|
||||||
// With RDFS, we might like to return properties with rdfs:range containing a datatype
|
|
||||||
}
|
|
||||||
Collections.sort(datapropsForClass, new DataPropertyRanker());
|
|
||||||
return datapropsForClass;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<DataProperty> getAllPossibleDatapropsForIndividual(String individualURI) {
|
public Collection<DataProperty> getAllPossibleDatapropsForIndividual(String individualURI) {
|
||||||
Individual ind = getWebappDaoFactory().getIndividualDao().getIndividualByURI(individualURI);
|
return filterAndConvertToDataProperties(getAllPossiblePropInstForIndividual(individualURI));
|
||||||
Collection<DataProperty> dpColl = new ArrayList<DataProperty>();
|
}
|
||||||
List<String> vclassURIs = getVClassURIs(ind);
|
|
||||||
|
private List<DataProperty> filterAndConvertToDataProperties(
|
||||||
try {
|
List<PropertyInstance> propInsts) {
|
||||||
for (VClass currClass : ind.getVClasses( DIRECT )) {
|
List<DataProperty> dataprops = new ArrayList<DataProperty>();
|
||||||
List<DataProperty> currList = getDatapropsForClass(currClass.getURI());
|
for (PropertyInstance propInst : propInsts) {
|
||||||
for (Iterator<DataProperty> dpIter = currList.iterator(); dpIter.hasNext();) {
|
OntModel tboxModel = getOntModel();
|
||||||
DataProperty dp = (DataProperty) dpIter.next();
|
tboxModel.enterCriticalSection(Lock.READ);
|
||||||
boolean addIt = true;
|
boolean add = false;
|
||||||
// some inefficient de-duping
|
try {
|
||||||
for (Iterator<DataProperty> existingIter = dpColl.iterator(); existingIter.hasNext(); ) {
|
add = (propInst.getPropertyURI() != null
|
||||||
DataProperty existingDp = (DataProperty) existingIter.next();
|
&& tboxModel.contains(
|
||||||
try {
|
tboxModel.getResource(
|
||||||
if (existingDp.getURI().equals(dp.getURI()) &&
|
propInst.getPropertyURI()),
|
||||||
existingDp.getDomainClassURI().equals(dp.getDomainClassURI()) &&
|
RDF.type,
|
||||||
existingDp.getRangeDatatypeURI().equals(dp.getRangeDatatypeURI())) {
|
OWL.DatatypeProperty));
|
||||||
addIt = false;
|
} finally {
|
||||||
}
|
tboxModel.leaveCriticalSection();
|
||||||
} catch (Exception e) { }
|
}
|
||||||
}
|
if (add) {
|
||||||
if (addIt) {
|
DataProperty dataprop = getDataPropertyByURI(propInst.getPropertyURI());
|
||||||
dpColl.add(dp);
|
dataprop.setRangeDatatypeURI(propInst.getRangeClassURI());
|
||||||
}
|
dataprops.add(dataprop);
|
||||||
}
|
}
|
||||||
// 2010-01-25 addition by BJL
|
}
|
||||||
// now change range datatype based on individual
|
return dataprops;
|
||||||
// TODO: rethink all these methods to reduce inefficiency
|
|
||||||
for (DataProperty dp : dpColl) {
|
|
||||||
dp.setRangeDatatypeURI(getRequiredDatatypeURI(ind, dp, vclassURIs));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (ProfileException pe) {
|
|
||||||
// TODO language profile doesn't support data properties.
|
|
||||||
// With RDFS, we might like to return properties with rdfs:range containing a datatype
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
for (DataProperty dp : dpColl) {
|
|
||||||
dp.setDomainClassURI(ind.getVClassURI()); // TODO: improve. This is so the DWR property editing passes the individual's VClass to get the right restrictions
|
|
||||||
}
|
|
||||||
Collections.sort(dpColl, new PropInstSorter()); */
|
|
||||||
return dpColl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean reasoningAvailable() {
|
protected boolean reasoningAvailable() {
|
||||||
|
|
|
@ -3,12 +3,16 @@
|
||||||
package edu.cornell.mannlib.vitro.webapp.dao.jena;
|
package edu.cornell.mannlib.vitro.webapp.dao.jena;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
@ -16,11 +20,15 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import com.hp.hpl.jena.ontology.OntClass;
|
import com.hp.hpl.jena.ontology.OntClass;
|
||||||
import com.hp.hpl.jena.ontology.OntModel;
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
import com.hp.hpl.jena.ontology.OntProperty;
|
import com.hp.hpl.jena.ontology.OntProperty;
|
||||||
|
import com.hp.hpl.jena.ontology.Restriction;
|
||||||
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.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.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;
|
||||||
import com.hp.hpl.jena.rdf.model.Statement;
|
import com.hp.hpl.jena.rdf.model.Statement;
|
||||||
|
@ -30,8 +38,10 @@ import com.hp.hpl.jena.sparql.resultset.ResultSetMem;
|
||||||
import com.hp.hpl.jena.vocabulary.OWL;
|
import com.hp.hpl.jena.vocabulary.OWL;
|
||||||
import com.hp.hpl.jena.vocabulary.RDFS;
|
import com.hp.hpl.jena.vocabulary.RDFS;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstance;
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
|
||||||
|
@ -431,4 +441,318 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
|
||||||
return rs;
|
return rs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* requires SPARQL 1.1 (or ARQ) property path support
|
||||||
|
* @param vclassURI
|
||||||
|
* @return list of property resources with union domains that include the vclass
|
||||||
|
*/
|
||||||
|
protected List<Resource> getPropertiesWithAppropriateDomainFor(String vclassURI) {
|
||||||
|
List<Resource> propertyResList = new ArrayList<Resource>();
|
||||||
|
String queryStr =
|
||||||
|
"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \n" +
|
||||||
|
"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
|
||||||
|
"PREFIX owl: <http://www.w3.org/2002/07/owl#> \n\n " +
|
||||||
|
"SELECT ?p WHERE { \n" +
|
||||||
|
" { \n" +
|
||||||
|
" ?p rdfs:domain <" + vclassURI + "> . \n" +
|
||||||
|
" } UNION { \n" +
|
||||||
|
" ?parent rdfs:domain <" + vclassURI + "> . \n" +
|
||||||
|
" ?p rdfs:subPropertyOf* ?parent. \n" +
|
||||||
|
" OPTIONAL { \n" +
|
||||||
|
" ?p rdfs:domain ?childDomain \n" +
|
||||||
|
" } \n" +
|
||||||
|
" FILTER (!bound(?childDomain)) \n" +
|
||||||
|
" } UNION { \n" +
|
||||||
|
" ?f rdf:first <" + vclassURI + "> . \n" +
|
||||||
|
" ?u rdf:rest* ?f . \n" +
|
||||||
|
" ?d owl:unionOf ?u . \n" +
|
||||||
|
" ?p rdfs:domain ?d . \n" +
|
||||||
|
" } UNION { \n" +
|
||||||
|
" ?f rdf:first <" + vclassURI + "> . \n" +
|
||||||
|
" ?u rdf:rest* ?f . \n" +
|
||||||
|
" ?d owl:unionOf ?u . \n" +
|
||||||
|
" ?parent rdfs:domain ?d . \n" +
|
||||||
|
" ?p rdfs:subPropertyOf* ?parent. \n" +
|
||||||
|
" OPTIONAL { \n" +
|
||||||
|
" ?p rdfs:domain ?childDomain \n" +
|
||||||
|
" } \n" +
|
||||||
|
" FILTER (!bound(?childDomain)) \n" +
|
||||||
|
" } \n" +
|
||||||
|
" FILTER(?p != owl:bottomDataProperty \n" +
|
||||||
|
" && ?p != owl:bottomObjectProperty) \n" +
|
||||||
|
"}";
|
||||||
|
log.info(queryStr);
|
||||||
|
Query q = QueryFactory.create(queryStr, Syntax.syntaxSPARQL_11);
|
||||||
|
QueryExecution qe = QueryExecutionFactory.create(
|
||||||
|
q, getOntModelSelector().getTBoxModel());
|
||||||
|
try {
|
||||||
|
ResultSet rs = qe.execSelect();
|
||||||
|
while (rs.hasNext()) {
|
||||||
|
QuerySolution qs = rs.nextSolution();
|
||||||
|
propertyResList.add(qs.getResource("p"));
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
qe.close();
|
||||||
|
}
|
||||||
|
return propertyResList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PropertyInstance> getAllPossiblePropInstForIndividual(String individualURI) {
|
||||||
|
Individual ind = getWebappDaoFactory().getIndividualDao().getIndividualByURI(individualURI);
|
||||||
|
VClassDao vcDao = getWebappDaoFactory().getVClassDao();
|
||||||
|
|
||||||
|
List<VClass> allTypes = ind.getVClasses(false); // include indirect types
|
||||||
|
|
||||||
|
Set<String> allSuperclassURIs = new HashSet<String>();
|
||||||
|
|
||||||
|
for (VClass type : allTypes) {
|
||||||
|
String classURI = type.getURI();
|
||||||
|
if (classURI != null) {
|
||||||
|
allSuperclassURIs.add(type.getURI());
|
||||||
|
}
|
||||||
|
for (String equivURI : vcDao.getEquivalentClassURIs(classURI)) {
|
||||||
|
allSuperclassURIs.add(equivURI);
|
||||||
|
allSuperclassURIs.addAll(vcDao.getAllSuperClassURIs(equivURI));
|
||||||
|
}
|
||||||
|
allSuperclassURIs.addAll(vcDao.getAllSuperClassURIs(classURI));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<VClass> vclasses = new ArrayList<VClass>();
|
||||||
|
for(String vclassURI : allSuperclassURIs) {
|
||||||
|
VClass vclass = vcDao.getVClassByURI(vclassURI);
|
||||||
|
if (vclass != null) {
|
||||||
|
vclasses.add(vclass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<PropertyInstance> piList = getAllPropInstByVClasses(vclasses);
|
||||||
|
|
||||||
|
for (PropertyInstance pi : piList) {
|
||||||
|
pi.setDomainClassURI(ind.getVClassURI());
|
||||||
|
// TODO: improve. This is so the DWR property editing passes the
|
||||||
|
// individual's VClass to get the right restrictions
|
||||||
|
}
|
||||||
|
|
||||||
|
return piList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sorts VClasses so that subclasses come before superclasses
|
||||||
|
*/
|
||||||
|
private class VClassHierarchyRanker implements Comparator<VClass> {
|
||||||
|
private VClassDao vcDao;
|
||||||
|
public VClassHierarchyRanker(VClassDao vcDao) {
|
||||||
|
this.vcDao = vcDao;
|
||||||
|
}
|
||||||
|
public int compare(VClass vc1, VClass vc2) {
|
||||||
|
if (vcDao.isSubClassOf(vc1, vc2)) {
|
||||||
|
return -1;
|
||||||
|
} else if (vcDao.isSubClassOf(vc2, vc1)) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<PropertyInstance> getAllPropInstByVClass(String classURI) {
|
||||||
|
if (classURI==null || classURI.length()<1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
VClassDao vcDao = getWebappDaoFactory().getVClassDao();
|
||||||
|
|
||||||
|
Set<String> allSuperclassURIs = new HashSet<String>();
|
||||||
|
|
||||||
|
allSuperclassURIs.add(classURI);
|
||||||
|
for (String equivURI : vcDao.getEquivalentClassURIs(classURI)) {
|
||||||
|
allSuperclassURIs.add(equivURI);
|
||||||
|
allSuperclassURIs.addAll(vcDao.getAllSuperClassURIs(equivURI));
|
||||||
|
}
|
||||||
|
allSuperclassURIs.addAll(vcDao.getAllSuperClassURIs(classURI));
|
||||||
|
|
||||||
|
List<VClass> vclasses = new ArrayList<VClass>();
|
||||||
|
for(String vclassURI : allSuperclassURIs) {
|
||||||
|
VClass vclass = vcDao.getVClassByURI(vclassURI);
|
||||||
|
if (vclass != null) {
|
||||||
|
vclasses.add(vclass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return getAllPropInstByVClasses(vclasses);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updatePropertyRangeMap(Map<String, Resource[]> map,
|
||||||
|
String propURI,
|
||||||
|
Resource[] ranges) {
|
||||||
|
Resource[] existingRanges = map.get(propURI);
|
||||||
|
if (existingRanges == null) {
|
||||||
|
map.put(propURI, ranges);
|
||||||
|
} else if (existingRanges[0] == null && existingRanges[1] != null) {
|
||||||
|
existingRanges[0] = ranges[0];
|
||||||
|
map.put(propURI, existingRanges);
|
||||||
|
} else if (existingRanges[0] != null && existingRanges[1] == null) {
|
||||||
|
existingRanges[1] = ranges[1];
|
||||||
|
map.put(propURI, existingRanges);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PropertyInstance> getAllPropInstByVClasses(List<VClass> vclasses) {
|
||||||
|
|
||||||
|
List<PropertyInstance> propInsts = new ArrayList<PropertyInstance>();
|
||||||
|
|
||||||
|
if(vclasses == null || vclasses.isEmpty()) {
|
||||||
|
return propInsts;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collections.sort(vclasses, new VClassHierarchyRanker(this.getWebappDaoFactory().getVClassDao()));
|
||||||
|
|
||||||
|
OntModel ontModel = getOntModelSelector().getTBoxModel();
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
ontModel.enterCriticalSection(Lock.READ);
|
||||||
|
|
||||||
|
// map object property URI to an array of two resources:
|
||||||
|
// the first is the "allValuesFrom" resource and the second is
|
||||||
|
// "someValuesFrom"
|
||||||
|
Map<String, Resource[]> applicableProperties =
|
||||||
|
new HashMap<String, Resource[]>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (VClass vclass : vclasses) {
|
||||||
|
if (vclass.isAnonymous()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String VClassURI = vclass.getURI();
|
||||||
|
|
||||||
|
OntClass ontClass = getOntClass(ontModel,VClassURI);
|
||||||
|
if (ontClass != null) {
|
||||||
|
List<OntClass> relatedClasses = new ArrayList<OntClass>();
|
||||||
|
relatedClasses.addAll(ontClass.listEquivalentClasses().toList());
|
||||||
|
relatedClasses.addAll(ontClass.listSuperClasses().toList());
|
||||||
|
for (OntClass relatedClass : relatedClasses) {
|
||||||
|
// find properties in restrictions
|
||||||
|
if (relatedClass.isRestriction()) {
|
||||||
|
// TODO: check if restriction is something like
|
||||||
|
// maxCardinality 0 or allValuesFrom owl:Nothing,
|
||||||
|
// in which case the property is NOT applicable!
|
||||||
|
Restriction rest = (Restriction) relatedClass.as(Restriction.class);
|
||||||
|
OntProperty onProperty = rest.getOnProperty();
|
||||||
|
if (onProperty != null) {
|
||||||
|
Resource[] ranges = new Resource[2];
|
||||||
|
if (rest.isAllValuesFromRestriction()) {
|
||||||
|
ranges[0] = (rest.asAllValuesFromRestriction()).getAllValuesFrom();
|
||||||
|
} else if (rest.isSomeValuesFromRestriction()) {
|
||||||
|
ranges[1] = (rest.asSomeValuesFromRestriction()).getSomeValuesFrom();
|
||||||
|
}
|
||||||
|
updatePropertyRangeMap(applicableProperties, onProperty.getURI(), ranges);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Resource> propertyList =
|
||||||
|
getPropertiesWithAppropriateDomainFor(VClassURI);
|
||||||
|
for (Resource prop : propertyList) {
|
||||||
|
if (prop.getNameSpace() != null
|
||||||
|
&& !NONUSER_NAMESPACES.contains(
|
||||||
|
prop.getNameSpace()) ) {
|
||||||
|
StmtIterator rangeSit = prop.listProperties(
|
||||||
|
RDFS.range);
|
||||||
|
Resource rangeRes = null;
|
||||||
|
while (rangeSit.hasNext()) {
|
||||||
|
Statement s = rangeSit.nextStatement();
|
||||||
|
if (s.getObject().isURIResource()) {
|
||||||
|
rangeRes = (Resource) s.getObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Resource[] ranges = new Resource[2];
|
||||||
|
ranges[0] = rangeRes;
|
||||||
|
updatePropertyRangeMap(
|
||||||
|
applicableProperties, prop.getURI(), ranges);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Unable to get applicable properties " +
|
||||||
|
"by examining property restrictions and domains", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// make the PropertyInstance objects
|
||||||
|
for (String propertyURI : applicableProperties.keySet()) {
|
||||||
|
OntProperty op = ontModel
|
||||||
|
.getOntProperty(propertyURI);
|
||||||
|
if (op == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String domainURIStr = getURIStr(op.getDomain());
|
||||||
|
Resource[] foundRanges = applicableProperties.get(propertyURI);
|
||||||
|
Resource rangeRes = (foundRanges[0] != null)
|
||||||
|
? foundRanges[0]
|
||||||
|
: (op.getRange() == null && foundRanges[1] != null)
|
||||||
|
? foundRanges[1]
|
||||||
|
: op.getRange();
|
||||||
|
PropertyInstance pi = new PropertyInstance();
|
||||||
|
if (rangeRes != null) {
|
||||||
|
String rangeClassURI;
|
||||||
|
if (rangeRes.isAnon()) {
|
||||||
|
rangeClassURI = PSEUDO_BNODE_NS + rangeRes.getId()
|
||||||
|
.toString();
|
||||||
|
} else {
|
||||||
|
rangeClassURI = (String) rangeRes.getURI();
|
||||||
|
}
|
||||||
|
pi.setRangeClassURI(rangeClassURI);
|
||||||
|
VClass range = getWebappDaoFactory().getVClassDao()
|
||||||
|
.getVClassByURI(rangeClassURI);
|
||||||
|
if (range == null) {
|
||||||
|
range = new VClass();
|
||||||
|
range.setURI(rangeClassURI);
|
||||||
|
range.setName(range.getLocalName());
|
||||||
|
}
|
||||||
|
pi.setRangeClassName(range.getName());
|
||||||
|
} else {
|
||||||
|
pi.setRangeClassURI(OWL.Thing.getURI()); // TODO see above
|
||||||
|
}
|
||||||
|
pi.setDomainClassURI(domainURIStr);
|
||||||
|
VClass domain = getWebappDaoFactory().getVClassDao()
|
||||||
|
.getVClassByURI(domainURIStr);
|
||||||
|
if (domain == null) {
|
||||||
|
domain = new VClass();
|
||||||
|
domain.setURI(domainURIStr);
|
||||||
|
domain.setName(domain.getLocalName());
|
||||||
|
}
|
||||||
|
pi.setDomainClassName(domain.getName());
|
||||||
|
pi.setSubjectSide(true);
|
||||||
|
pi.setPropertyURI(op.getURI());
|
||||||
|
pi.setPropertyName(getLabelOrId(op)); // TODO
|
||||||
|
pi.setRangePublic(getLabelOrId(op));
|
||||||
|
pi.setDomainPublic(getLabelOrId(op));
|
||||||
|
propInsts.add(pi);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
ontModel.leaveCriticalSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
return propInsts;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getURIStr(Resource res) {
|
||||||
|
String URIStr;
|
||||||
|
if (res == null) {
|
||||||
|
URIStr = OWL.Thing.getURI(); // TODO: rdf:Resource if using RDF model; or option to turn off entirely
|
||||||
|
} else {
|
||||||
|
if (res.isAnon()) {
|
||||||
|
URIStr = PSEUDO_BNODE_NS+res.getId().toString();
|
||||||
|
} else {
|
||||||
|
URIStr = res.getURI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return URIStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,21 +19,14 @@ import com.hp.hpl.jena.ontology.OntClass;
|
||||||
import com.hp.hpl.jena.ontology.OntModel;
|
import com.hp.hpl.jena.ontology.OntModel;
|
||||||
import com.hp.hpl.jena.ontology.OntProperty;
|
import com.hp.hpl.jena.ontology.OntProperty;
|
||||||
import com.hp.hpl.jena.ontology.Restriction;
|
import com.hp.hpl.jena.ontology.Restriction;
|
||||||
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.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.ResIterator;
|
|
||||||
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.rdf.model.StmtIterator;
|
||||||
import com.hp.hpl.jena.shared.Lock;
|
import com.hp.hpl.jena.shared.Lock;
|
||||||
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.RDFS;
|
import com.hp.hpl.jena.vocabulary.RDFS;
|
||||||
|
|
||||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||||
|
@ -45,11 +38,11 @@ import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
|
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualDeletionEvent;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualDeletionEvent;
|
||||||
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualUpdateEvent;
|
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.IndividualUpdateEvent;
|
||||||
public class PropertyInstanceDaoJena extends JenaBaseDao implements
|
public class PropertyInstanceDaoJena extends PropertyDaoJena implements
|
||||||
PropertyInstanceDao {
|
PropertyInstanceDao {
|
||||||
|
|
||||||
public PropertyInstanceDaoJena(WebappDaoFactoryJena wadf) {
|
public PropertyInstanceDaoJena(DatasetWrapperFactory dwf, WebappDaoFactoryJena wadf) {
|
||||||
super(wadf);
|
super(dwf, wadf);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteObjectPropertyStatement(String subjectURI, String propertyURI, String objectURI) {
|
public void deleteObjectPropertyStatement(String subjectURI, String propertyURI, String objectURI) {
|
||||||
|
@ -98,299 +91,48 @@ public class PropertyInstanceDaoJena extends JenaBaseDao implements
|
||||||
ontModel.leaveCriticalSection();
|
ontModel.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<PropertyInstance> getAllPossiblePropInstForIndividual(String individualURI) {
|
@Override
|
||||||
Individual ind = getWebappDaoFactory().getIndividualDao().getIndividualByURI(individualURI);
|
public List<PropertyInstance> getAllPossiblePropInstForIndividual(String individualURI) {
|
||||||
VClassDao vcDao = getWebappDaoFactory().getVClassDao();
|
return filterAndSort(super.getAllPossiblePropInstForIndividual(individualURI));
|
||||||
|
}
|
||||||
List<VClass> allTypes = ind.getVClasses(false); // include indirect types
|
|
||||||
|
@Override
|
||||||
Set<String> allSuperclassURIs = new HashSet<String>();
|
public List<PropertyInstance> getAllPropInstByVClass(String vclassURI) {
|
||||||
|
return filterAndSort(super.getAllPropInstByVClass(vclassURI));
|
||||||
for (VClass type : allTypes) {
|
}
|
||||||
String classURI = type.getURI();
|
|
||||||
if (classURI != null) {
|
@Override
|
||||||
allSuperclassURIs.add(type.getURI());
|
public List<PropertyInstance> getAllPropInstByVClasses(List<VClass> vclasses) {
|
||||||
}
|
return filterAndSort(super.getAllPropInstByVClasses(vclasses));
|
||||||
for (String equivURI : vcDao.getEquivalentClassURIs(classURI)) {
|
}
|
||||||
allSuperclassURIs.add(equivURI);
|
|
||||||
allSuperclassURIs.addAll(vcDao.getAllSuperClassURIs(equivURI));
|
private List<PropertyInstance>filterAndSort(List<PropertyInstance> propList) {
|
||||||
}
|
ArrayList<PropertyInstance> propInsts = new ArrayList<PropertyInstance>();
|
||||||
allSuperclassURIs.addAll(vcDao.getAllSuperClassURIs(classURI));
|
for (PropertyInstance propInst : propList) {
|
||||||
}
|
OntModel tboxModel = getOntModel();
|
||||||
|
tboxModel.enterCriticalSection(Lock.READ);
|
||||||
List<VClass> vclasses = new ArrayList<VClass>();
|
boolean add = false;
|
||||||
for(String vclassURI : allSuperclassURIs) {
|
try {
|
||||||
VClass vclass = vcDao.getVClassByURI(vclassURI);
|
add = (propInst.getPropertyURI() != null
|
||||||
if (vclass != null) {
|
&& tboxModel.contains(
|
||||||
vclasses.add(vclass);
|
tboxModel.getResource(
|
||||||
}
|
propInst.getPropertyURI()),
|
||||||
}
|
RDF.type,
|
||||||
|
OWL.ObjectProperty));
|
||||||
Collection<PropertyInstance> piList = getAllPropInstByVClasses(vclasses);
|
} finally {
|
||||||
|
tboxModel.leaveCriticalSection();
|
||||||
for (PropertyInstance pi : piList) {
|
}
|
||||||
pi.setDomainClassURI(ind.getVClassURI());
|
if (add) {
|
||||||
// TODO: improve. This is so the DWR property editing passes the
|
propInsts.add(propInst);
|
||||||
// individual's VClass to get the right restrictions
|
}
|
||||||
}
|
}
|
||||||
|
Collections.sort(propInsts, new PropInstSorter());
|
||||||
return piList;
|
return propInsts;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* sorts VClasses so that subclasses come before superclasses
|
|
||||||
*/
|
|
||||||
private class VClassHierarchyRanker implements Comparator<VClass> {
|
|
||||||
private VClassDao vcDao;
|
|
||||||
public VClassHierarchyRanker(VClassDao vcDao) {
|
|
||||||
this.vcDao = vcDao;
|
|
||||||
}
|
|
||||||
public int compare(VClass vc1, VClass vc2) {
|
|
||||||
if (vcDao.isSubClassOf(vc1, vc2)) {
|
|
||||||
return -1;
|
|
||||||
} else if (vcDao.isSubClassOf(vc2, vc1)) {
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Collection<PropertyInstance> getAllPropInstByVClass(String classURI) {
|
|
||||||
if (classURI==null || classURI.length()<1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
VClassDao vcDao = getWebappDaoFactory().getVClassDao();
|
|
||||||
|
|
||||||
Set<String> allSuperclassURIs = new HashSet<String>();
|
|
||||||
|
|
||||||
allSuperclassURIs.add(classURI);
|
|
||||||
for (String equivURI : vcDao.getEquivalentClassURIs(classURI)) {
|
|
||||||
allSuperclassURIs.add(equivURI);
|
|
||||||
allSuperclassURIs.addAll(vcDao.getAllSuperClassURIs(equivURI));
|
|
||||||
}
|
|
||||||
allSuperclassURIs.addAll(vcDao.getAllSuperClassURIs(classURI));
|
|
||||||
|
|
||||||
List<VClass> vclasses = new ArrayList<VClass>();
|
|
||||||
for(String vclassURI : allSuperclassURIs) {
|
|
||||||
VClass vclass = vcDao.getVClassByURI(vclassURI);
|
|
||||||
if (vclass != null) {
|
|
||||||
vclasses.add(vclass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return getAllPropInstByVClasses(vclasses);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updatePropertyRangeMap(Map<String, Resource[]> map,
|
|
||||||
String propURI,
|
|
||||||
Resource[] ranges) {
|
|
||||||
Resource[] existingRanges = map.get(propURI);
|
|
||||||
if (existingRanges == null) {
|
|
||||||
map.put(propURI, ranges);
|
|
||||||
} else if (existingRanges[0] == null && existingRanges[1] != null) {
|
|
||||||
existingRanges[0] = ranges[0];
|
|
||||||
map.put(propURI, existingRanges);
|
|
||||||
} else if (existingRanges[0] != null && existingRanges[1] == null) {
|
|
||||||
existingRanges[1] = ranges[1];
|
|
||||||
map.put(propURI, existingRanges);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<PropertyInstance> getAllPropInstByVClasses(List<VClass> vclasses) {
|
|
||||||
|
|
||||||
List<PropertyInstance> propInsts = new ArrayList<PropertyInstance>();
|
|
||||||
|
|
||||||
if(vclasses == null || vclasses.isEmpty()) {
|
|
||||||
return propInsts;
|
|
||||||
}
|
|
||||||
|
|
||||||
Collections.sort(vclasses, new VClassHierarchyRanker(this.getWebappDaoFactory().getVClassDao()));
|
|
||||||
|
|
||||||
OntModel ontModel = getOntModelSelector().getTBoxModel();
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
ontModel.enterCriticalSection(Lock.READ);
|
|
||||||
|
|
||||||
// map object property URI to an array of two resources:
|
|
||||||
// the first is the "allValuesFrom" resource and the second is
|
|
||||||
// "someValuesFrom"
|
|
||||||
Map<String, Resource[]> applicableProperties =
|
|
||||||
new HashMap<String, Resource[]>();
|
|
||||||
|
|
||||||
try {
|
|
||||||
for (VClass vclass : vclasses) {
|
|
||||||
if (vclass.isAnonymous()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String VClassURI = vclass.getURI();
|
|
||||||
|
|
||||||
OntClass ontClass = getOntClass(ontModel,VClassURI);
|
|
||||||
if (ontClass != null) {
|
|
||||||
List<OntClass> relatedClasses = new ArrayList<OntClass>();
|
|
||||||
relatedClasses.addAll(ontClass.listEquivalentClasses().toList());
|
|
||||||
relatedClasses.addAll(ontClass.listSuperClasses().toList());
|
|
||||||
for (OntClass relatedClass : relatedClasses) {
|
|
||||||
// find properties in restrictions
|
|
||||||
if (relatedClass.isRestriction()) {
|
|
||||||
// TODO: check if restriction is something like
|
|
||||||
// maxCardinality 0 or allValuesFrom owl:Nothing,
|
|
||||||
// in which case the property is NOT applicable!
|
|
||||||
Restriction rest = (Restriction) relatedClass.as(Restriction.class);
|
|
||||||
OntProperty onProperty = rest.getOnProperty();
|
|
||||||
if (onProperty != null && onProperty.canAs(ObjectProperty.class)) {
|
|
||||||
Resource[] ranges = new Resource[2];
|
|
||||||
if (rest.isAllValuesFromRestriction()) {
|
|
||||||
ranges[0] = (rest.asAllValuesFromRestriction()).getAllValuesFrom();
|
|
||||||
} else if (rest.isSomeValuesFromRestriction()) {
|
|
||||||
ranges[1] = (rest.asSomeValuesFromRestriction()).getSomeValuesFrom();
|
|
||||||
}
|
|
||||||
updatePropertyRangeMap(applicableProperties, onProperty.getURI(), ranges);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Resource> propertyList = new ArrayList<Resource>();
|
|
||||||
// find properties with class in domain
|
|
||||||
ResIterator pit = ontModel.listSubjectsWithProperty(
|
|
||||||
RDFS.domain, ontClass);
|
|
||||||
while (pit.hasNext()) {
|
|
||||||
Resource prop = pit.nextResource();
|
|
||||||
propertyList.add(prop);
|
|
||||||
}
|
|
||||||
propertyList.addAll(
|
|
||||||
getPropertiesWithUnionDomainIncluding(VClassURI));
|
|
||||||
for (Resource prop : propertyList) {
|
|
||||||
if (prop.getNameSpace() != null
|
|
||||||
&& !NONUSER_NAMESPACES.contains(
|
|
||||||
prop.getNameSpace()) ) {
|
|
||||||
StmtIterator rangeSit = prop.listProperties(
|
|
||||||
RDFS.range);
|
|
||||||
Resource rangeRes = null;
|
|
||||||
while (rangeSit.hasNext()) {
|
|
||||||
Statement s = rangeSit.nextStatement();
|
|
||||||
if (s.getObject().isURIResource()) {
|
|
||||||
rangeRes = (Resource) s.getObject();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Resource[] ranges = new Resource[2];
|
|
||||||
ranges[0] = rangeRes;
|
|
||||||
updatePropertyRangeMap(
|
|
||||||
applicableProperties, prop.getURI(), ranges);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Unable to get applicable properties " +
|
|
||||||
"by examining property restrictions and domains", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// make the PropertyInstance objects
|
|
||||||
for (String propertyURI : applicableProperties.keySet()) {
|
|
||||||
ObjectProperty op = ontModel.getObjectProperty(propertyURI);
|
|
||||||
if (op == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String domainURIStr = getURIStr(op.getDomain());
|
|
||||||
Resource[] foundRanges = applicableProperties.get(propertyURI);
|
|
||||||
Resource rangeRes = (foundRanges[0] != null)
|
|
||||||
? foundRanges[0]
|
|
||||||
: (op.getRange() == null && foundRanges[1] != null)
|
|
||||||
? foundRanges[1]
|
|
||||||
: op.getRange();
|
|
||||||
PropertyInstance pi = new PropertyInstance();
|
|
||||||
if (rangeRes != null) {
|
|
||||||
String rangeClassURI;
|
|
||||||
if (rangeRes.isAnon()) {
|
|
||||||
rangeClassURI = PSEUDO_BNODE_NS+rangeRes.getId().toString();
|
|
||||||
} else {
|
|
||||||
rangeClassURI = (String) rangeRes.getURI();
|
|
||||||
}
|
|
||||||
pi.setRangeClassURI(rangeClassURI);
|
|
||||||
try {
|
|
||||||
pi.setRangeClassName(getWebappDaoFactory().getVClassDao().getVClassByURI(rangeClassURI).getName());
|
|
||||||
//pi.setRangeClassName(getLabel(getOntModel().getOntResource(rangeClassURI)));
|
|
||||||
} catch (NullPointerException e) {/* probably a union or intersection - need to handle this somehow */}
|
|
||||||
} else {
|
|
||||||
pi.setRangeClassURI(OWL.Thing.getURI()); // TODO see above
|
|
||||||
}
|
|
||||||
pi.setDomainClassURI(domainURIStr);
|
|
||||||
try {
|
|
||||||
pi.setDomainClassName(getWebappDaoFactory().getVClassDao().getVClassByURI(domainURIStr).getName());
|
|
||||||
//pi.setDomainClassName(getLabel(getOntModel().getOntResource(op.getDomain().getURI())));
|
|
||||||
} catch (NullPointerException e) {/* probably a union or intersection - need to handle this somehow */}
|
|
||||||
pi.setSubjectSide(true);
|
|
||||||
pi.setPropertyURI(op.getURI());
|
|
||||||
pi.setPropertyName(getLabelOrId(op)); // TODO
|
|
||||||
pi.setRangePublic(getLabelOrId(op));
|
|
||||||
pi.setDomainPublic(getLabelOrId(op));
|
|
||||||
propInsts.add(pi);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
ontModel.leaveCriticalSection();
|
|
||||||
}
|
|
||||||
|
|
||||||
Collections.sort(propInsts, new PropInstSorter());
|
|
||||||
return propInsts;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private class PropInstSorter implements Comparator<PropertyInstance> {
|
||||||
* requires SPARQL 1.1 (or ARQ) property path support
|
public int compare (PropertyInstance pi1, PropertyInstance pi2) {
|
||||||
* @param vclassURI
|
|
||||||
* @return list of property resources with union domains that include the vclass
|
|
||||||
*/
|
|
||||||
private List<Resource> getPropertiesWithUnionDomainIncluding(String vclassURI) {
|
|
||||||
List<Resource> propertyResList = new ArrayList<Resource>();
|
|
||||||
String queryStr =
|
|
||||||
"PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> \n" +
|
|
||||||
"PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
|
|
||||||
"PREFIX owl: <http://www.w3.org/2002/07/owl#> \n\n " +
|
|
||||||
"SELECT ?p WHERE { \n" +
|
|
||||||
" ?f rdf:first <" + vclassURI + "> . \n" +
|
|
||||||
" ?u rdf:rest* ?f . \n" +
|
|
||||||
" ?d owl:unionOf ?u . \n" +
|
|
||||||
" ?p rdfs:domain ?d . \n" +
|
|
||||||
"}";
|
|
||||||
Query q = QueryFactory.create(queryStr, Syntax.syntaxSPARQL_11);
|
|
||||||
QueryExecution qe = QueryExecutionFactory.create(
|
|
||||||
q, getOntModelSelector().getTBoxModel());
|
|
||||||
try {
|
|
||||||
ResultSet rs = qe.execSelect();
|
|
||||||
while (rs.hasNext()) {
|
|
||||||
QuerySolution qs = rs.nextSolution();
|
|
||||||
propertyResList.add(qs.getResource("p"));
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
qe.close();
|
|
||||||
}
|
|
||||||
return propertyResList;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getURIStr(Resource res) {
|
|
||||||
String URIStr;
|
|
||||||
if (res == null) {
|
|
||||||
URIStr = OWL.Thing.getURI(); // TODO: rdf:Resource if using RDF model; or option to turn off entirely
|
|
||||||
} else {
|
|
||||||
if (res.isAnon()) {
|
|
||||||
URIStr = PSEUDO_BNODE_NS+res.getId().toString();
|
|
||||||
} else {
|
|
||||||
URIStr = res.getURI();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return URIStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class PropInstSorter implements Comparator {
|
|
||||||
public int compare (Object o1, Object o2) {
|
|
||||||
PropertyInstance pi1 = (PropertyInstance) o1;
|
|
||||||
PropertyInstance pi2 = (PropertyInstance) o2;
|
|
||||||
try {
|
try {
|
||||||
if (pi1.getDomainPublic().equals(pi2.getDomainPublic())) {
|
if (pi1.getDomainPublic().equals(pi2.getDomainPublic())) {
|
||||||
return pi1.getRangeClassName().compareTo(pi2.getRangeClassName());
|
return pi1.getRangeClassName().compareTo(pi2.getRangeClassName());
|
||||||
|
|
|
@ -536,7 +536,7 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
|
||||||
private PropertyInstanceDao propertyInstanceDao = null;
|
private PropertyInstanceDao propertyInstanceDao = null;
|
||||||
public PropertyInstanceDao getPropertyInstanceDao() {
|
public PropertyInstanceDao getPropertyInstanceDao() {
|
||||||
if( propertyInstanceDao == null )
|
if( propertyInstanceDao == null )
|
||||||
propertyInstanceDao = new PropertyInstanceDaoJena(this);
|
propertyInstanceDao = new PropertyInstanceDaoJena(dwf, this);
|
||||||
return propertyInstanceDao;
|
return propertyInstanceDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue