Faux data properties and fixes for current faux properties view (#352)

* Faux data properties

* Use not disjointed classes for faux properties domain and range options

* Fix faux object property shadowing real property
List faux data properties
List faux properties which base properties domain don't match current subject

* Write exception to log in VClassDaoJena

* filter faux properties returned in possiblePropInstForIndividual

* safety checks added

* extracted getBaseLabel method, fixed base labels for data properties

* fix for prev commit

* Formatting fixes

* More formatting fixes

* More formatting fixes

* More formatting fixes

* More formatting fixes

* More formatting fixes

Co-authored-by: Georgy Litvinov <georgy.litvinov@tib.eu>
This commit is contained in:
Georgy Litvinov 2022-12-16 11:40:49 +01:00 committed by GitHub
parent c885162d8d
commit a0a1a6664b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 1088 additions and 368 deletions

View file

@ -6,8 +6,6 @@ import java.lang.reflect.Method;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -17,6 +15,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -272,6 +271,37 @@ public class FormUtils {
return options; return options;
} }
public static List<Option> makeOptionListOfNotDisjointClasses(WebappDaoFactory wadf, String baseVclassUri, String selectedUri) {
VClassDao vClassDao = wadf.getVClassDao();
Set<String> uris = getNotDisjointClassUris(wadf, baseVclassUri, vClassDao);
uris.add(baseVclassUri);
List<Option> options = new LinkedList<>();
for (String vclassUri : uris) {
VClass vclass = vClassDao.getVClassByURI(vclassUri);
Option option = new Option();
option.setValue(vclass.getURI());
option.setBody(vclass.getPickListName());
options.add(option);
if (Objects.equals(selectedUri, vclass.getURI())) {
option.setSelected(true);
}
}
options.sort((o1, o2) -> o1.getBody().compareTo(o2.getBody()));
return options;
}
private static Set<String> getNotDisjointClassUris(WebappDaoFactory wadf, String classUri, VClassDao vClassDao) {
Set<String> allClasses = wadf.getVClassDao()
.getAllVclasses()
.stream()
.map(vclass -> vclass.getURI())
.collect(Collectors.toSet());
Set<String> disjointClasses = new HashSet<>(vClassDao.getDisjointWithClassURIs(classUri));
allClasses.removeAll(disjointClasses);
return allClasses;
}
public static void beanSet(Object newObj, String field, String value) { public static void beanSet(Object newObj, String field, String value) {
beanSet (newObj, field, value, null); beanSet (newObj, field, value, null);
} }

View file

@ -88,6 +88,11 @@ public class DataProperty extends Property implements Comparable<DataProperty>,
return rangeDatatypeURI; return rangeDatatypeURI;
} }
@Override
public String getRangeVClassURI() {
return rangeDatatypeURI;
}
public void setRangeDatatypeURI(String rangeDatatypeURI) { public void setRangeDatatypeURI(String rangeDatatypeURI) {
this.rangeDatatypeURI = rangeDatatypeURI; this.rangeDatatypeURI = rangeDatatypeURI;
} }

View file

@ -6,6 +6,8 @@ import static org.apache.jena.rdf.model.ResourceFactory.createResource;
import java.util.Objects; import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty; import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty;
/** /**
@ -20,7 +22,7 @@ public class FauxProperty extends BaseResourceBean implements ResourceBean,
private String configUri; private String configUri;
// Must not be null on insert or update. Partial identifier on delete. // Must not be null on insert or update. Partial identifier on delete.
private String rangeURI; private String rangeURI = "";
// May be null. Partial identifier on delete. // May be null. Partial identifier on delete.
private String domainURI; private String domainURI;
@ -55,7 +57,7 @@ public class FauxProperty extends BaseResourceBean implements ResourceBean,
*/ */
public FauxProperty(String domainURI, String baseURI, String rangeURI) { public FauxProperty(String domainURI, String baseURI, String rangeURI) {
super(Objects.requireNonNull(baseURI, "baseURI may not be null")); super(Objects.requireNonNull(baseURI, "baseURI may not be null"));
this.rangeURI = rangeURI; this.setRangeURI(rangeURI);
this.domainURI = domainURI; this.domainURI = domainURI;
} }
@ -93,7 +95,11 @@ public class FauxProperty extends BaseResourceBean implements ResourceBean,
} }
public void setRangeURI(String rangeURI) { public void setRangeURI(String rangeURI) {
this.rangeURI = rangeURI; if (StringUtils.isEmpty(rangeURI)) {
this.rangeURI = "";
} else {
this.rangeURI = rangeURI;
}
} }
public String getBaseLabel() { public String getBaseLabel() {
@ -105,7 +111,14 @@ public class FauxProperty extends BaseResourceBean implements ResourceBean,
} }
public String getRangeLabel() { public String getRangeLabel() {
return (rangeLabel == null) ? localName(rangeURI) : rangeLabel; if (StringUtils.isEmpty(rangeLabel)) {
if (StringUtils.isEmpty(rangeURI)) {
return "untyped";
}
return localName(rangeURI);
} else {
return rangeLabel;
}
} }
public void setRangeLabel(String rangeLabel) { public void setRangeLabel(String rangeLabel) {

View file

@ -4,7 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.beans;
import java.beans.XMLEncoder; import java.beans.XMLEncoder;
import java.text.Collator; import java.text.Collator;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.Iterator; import java.util.Iterator;

View file

@ -22,6 +22,7 @@ import edu.cornell.mannlib.vedit.controller.BaseEditController;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Ontology; import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup; import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.beans.VClass;
@ -177,6 +178,11 @@ public class DatapropEditController extends BaseEditController {
sortForPickList(eqProps, vreq); sortForPickList(eqProps, vreq);
request.setAttribute("equivalentProperties", eqProps); request.setAttribute("equivalentProperties", eqProps);
List<FauxProperty> fauxProps = vreq.getUnfilteredAssertionsWebappDaoFactory().getFauxPropertyDao().
getFauxPropertiesForBaseUri(dp.getURI());
sortForPickList(fauxProps, vreq);
request.setAttribute("fauxproperties", fauxProps);
ApplicationBean appBean = vreq.getAppBean(); ApplicationBean appBean = vreq.getAppBean();
request.setAttribute("epoKey",epo.getKey()); request.setAttribute("epoKey",epo.getKey());

View file

@ -32,12 +32,14 @@ import edu.cornell.mannlib.vedit.validator.Validator;
import edu.cornell.mannlib.vedit.validator.impl.RequiredFieldValidator; import edu.cornell.mannlib.vedit.validator.impl.RequiredFieldValidator;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionListener; import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionListener;
import edu.cornell.mannlib.vitro.webapp.beans.Datatype;
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty; import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
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.PropertyGroup; import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.edit.utils.RoleLevelOptionsSetup; import edu.cornell.mannlib.vitro.webapp.controller.edit.utils.RoleLevelOptionsSetup;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
@ -99,6 +101,8 @@ public class FauxPropertyRetryController extends BaseEditController {
private FauxProperty beanForEditing; private FauxProperty beanForEditing;
private Property baseProperty; private Property baseProperty;
private boolean isFauxDataProperty = false;
EpoPopulator(HttpServletRequest req, EditProcessObject epo) { EpoPopulator(HttpServletRequest req, EditProcessObject epo) {
this.req = new VitroRequest(req); this.req = new VitroRequest(req);
this.ctx = req.getSession().getServletContext(); this.ctx = req.getSession().getServletContext();
@ -127,10 +131,19 @@ public class FauxPropertyRetryController extends BaseEditController {
this.baseProperty = req.getUnfilteredWebappDaoFactory() this.baseProperty = req.getUnfilteredWebappDaoFactory()
.getObjectPropertyDao() .getObjectPropertyDao()
.getObjectPropertyByURI(beanForEditing.getURI()); .getObjectPropertyByURI(beanForEditing.getURI());
if (this.baseProperty == null) {
this.baseProperty = req.getUnfilteredWebappDaoFactory()
.getDataPropertyDao()
.getDataPropertyByURI(beanForEditing.getURI());
isFauxDataProperty = true;
}
addCheckboxValuesToTheRequest(); addCheckboxValuesToTheRequest();
setFieldValidators(); if (!isFauxDataProperty) {
setFieldValidators();
}
setListeners(); setListeners();
setForwarders(); setForwarders();
@ -150,8 +163,7 @@ public class FauxPropertyRetryController extends BaseEditController {
return newFauxProperty(baseUri); return newFauxProperty(baseUri);
} }
FauxProperty bean = fpDao.getFauxPropertyByUris(domainUri, baseUri, FauxProperty bean = fpDao.getFauxPropertyByUris(domainUri, baseUri, rangeUri);
rangeUri);
if (bean == null) { if (bean == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"FauxProperty does not exist for <" + domainUri "FauxProperty does not exist for <" + domainUri
@ -168,7 +180,11 @@ public class FauxPropertyRetryController extends BaseEditController {
private FauxProperty newFauxProperty(String baseUri) { private FauxProperty newFauxProperty(String baseUri) {
FauxProperty fp = new FauxProperty(null, baseUri, null); FauxProperty fp = new FauxProperty(null, baseUri, null);
ObjectPropertyDao opDao = wadf.getObjectPropertyDao(); ObjectPropertyDao opDao = wadf.getObjectPropertyDao();
ObjectProperty base = opDao.getObjectPropertyByURI(baseUri); DataPropertyDao dpDao = wadf.getDataPropertyDao();
Property base = opDao.getObjectPropertyByURI(baseUri);
if (base == null) {
base = dpDao.getDataPropertyByURI(baseUri);
}
fp.setGroupURI(base.getGroupURI()); fp.setGroupURI(base.getGroupURI());
fp.setRangeURI(base.getRangeVClassURI()); fp.setRangeURI(base.getRangeVClassURI());
fp.setDomainURI(base.getDomainVClassURI()); fp.setDomainURI(base.getDomainVClassURI());
@ -270,7 +286,7 @@ public class FauxPropertyRetryController extends BaseEditController {
list.addAll(FormUtils.makeVClassOptionList(wadf, list.addAll(FormUtils.makeVClassOptionList(wadf,
beanForEditing.getDomainURI())); beanForEditing.getDomainURI()));
} else { } else {
list.addAll(FormUtils.makeOptionListOfSubVClasses(wadf, list.addAll(FormUtils.makeOptionListOfNotDisjointClasses(wadf,
baseProperty.getDomainVClassURI(), baseProperty.getDomainVClassURI(),
beanForEditing.getDomainURI())); beanForEditing.getDomainURI()));
} }
@ -279,12 +295,20 @@ public class FauxPropertyRetryController extends BaseEditController {
} }
private List<Option> buildRangeOptionList() { private List<Option> buildRangeOptionList() {
if (isFauxDataProperty) {
return buildDataPropOptionList();
} else {
return buildObjectPropOptionList();
}
}
private List<Option> buildObjectPropOptionList() {
List<Option> list = new ArrayList<>(); List<Option> list = new ArrayList<>();
if (baseProperty.getRangeVClassURI() == null) { if (baseProperty.getRangeVClassURI() == null) {
list.addAll(FormUtils.makeVClassOptionList(wadf, list.addAll(FormUtils.makeVClassOptionList(wadf,
beanForEditing.getRangeURI())); beanForEditing.getRangeURI()));
} else { } else {
list.addAll(FormUtils.makeOptionListOfSubVClasses(wadf, list.addAll(FormUtils.makeOptionListOfNotDisjointClasses(wadf,
baseProperty.getRangeVClassURI(), baseProperty.getRangeVClassURI(),
beanForEditing.getRangeURI())); beanForEditing.getRangeURI()));
if (containsVCardKind(list)) { if (containsVCardKind(list)) {
@ -295,6 +319,26 @@ public class FauxPropertyRetryController extends BaseEditController {
return list; return list;
} }
private List<Option> buildDataPropOptionList() {
List<Option> list = new ArrayList<>();
String rangeUri = baseProperty.getRangeVClassURI();
if (rangeUri == null) {
Option option = new Option();
option.setValue("");
option.setBody("untyped (rdfs:Literal)");
option.setSelected(true);
list.add(option);
} else {
Datatype dataType = wadf.getDatatypeDao().getDatatypeByURI(rangeUri);
Option option = new Option();
option.setValue(dataType.getUri());
option.setBody(dataType.getName());
option.setSelected(true);
list.add(option);
}
return list;
}
private static final String VCARD_KIND_URI = "http://www.w3.org/2006/vcard/ns#Kind"; private static final String VCARD_KIND_URI = "http://www.w3.org/2006/vcard/ns#Kind";
private static final String VCARD_NAMESPACE = "http://www.w3.org/2006/vcard/ns#"; private static final String VCARD_NAMESPACE = "http://www.w3.org/2006/vcard/ns#";

View file

@ -8,39 +8,40 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty; import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
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.PropertyGroup; import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao;
import javax.servlet.annotation.WebServlet; import javax.servlet.annotation.WebServlet;
@WebServlet(name = "ListFauxPropertiesController", urlPatterns = {"/listFauxProperties"} ) @WebServlet(name = "ListFauxPropertiesController", urlPatterns = { "/listFauxProperties" })
public class ListFauxPropertiesController extends FreemarkerHttpServlet { public class ListFauxPropertiesController extends FreemarkerHttpServlet {
private static final Log log = LogFactory.getLog(ListFauxPropertiesController.class.getName()); private static final Log log = LogFactory.getLog(ListFauxPropertiesController.class.getName());
private static final String TEMPLATE_NAME = "siteAdmin-fauxPropertiesList.ftl"; private static final String TEMPLATE_NAME = "siteAdmin-fauxPropertiesList.ftl";
private ObjectPropertyDao opDao = null; private String notFoundMessage = "";
private PropertyGroupDao pgDao = null;
private FauxPropertyDao fpDao = null;
private String notFoundMessage = "";
@Override @Override
protected AuthorizationRequest requiredActions(VitroRequest vreq) { protected AuthorizationRequest requiredActions(VitroRequest vreq) {
return SimplePermission.EDIT_ONTOLOGY.ACTION; return SimplePermission.EDIT_ONTOLOGY.ACTION;
} }
@Override @Override
protected ResponseValues processRequest(VitroRequest vreq) { protected ResponseValues processRequest(VitroRequest vreq) {
@ -50,176 +51,303 @@ public class ListFauxPropertiesController extends FreemarkerHttpServlet {
String displayOption = ""; String displayOption = "";
if ( vreq.getParameter("displayOption") != null ) { if (vreq.getParameter("displayOption") != null) {
displayOption = vreq.getParameter("displayOption"); displayOption = vreq.getParameter("displayOption");
} } else {
else {
displayOption = "listing"; displayOption = "listing";
} }
body.put("displayOption", displayOption); body.put("displayOption", displayOption);
if ( displayOption.equals("listing") ) { if (displayOption.equals("listing")) {
body.put("pageTitle", "Faux Property Listing"); body.put("pageTitle", "Faux Property Listing");
} } else {
else {
body.put("pageTitle", "Faux Properties by Base Property"); body.put("pageTitle", "Faux Properties by Base Property");
} }
List<ObjectProperty> objectProps = getOPDao(vreq).getRootObjectProperties();
List<DataProperty> dataProps = getDPDao(vreq).getRootDataProperties();
Map<String, Object> allFauxProps = new TreeMap<String, Object>();
opDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getObjectPropertyDao(); // get the faux depending on the display option
fpDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getFauxPropertyDao(); if (displayOption.equals("listing")) {
pgDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getPropertyGroupDao(); allFauxProps.putAll(getFauxPropertyList(objectProps, vreq));
allFauxProps.putAll(getFauxDataPropertyList(dataProps, vreq));
List<ObjectProperty> objectProps = null; } else {
objectProps = opDao.getRootObjectProperties(); allFauxProps.putAll(getFauxByBaseList(objectProps, vreq));
allFauxProps.putAll(getFauxDataPropsByBaseList(dataProps, vreq));
Map<String, Object> allFauxProps = new TreeMap<String, Object>();
// get the faux depending on the display option
if ( displayOption.equals("listing") ) {
allFauxProps = getFauxPropertyList(objectProps);
} }
else {
allFauxProps = getFauxByBaseList(objectProps);
}
log.debug(allFauxProps.toString()); log.debug(allFauxProps.toString());
if ( notFoundMessage.length() == 0 ) { if (notFoundMessage.length() == 0) {
body.put("message", notFoundMessage); body.put("message", notFoundMessage);
} } else {
else { body.put("fauxProps", allFauxProps);
body.put("fauxProps", allFauxProps); }
}
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); log.error(t, t);
} }
return new TemplateResponseValues(TEMPLATE_NAME, body); return new TemplateResponseValues(TEMPLATE_NAME, body);
} }
private TreeMap<String, Object> getFauxPropertyList(List<ObjectProperty> objectProps) { private PropertyGroupDao getPGDao(VitroRequest vreq) {
List<FauxProperty> fauxProps = null; return vreq.getUnfilteredAssertionsWebappDaoFactory().getPropertyGroupDao();
TreeMap<String, Object> theFauxProps = new TreeMap<String, Object>(); }
if ( objectProps != null ) {
private FauxPropertyDao getFPDao(VitroRequest vreq) {
return vreq.getUnfilteredAssertionsWebappDaoFactory().getFauxPropertyDao();
}
private DataPropertyDao getDPDao(VitroRequest vreq) {
return vreq.getUnfilteredAssertionsWebappDaoFactory().getDataPropertyDao();
}
private ObjectPropertyDao getOPDao(VitroRequest vreq) {
return vreq.getUnfilteredAssertionsWebappDaoFactory().getObjectPropertyDao();
}
private TreeMap<String, Object> getFauxPropertyList(List<ObjectProperty> objectProps, VitroRequest vreq) {
List<FauxProperty> fauxProps = null;
TreeMap<String, Object> theFauxProps = new TreeMap<String, Object>();
if (objectProps != null) {
Iterator<ObjectProperty> opIt = objectProps.iterator(); Iterator<ObjectProperty> opIt = objectProps.iterator();
if ( !opIt.hasNext()) { if (!opIt.hasNext()) {
notFoundMessage = "No object properties found."; notFoundMessage = "No object properties found.";
} } else {
else {
while (opIt.hasNext()) { while (opIt.hasNext()) {
ObjectProperty op = opIt.next(); ObjectProperty op = opIt.next();
String baseURI = op.getURI(); String baseURI = op.getURI();
fauxProps = fpDao.getFauxPropertiesForBaseUri(baseURI); fauxProps = getFPDao(vreq).getFauxPropertiesForBaseUri(baseURI);
if ( fauxProps != null ) { if (fauxProps != null) {
Iterator<FauxProperty> fpIt = fauxProps.iterator(); Iterator<FauxProperty> fpIt = fauxProps.iterator();
if ( !fpIt.hasNext()) { if (!fpIt.hasNext()) {
notFoundMessage = "No faux properties found."; notFoundMessage = "No faux properties found.";
} } else {
else { while (fpIt.hasNext()) {
while (fpIt.hasNext()) { // No point in getting these unless we have a
// No point in getting these unless we have a faux property // faux property
String baseLabel = getDisplayLabel(op) == null ? "(no name)" : getDisplayLabel(op); String baseLabel = getBaseLabel(op, false);
String baseLocalName = op.getLocalNameWithPrefix(); // get the info we need from the faux property
baseLabel = baseLabel.substring(0,baseLabel.indexOf("(")); FauxProperty fp = fpIt.next();
baseLabel += "(" + baseLocalName + ")"; String fauxLabel = fp.getDisplayName();
// get the info we need from the faux property String rangeLabel = fp.getRangeLabel();
FauxProperty fp = fpIt.next(); String rangeURI = fp.getRangeURI();
String fauxLabel = fp.getDisplayName(); String domainLabel = fp.getDomainLabel();
String rangeLabel = fp.getRangeLabel(); String domainURI = fp.getDomainURI();
String rangeURI = fp.getRangeURI(); String groupURI = fp.getGroupURI();
String domainLabel = fp.getDomainLabel(); // FauxProperty only gets groupURI but we want
String domainURI = fp.getDomainURI(); // the label
String groupURI = fp.getGroupURI(); PropertyGroup pGroup = getPGDao(vreq).getGroupByURI(groupURI);
// FauxProperty only gets groupURI but we want the label String groupLabel = (pGroup == null) ? "unspecified" : pGroup.getName();
PropertyGroup pGroup = pgDao.getGroupByURI(groupURI); // store all the strings in a hash with the faux
String groupLabel = ( pGroup == null ) ? "unspecified" : pGroup.getName(); // property label as the key
// store all the strings in a hash with the faux property label as the key Map<String, Object> tmpHash = new HashMap<String, Object>();
Map<String, Object> tmpHash = new HashMap<String, Object>(); tmpHash.put("base", baseLabel);
tmpHash.put("base", baseLabel); tmpHash.put("baseURI", baseURI);
tmpHash.put("baseURI", baseURI); tmpHash.put("group", groupLabel);
tmpHash.put("group", groupLabel); tmpHash.put("range", rangeLabel);
tmpHash.put("range", rangeLabel); tmpHash.put("rangeURI", rangeURI);
tmpHash.put("rangeURI", rangeURI); tmpHash.put("domain", domainLabel);
tmpHash.put("domain", domainLabel); tmpHash.put("domainURI", domainURI);
tmpHash.put("domainURI", domainURI); tmpHash.put("editUrl", "propertyEdit");
// add the faux and its details to the treemap
theFauxProps.put(fauxLabel + "@@" + domainLabel, tmpHash); // add the faux and its details to the treemap
} theFauxProps.put(fauxLabel + "@@" + domainLabel, tmpHash);
} }
} }
} }
}
} }
} }
return theFauxProps; return theFauxProps;
} }
private TreeMap<String, Object> getFauxByBaseList(List<ObjectProperty> objectProps) { private TreeMap<String, Object> getFauxByBaseList(List<ObjectProperty> objectProps, VitroRequest vreq) {
List<FauxProperty> fauxProps = null; List<FauxProperty> fauxProps = null;
TreeMap<String, Object> fauxByBaseProps = new TreeMap<String, Object>(); TreeMap<String, Object> fauxByBaseProps = new TreeMap<String, Object>();
if ( objectProps != null ) { if (objectProps != null) {
Iterator<ObjectProperty> opIt = objectProps.iterator(); Iterator<ObjectProperty> opIt = objectProps.iterator();
if ( !opIt.hasNext()) { if (!opIt.hasNext()) {
notFoundMessage = "No object properties found."; notFoundMessage = "No object properties found.";
} } else {
else {
while (opIt.hasNext()) { while (opIt.hasNext()) {
TreeMap<String, Object> fauxForGivenBase = new TreeMap<String, Object>(); TreeMap<String, Object> fauxForGivenBase = new TreeMap<String, Object>();
ObjectProperty op = opIt.next(); ObjectProperty op = opIt.next();
String baseURI = op.getURI(); String baseURI = op.getURI();
fauxProps = fpDao.getFauxPropertiesForBaseUri(baseURI); fauxProps = getFPDao(vreq).getFauxPropertiesForBaseUri(baseURI);
if ( fauxProps != null ) { if (fauxProps != null) {
Iterator<FauxProperty> fpIt = fauxProps.iterator(); Iterator<FauxProperty> fpIt = fauxProps.iterator();
if ( !fpIt.hasNext()) { if (!fpIt.hasNext()) {
notFoundMessage = "No faux properties found."; notFoundMessage = "No faux properties found.";
} } else {
else { String baseLabel = getBaseLabel(op, true);
String baseLabel = getDisplayLabel(op) == null ? "(no name)" : getDisplayLabel(op); while (fpIt.hasNext()) {
String baseLocalName = op.getLocalNameWithPrefix(); // get the info we need from the faux property
baseLabel = baseLabel.substring(0,baseLabel.indexOf("(")); FauxProperty fp = fpIt.next();
baseLabel += "(" + baseLocalName + ")" + "|" + baseURI; String fauxLabel = fp.getDisplayName();
while (fpIt.hasNext()) { String rangeLabel = fp.getRangeLabel();
// get the info we need from the faux property String rangeURI = fp.getRangeURI();
FauxProperty fp = fpIt.next(); String domainLabel = fp.getDomainLabel();
String fauxLabel = fp.getDisplayName(); String domainURI = fp.getDomainURI();
String rangeLabel = fp.getRangeLabel(); String groupURI = fp.getGroupURI();
String rangeURI = fp.getRangeURI(); // FauxProperty only gets groupURI but we want
String domainLabel = fp.getDomainLabel(); // the label
String domainURI = fp.getDomainURI(); PropertyGroup pGroup = getPGDao(vreq).getGroupByURI(groupURI);
String groupURI = fp.getGroupURI(); String groupLabel = (pGroup == null) ? "unspecified" : pGroup.getName();
// FauxProperty only gets groupURI but we want the label // store all the strings in a hash with the faux
PropertyGroup pGroup = pgDao.getGroupByURI(groupURI); // property label as the key
String groupLabel = ( pGroup == null ) ? "unspecified" : pGroup.getName(); Map<String, Object> tmpHash = new HashMap<String, Object>();
// store all the strings in a hash with the faux property label as the key tmpHash.put("baseURI", baseURI);
Map<String, Object> tmpHash = new HashMap<String, Object>(); tmpHash.put("group", groupLabel);
tmpHash.put("baseURI", baseURI); tmpHash.put("range", rangeLabel);
tmpHash.put("group", groupLabel); tmpHash.put("rangeURI", rangeURI);
tmpHash.put("range", rangeLabel); tmpHash.put("domain", domainLabel);
tmpHash.put("rangeURI", rangeURI); tmpHash.put("domainURI", domainURI);
tmpHash.put("domain", domainLabel);
tmpHash.put("domainURI", domainURI); // add the faux and its details to the treemap
// add the faux and its details to the treemap fauxForGivenBase.put(fauxLabel + "@@" + domainLabel, tmpHash);
fauxForGivenBase.put(fauxLabel + "@@" + domainLabel, tmpHash); fauxForGivenBase.put("editUrl", "propertyEdit");
} }
fauxByBaseProps.put(baseLabel, fauxForGivenBase); fauxByBaseProps.put(baseLabel, fauxForGivenBase);
} }
} }
} }
} }
} }
return fauxByBaseProps; return fauxByBaseProps;
} }
/* private TreeMap<String, Object> getFauxDataPropertyList(List<DataProperty> dataProps, VitroRequest vreq) {
* should never be null List<FauxProperty> fauxProps = null;
*/ TreeMap<String, Object> theFauxProps = new TreeMap<String, Object>();
public static String getDisplayLabel(ObjectProperty op) { if (dataProps != null) {
String displayLabel = op.getPickListName(); Iterator<DataProperty> opIt = dataProps.iterator();
displayLabel = (displayLabel != null && displayLabel.length() > 0) if (!opIt.hasNext()) {
? displayLabel notFoundMessage = "No data properties found.";
: op.getLocalName(); } else {
return (displayLabel != null) ? displayLabel : "[object property]" ; while (opIt.hasNext()) {
DataProperty dp = opIt.next();
String baseURI = dp.getURI();
fauxProps = getFPDao(vreq).getFauxPropertiesForBaseUri(baseURI);
if (fauxProps != null) {
Iterator<FauxProperty> fpIt = fauxProps.iterator();
if (!fpIt.hasNext()) {
notFoundMessage = "No faux properties found.";
} else {
while (fpIt.hasNext()) {
// No point in getting these unless we have a
// faux property
String baseLabel = getBaseLabel(dp, false);
// get the info we need from the faux property
FauxProperty fp = fpIt.next();
String fauxLabel = fp.getDisplayName();
String rangeLabel = fp.getRangeLabel();
String rangeURI = fp.getRangeURI();
String domainLabel = fp.getDomainLabel();
String domainURI = fp.getDomainURI();
String groupURI = fp.getGroupURI();
// FauxProperty only gets groupURI but we want
// the label
PropertyGroup pGroup = getPGDao(vreq).getGroupByURI(groupURI);
String groupLabel = (pGroup == null) ? "unspecified" : pGroup.getName();
// store all the strings in a hash with the faux
// property label as the key
Map<String, Object> tmpHash = new HashMap<String, Object>();
tmpHash.put("base", baseLabel);
tmpHash.put("baseURI", baseURI);
tmpHash.put("group", groupLabel);
tmpHash.put("range", rangeLabel);
tmpHash.put("rangeURI", rangeURI);
tmpHash.put("domain", domainLabel);
tmpHash.put("domainURI", domainURI);
tmpHash.put("editUrl", "datapropEdit");
// add the faux and its details to the treemap
theFauxProps.put(fauxLabel + "@@" + domainLabel, tmpHash);
}
}
}
}
}
}
return theFauxProps;
}
private TreeMap<String, Object> getFauxDataPropsByBaseList(List<DataProperty> dataProps, VitroRequest vreq) {
List<FauxProperty> fauxProps = null;
TreeMap<String, Object> fauxByBaseProps = new TreeMap<String, Object>();
if (dataProps != null) {
Iterator<DataProperty> opIt = dataProps.iterator();
if (!opIt.hasNext()) {
notFoundMessage = "No data properties found.";
} else {
while (opIt.hasNext()) {
TreeMap<String, Object> fauxForGivenBase = new TreeMap<String, Object>();
DataProperty dp = opIt.next();
String baseURI = dp.getURI();
fauxProps = getFPDao(vreq).getFauxPropertiesForBaseUri(baseURI);
if (fauxProps != null) {
Iterator<FauxProperty> fpIt = fauxProps.iterator();
if (!fpIt.hasNext()) {
notFoundMessage = "No faux properties found.";
} else {
String baseLabel = getBaseLabel(dp, true);
while (fpIt.hasNext()) {
// get the info we need from the faux property
FauxProperty fp = fpIt.next();
String fauxLabel = fp.getDisplayName();
String rangeLabel = fp.getRangeLabel();
String rangeURI = fp.getRangeURI();
String domainLabel = fp.getDomainLabel();
String domainURI = fp.getDomainURI();
String groupURI = fp.getGroupURI();
// FauxProperty only gets groupURI but we want
// the label
PropertyGroup pGroup = getPGDao(vreq).getGroupByURI(groupURI);
String groupLabel = (pGroup == null) ? "unspecified" : pGroup.getName();
// store all the strings in a hash with the faux
// property label as the key
Map<String, Object> tmpHash = new HashMap<String, Object>();
tmpHash.put("baseURI", baseURI);
tmpHash.put("group", groupLabel);
tmpHash.put("range", rangeLabel);
tmpHash.put("rangeURI", rangeURI);
tmpHash.put("domain", domainLabel);
tmpHash.put("domainURI", domainURI);
// add the faux and its details to the treemap
fauxForGivenBase.put(fauxLabel + "@@" + domainLabel, tmpHash);
fauxForGivenBase.put("editUrl", "datapropEdit");
}
fauxByBaseProps.put(baseLabel, fauxForGivenBase);
}
}
}
}
}
return fauxByBaseProps;
}
private String getBaseLabel(Property property, boolean addUri) {
String baseLabel = property.getPickListName();
if (StringUtils.isEmpty(baseLabel)) {
baseLabel = property.getLocalName();
}
if (StringUtils.isEmpty(baseLabel)) {
baseLabel = "[property]";
}
String baseLocalName = property.getLocalNameWithPrefix();
int indexOf = baseLabel.indexOf("(");
if (indexOf > 0) {
baseLabel = baseLabel.substring(0, indexOf);
}
baseLabel += "(" + baseLocalName + ")";
if (addUri) {
baseLabel += "|" + property.getURI();
}
return baseLabel;
} }
} }

View file

@ -14,6 +14,7 @@ import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.jena.ontology.ObjectProperty; import org.apache.jena.ontology.ObjectProperty;
@ -152,13 +153,10 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
Collection<String> rangeUris = getPropertyResourceURIValues( Collection<String> rangeUris = getPropertyResourceURIValues(
context, QUALIFIED_BY_RANGE); context, QUALIFIED_BY_RANGE);
if (rangeUris.isEmpty()) { String rangeUri = null;
log.debug("'" + contextUri + "' has no value for '" if (!rangeUris.isEmpty()) {
+ QUALIFIED_BY_RANGE + "'"); rangeUri = rangeUris.iterator().next();
return null;
} }
String rangeUri = rangeUris.iterator().next();
// domainURI is optional. // domainURI is optional.
Collection<String> domainUris = getPropertyResourceURIValues( Collection<String> domainUris = getPropertyResourceURIValues(
context, QUALIFIED_BY_DOMAIN); context, QUALIFIED_BY_DOMAIN);
@ -214,7 +212,7 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
addPropertyResourceValue(context, RDF.type, CONFIG_CONTEXT); addPropertyResourceValue(context, RDF.type, CONFIG_CONTEXT);
addPropertyResourceURIValue(context, CONFIG_CONTEXT_FOR, addPropertyResourceURIValue(context, CONFIG_CONTEXT_FOR,
fp.getBaseURI()); fp.getBaseURI());
addPropertyResourceURIValue(context, QUALIFIED_BY_RANGE, addPropertyResourceURINotEmpty(context, QUALIFIED_BY_RANGE,
fp.getRangeURI()); fp.getRangeURI());
addPropertyResourceURINotEmpty(context, QUALIFIED_BY_DOMAIN, addPropertyResourceURINotEmpty(context, QUALIFIED_BY_DOMAIN,
fp.getDomainURI()); fp.getDomainURI());
@ -493,31 +491,22 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
// ConfigContext // ConfigContext
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
private static final String QUERY_LOCATE_CONFIG_CONTEXT_WITH_DOMAIN = "" // private static String queryLocateConfigContext(boolean hasDomain, boolean hasRange) {
+ "PREFIX : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" // return "PREFIX : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n"
+ "\n" // + "SELECT DISTINCT ?context ?config \n"
+ "SELECT DISTINCT ?context ?config \n" // + "WHERE { \n"
+ "WHERE { \n" // + " ?context a :ConfigContext . \n"
+ " ?context a :ConfigContext ; \n" // + " ?context :configContextFor ?baseUri . \n"
+ " :configContextFor ?baseUri ; \n" // + ( hasDomain ? "" : " FILTER NOT EXISTS { \n " )
+ " :qualifiedByDomain ?domainUri ; \n" // + " ?context :qualifiedByDomain ?domainUri . \n"
+ " :qualifiedBy ?rangeUri ; \n" // + ( hasDomain ? "" : "} \n" )
+ " :hasConfiguration ?config . \n" // + ( hasRange ? "" : " FILTER NOT EXISTS { \n " )
+ "} \n"; // + " ?context :qualifiedBy ?rangeUri . \n"
+ ( hasRange ? "" : "} \n" )
+ " ?context :hasConfiguration ?config . \n"
+ "} \n";
private static final String QUERY_LOCATE_CONFIG_CONTEXT_WITH_NO_DOMAIN = "" // }
+ "PREFIX : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" //
+ "\n" //
+ "SELECT DISTINCT ?context ?config \n" //
+ "WHERE { \n" //
+ " ?context a :ConfigContext ; \n" //
+ " :configContextFor ?baseUri ; \n" //
+ " :qualifiedBy ?rangeUri ; \n" //
+ " :hasConfiguration ?config . \n" //
+ " FILTER NOT EXISTS { \n" //
+ " ?context :qualifiedByDomain ?domainUri \n" //
+ " } \n" //
+ "} \n"; //
private static class ParserLocateConfigContext extends private static class ParserLocateConfigContext extends
ResultSetParser<Set<ConfigContext>> { ResultSetParser<Set<ConfigContext>> {
@ -556,22 +545,16 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
private static class ConfigContext { private static class ConfigContext {
public static Set<ConfigContext> findByQualifiers( public static Set<ConfigContext> findByQualifiers(
LockableOntModel lockableDisplayModel, String domainUri, LockableOntModel lockableDisplayModel, String domainUri, String baseUri, String rangeUri) {
String baseUri, String rangeUri) {
try (LockedOntModel displayModel = lockableDisplayModel.read()) { try (LockedOntModel displayModel = lockableDisplayModel.read()) {
QueryHolder qHolder; boolean hasDomain = !StringUtils.isEmpty(domainUri) && !domainUri.equals(OWL.Thing.getURI());
if (domainUri == null || domainUri.trim().isEmpty() boolean hasRange = !StringUtils.isEmpty(rangeUri);
|| domainUri.equals(OWL.Thing.getURI())) { QueryHolder qHolder = queryHolder(queryLocateConfigContext(hasDomain, hasRange)).bindToUri("baseUri", baseUri);
qHolder = queryHolder( if (hasDomain) {
QUERY_LOCATE_CONFIG_CONTEXT_WITH_NO_DOMAIN) qHolder = qHolder.bindToUri("domainUri", domainUri);
.bindToUri("baseUri", baseUri).bindToUri( }
"rangeUri", rangeUri); if (hasRange) {
} else { qHolder = qHolder.bindToUri("rangeUri", rangeUri);
qHolder = queryHolder(
QUERY_LOCATE_CONFIG_CONTEXT_WITH_DOMAIN)
.bindToUri("baseUri", baseUri)
.bindToUri("rangeUri", rangeUri)
.bindToUri("domainUri", domainUri);
} }
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("domainUri=" + domainUri + ", baseUri=" + baseUri log.debug("domainUri=" + domainUri + ", baseUri=" + baseUri

View file

@ -813,7 +813,9 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
List<ObjectProperty> stragglers = getAdditionalFauxSubpropertiesForVClasses( List<ObjectProperty> stragglers = getAdditionalFauxSubpropertiesForVClasses(
vclasses, propInsts); vclasses, propInsts);
for (ObjectProperty op : stragglers) { for (ObjectProperty op : stragglers) {
propInsts.add(makePropInst(op)); if (op != null) {
propInsts.add(makePropInst(op));
}
} }
return propInsts; return propInsts;

View file

@ -264,6 +264,7 @@ public class VClassDaoJena extends JenaBaseDao implements VClassDao {
} catch (ProfileException pe) { } catch (ProfileException pe) {
// Current language profile does not support disjointWith axioms. // Current language profile does not support disjointWith axioms.
// We'd prefer to return an empty list instead of throwing an exception. // We'd prefer to return an empty list instead of throwing an exception.
log.error(pe, pe);
} finally { } finally {
getOntModel().leaveCriticalSection(); getOntModel().leaveCriticalSection();
} }

View file

@ -4,6 +4,9 @@ package edu.cornell.mannlib.vitro.webapp.utils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -18,112 +21,227 @@ import org.apache.jena.query.ResultSet;
import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Resource; import org.apache.jena.rdf.model.Resource;
import org.apache.jena.rdf.model.ResourceFactory;
import org.apache.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; 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.VClass; import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena; import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactoryJena;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.FauxDataPropertyWrapper;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.FauxObjectPropertyWrapper;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual.FauxPropertyWrapper;
public class ApplicationConfigurationOntologyUtils { public class ApplicationConfigurationOntologyUtils {
private static final Log log = LogFactory.getLog(ApplicationConfigurationOntologyUtils.class); private static final Log log = LogFactory.getLog(ApplicationConfigurationOntologyUtils.class);
public static List<ObjectProperty> getAdditionalFauxSubpropertiesForList(List<ObjectProperty> propList, Individual subject, VitroRequest vreq) { private static final String getPossibleFauxQuery(boolean isData) {
Model displayModel = vreq.getDisplayModel(); return
Model tboxModel = vreq.getOntModelSelector().getTBoxModel(); "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
return getAdditionalFauxSubpropertiesForList(propList, subject, displayModel, tboxModel);
}
public static List<ObjectProperty> getAdditionalFauxSubproperties(ObjectProperty prop,
Individual subject,
Model tboxModel,
Model union) {
List<ObjectProperty> additionalProps = new ArrayList<ObjectProperty>();
String queryStr = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
"PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" + "PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" +
"PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n" + "PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n" +
"SELECT DISTINCT ?range ?domain ?property WHERE { \n" + "SELECT DISTINCT ?domain ?property ?context ?isData WHERE { \n" +
" ?context config:configContextFor ?property . \n" + " ?context config:configContextFor ?property . \n" +
" ?context config:qualifiedBy ?range . \n" + (isData ?
"?property a <http://www.w3.org/2002/07/owl#DatatypeProperty> . \n"
:
"?property a <http://www.w3.org/2002/07/owl#ObjectProperty> . \n" ) +
" OPTIONAL { ?context config:qualifiedBy ?range . } \n " +
" ?context config:hasConfiguration ?configuration . \n" + " ?context config:hasConfiguration ?configuration . \n" +
" ?configuration a config:ObjectPropertyDisplayConfig . \n" + " ?configuration a config:ObjectPropertyDisplayConfig . \n" +
" OPTIONAL { ?context config:qualifiedByDomain ?domain } \n" + " OPTIONAL { ?context config:qualifiedByDomain ?domain } . \n" +
"}"; "}";
}
if(prop != null) { private static String getFauxPropQuery(String baseUri, boolean optionalRange) {
log.debug("Checking " + prop.getURI() + " for additional properties"); return
queryStr = queryStr.replaceAll("For \\?property", "For <" + prop.getURI() + ">"); "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" +
} "PREFIX config: <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" +
log.debug(queryStr); "PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n" +
Query q = QueryFactory.create(queryStr); "SELECT DISTINCT ?domain ?context WHERE { \n" +
" ?context config:configContextFor <" + baseUri + "> . \n" +
(optionalRange ? " OPTIONAL { " : "") +
" ?context config:qualifiedBy ?range . \n" +
(optionalRange ? " } " : "") +
" ?context config:hasConfiguration ?configuration . \n" +
" ?configuration a config:ObjectPropertyDisplayConfig . \n" +
" OPTIONAL { ?context config:qualifiedByDomain ?domain } \n" +
"}";
}
public static List<FauxObjectPropertyWrapper> getPopulatedFauxOPs(List<ObjectProperty> populatedObjectProperties, Individual subject, VitroRequest vreq) {
List<FauxObjectPropertyWrapper> fauxProperties = new ArrayList<FauxObjectPropertyWrapper>();
for (ObjectProperty op : populatedObjectProperties) {
fauxProperties.addAll(getPopulatedFauxObjectProperties(op, subject, vreq));
}
return fauxProperties;
}
public static List<FauxDataPropertyWrapper> getPopulatedFauxDPs(List<DataProperty> populatedDataProperties, Individual subject, VitroRequest vreq) {
List<FauxDataPropertyWrapper> fauxProperties = new ArrayList<FauxDataPropertyWrapper>();
for (DataProperty dp : populatedDataProperties) {
fauxProperties.addAll(getPopulatedFauxDataProperties(dp, subject, vreq));
}
return fauxProperties;
}
private static List<FauxObjectPropertyWrapper> getPopulatedFauxObjectProperties(ObjectProperty op, Individual subject, VitroRequest vreq) {
Model displayModel = vreq.getDisplayModel();
Model tboxModel = vreq.getOntModelSelector().getTBoxModel();
Model union = ModelFactory.createUnion(displayModel, tboxModel);
WebappDaoFactory wadf = new WebappDaoFactoryJena(ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, union));
FauxPropertyDao fpDao = wadf.getFauxPropertyDao();
Query q = createQuery(op, false);
QueryExecution qe = QueryExecutionFactory.create(q, union); QueryExecution qe = QueryExecutionFactory.create(q, union);
WebappDaoFactory wadf = new WebappDaoFactoryJena( List<FauxObjectPropertyWrapper> fauxObjectProps = new ArrayList<FauxObjectPropertyWrapper>();
ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, union));
ObjectPropertyDao opDao = wadf.getObjectPropertyDao();
try { try {
ResultSet rs = qe.execSelect(); ResultSet rs = qe.execSelect();
while (rs.hasNext()) { while (rs.hasNext()) {
QuerySolution qsoln = rs.nextSolution(); QuerySolution qsoln = rs.nextSolution();
log.debug(qsoln); log.debug(qsoln);
String opURI = (prop != null) ? prop.getURI() : qsoln.getResource(
"property").getURI();
Resource domainRes = qsoln.getResource("domain"); Resource domainRes = qsoln.getResource("domain");
String domainURI = (domainRes != null) ? domainRes.getURI() : null; String domainURI = (domainRes != null) ? domainRes.getURI() : null;
String rangeURI = qsoln.getResource("range").getURI(); String contextURI = qsoln.getResource("context").getURI();
if (appropriateDomain(domainRes, subject, tboxModel)) { if (isDomainMatchSubject(domainURI, subject)) {
ObjectProperty faux = opDao.getObjectPropertyByURIs( try {
opURI, domainURI, rangeURI, (prop != null) ? prop.clone() : null); FauxProperty fp = fpDao.getFauxPropertyFromContextUri(contextURI);
if (faux != null) { if (fp != null) {
additionalProps.add(faux); fauxObjectProps.add(new FauxObjectPropertyWrapper(op.clone(), fp));
} else { }
log.error("Could not retrieve " + opURI + " qualified by " + } catch (Exception e) {
" domain " + domainURI + " and range " + rangeURI); log.warn("Couldn't look up the faux property", e);
} }
} }
} }
} finally { } finally {
qe.close(); qe.close();
} }
return additionalProps; return fauxObjectProps;
} }
private static List<FauxDataPropertyWrapper> getPopulatedFauxDataProperties(DataProperty dp, Individual subject, VitroRequest vreq) {
Model displayModel = vreq.getDisplayModel();
public static List<ObjectProperty> getAdditionalFauxSubpropertiesForList(List<ObjectProperty> propList, Model tboxModel = vreq.getOntModelSelector().getTBoxModel();
Individual subject,
Model displayModel,
Model tboxModel) {
List<ObjectProperty> additionalProps = new ArrayList<ObjectProperty>();
Model union = ModelFactory.createUnion(displayModel, tboxModel); Model union = ModelFactory.createUnion(displayModel, tboxModel);
WebappDaoFactory wadf = new WebappDaoFactoryJena(ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, union));
FauxPropertyDao fpDao = wadf.getFauxPropertyDao();
for (ObjectProperty op : propList) { Query q = createQuery(dp, true);
additionalProps.addAll(getAdditionalFauxSubproperties(op, subject, tboxModel, union)); QueryExecution qe = QueryExecutionFactory.create(q, union);
List<FauxDataPropertyWrapper> fauxDataProps = new ArrayList<FauxDataPropertyWrapper>();
try {
ResultSet rs = qe.execSelect();
while (rs.hasNext()) {
QuerySolution qsoln = rs.nextSolution();
log.debug(qsoln);
Resource domainRes = qsoln.getResource("domain");
String domainURI = (domainRes != null) ? domainRes.getURI() : null;
String contextURI = qsoln.getResource("context").getURI();
if (isDomainMatchSubject(domainURI, subject)) {
try {
FauxProperty fp = fpDao.getFauxPropertyFromContextUri(contextURI);
if (fp != null) {
fauxDataProps.add(new FauxDataPropertyWrapper(dp, fp));
}
} catch (Exception e) {
log.warn("Couldn't look up the faux property", e);
}
}
}
} finally {
qe.close();
} }
return fauxDataProps;
return additionalProps;
} }
private static boolean appropriateDomain(Resource domainRes, Individual subject, Model tboxModel) { private static Query createQuery(Property op, boolean optionalRange) {
if (subject == null || domainRes == null) { String queryStr = getFauxPropQuery(op.getURI(), optionalRange);
log.debug(queryStr);
Query q = QueryFactory.create(queryStr);
return q;
}
private static boolean isDomainMatchSubject(String domainUri, Individual subject) {
if (subject == null || domainUri == null) {
return true; return true;
} }
for (VClass vclass : subject.getVClasses()) { Set<String> vClassUris = subject.getVClasses().stream().map(vclass -> vclass.getURI())
if ((vclass.getURI() != null) && .collect(Collectors.toSet());
((vclass.getURI().equals(domainRes.getURI()) || for (String vClassUri : vClassUris) {
(tboxModel.contains( if (vClassUri != null && vClassUri.equals(domainUri)) {
ResourceFactory.createResource(
vclass.getURI()), RDFS.subClassOf, domainRes))))) {
return true; return true;
} }
} }
return false; return false;
} }
public static List<Property> getPossibleFauxProps(List<? extends FauxPropertyWrapper> curProps, Individual subject, VitroRequest vreq, boolean isData) {
Model displayModel = vreq.getDisplayModel();
Model tboxModel = vreq.getOntModelSelector().getTBoxModel();
Model union = ModelFactory.createUnion(displayModel, tboxModel);
Map<String, FauxProperty> curPropsMap = curProps.stream()
.collect(Collectors.toMap(FauxPropertyWrapper::getContextUri, FauxPropertyWrapper::getFauxProperty));
WebappDaoFactory wadf = new WebappDaoFactoryJena(ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, union));
FauxPropertyDao fpDao = wadf.getFauxPropertyDao();
ObjectPropertyDao opDao = wadf.getObjectPropertyDao();
DataPropertyDao dpDao = wadf.getDataPropertyDao();
Query q = QueryFactory.create(getPossibleFauxQuery(isData));
QueryExecution qe = QueryExecutionFactory.create(q, union);
List<Property> fauxDataProps = new ArrayList<Property>();
try {
ResultSet rs = qe.execSelect();
while (rs.hasNext()) {
QuerySolution qsoln = rs.nextSolution();
Resource domainRes = qsoln.getResource("domain");
String domainURI = (domainRes != null) ? domainRes.getURI() : null;
String basePropertyUri = qsoln.getResource("property").getURI();
String contextURI = qsoln.getResource("context").getURI();
if (isDomainMatchSubject(domainURI, subject) && !curPropsMap.containsKey(contextURI)) {
if (isData) {
addDataProperty(fauxDataProps, basePropertyUri, contextURI, fpDao, dpDao);
} else {
addObjectProperty(fauxDataProps, basePropertyUri, contextURI, fpDao, opDao);
}
}
}
} finally {
qe.close();
}
return fauxDataProps;
}
private static void addObjectProperty(List<Property> fauxProps, String basePropertyUri, String contextURI,
FauxPropertyDao fpDao, ObjectPropertyDao opDao) {
try {
FauxProperty fp = fpDao.getFauxPropertyFromContextUri(contextURI);
ObjectProperty op = opDao.getObjectPropertyByURI(basePropertyUri);
if (fp != null && op != null) {
fauxProps.add(new FauxObjectPropertyWrapper(op, fp));
}
} catch (Exception e) {
log.warn("Couldn't look up the faux object property, contextUri " + contextURI, e);
}
}
private static void addDataProperty(List<Property> fauxProps, String basePropertyUri, String contextURI,
FauxPropertyDao fpDao, DataPropertyDao dpDao) {
try {
FauxProperty fp = fpDao.getFauxPropertyFromContextUri(contextURI);
DataProperty dp = dpDao.getDataPropertyByURI(basePropertyUri);
if (fp != null && dp != null) {
fauxProps.add(new FauxDataPropertyWrapper(dp, fp));
}
} catch (Exception e) {
log.warn("Couldn't look up the faux data property, contextUri " + contextURI, e);
}
}
} }

View file

@ -0,0 +1,329 @@
/* $This file is distributed under the terms of the license in LICENSE$ */
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
import java.util.List;
import java.util.Objects;
import org.apache.jena.rdf.model.ResourceFactory;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement;
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectPropertyStatement;
/**
* A DataProperty that has some of its values overridden by a FauxProperty.
*
* TODO This is a horrible kluge that should be discarded as soon as we can
* rewrite GroupedPropertyList.
*/
public class FauxDataPropertyWrapper extends DataProperty implements FauxPropertyWrapper{
private final DataProperty innerDP;
private final FauxProperty faux;
public FauxDataPropertyWrapper(DataProperty inner, FauxProperty faux) {
this.innerDP = inner;
this.faux = faux;
}
// ----------------------------------------------------------------------
// Methods where FauxProperty overrides.
// ----------------------------------------------------------------------
@Override
public String getGroupURI() {
String uri = faux.getGroupURI();
if (uri != null) {
return uri;
}
return innerDP.getGroupURI();
}
@Override
public void setGroupURI(String groupUri) {
faux.setGroupURI(groupUri);
innerDP.setGroupURI(groupUri);
}
// -------
@Override
public String getDomainVClassURI() {
String uri = faux.getDomainVClassURI();
if (uri != null) {
return uri;
}
return innerDP.getDomainVClassURI();
}
@Override
public void setDomainVClassURI(String domainClassURI) {
faux.setDomainURI(domainClassURI);
innerDP.setDomainVClassURI(domainClassURI);
}
// -------
@Override
public String getRangeVClassURI() {
String uri = faux.getRangeVClassURI();
if (uri != null) {
return uri;
}
return innerDP.getRangeVClassURI();
}
@Override
public void setRangeVClassURI(String rangeClassURI) {
faux.setRangeURI(rangeClassURI);
innerDP.setRangeVClassURI(rangeClassURI);
}
// -------
@Override
public String getCustomEntryForm() {
String s = faux.getCustomEntryForm();
if (s != null) {
return s;
}
return innerDP.getCustomEntryForm();
}
@Override
public void setCustomEntryForm(String s) {
faux.setCustomEntryForm(s);
innerDP.setCustomEntryForm(s);
}
// -------
@Override
public String getPublicDescription() {
String s = faux.getPublicDescription();
if (s != null) {
return s;
}
return innerDP.getPublicDescription();
}
@Override
public void setPublicDescription(String s) {
faux.setPublicDescription(s);
innerDP.setPublicDescription(s);
}
// -------
@Override
public String getPickListName() {
String name = faux.getDisplayName();
if (name != null) {
return name;
}
return innerDP.getPickListName();
}
@Override
public void setPickListName(String pickListName) {
faux.setDisplayName(pickListName);
innerDP.setPickListName(pickListName);
}
// ----------------------------------------------------------------------
// Methods from DataProperty
// ----------------------------------------------------------------------
@Override
public String getLabel() {
return innerDP.getLabel();
}
@Override
public String getDescription() {
return innerDP.getDescription();
}
@Override
public void setDescription(String description) {
innerDP.setDescription(description);
}
@Override
public String getExample() {
return innerDP.getExample();
}
@Override
public void setExample(String example) {
innerDP.setExample(example);
}
@Override
public boolean getFunctional() {
return innerDP.getFunctional();
}
@Override
public void setFunctional(boolean functional) {
innerDP.setFunctional(functional);
}
@Override
public void setLabel(String label) {
innerDP.setLabel(label);
}
@Override
public boolean isSubjectSide() {
return innerDP.isSubjectSide();
}
@Override
public boolean isEditLinkSuppressed() {
return innerDP.isEditLinkSuppressed();
}
@Override
public boolean isAddLinkSuppressed() {
return innerDP.isAddLinkSuppressed();
}
@Override
public boolean isDeleteLinkSuppressed() {
return innerDP.isDeleteLinkSuppressed();
}
@Override
public void setEditLinkSuppressed(boolean editLinkSuppressed) {
innerDP.setEditLinkSuppressed(editLinkSuppressed);
}
@Override
public void setAddLinkSuppressed(boolean addLinkSuppressed) {
innerDP.setAddLinkSuppressed(addLinkSuppressed);
}
@Override
public void setDeleteLinkSuppressed(boolean deleteLinkSuppressed) {
innerDP.setDeleteLinkSuppressed(deleteLinkSuppressed);
}
@Override
public boolean isAnonymous() {
return innerDP.isAnonymous();
}
@Override
public String getURI() {
return innerDP.getURI();
}
@Override
public void setURI(String URI) {
innerDP.setURI(URI);
}
@Override
public String getNamespace() {
return innerDP.getNamespace();
}
@Override
public void setNamespace(String namespace) {
innerDP.setNamespace(namespace);
}
@Override
public String getLocalName() {
return innerDP.getLocalName();
}
@Override
public void setLocalName(String localName) {
innerDP.setLocalName(localName);
}
@Override
public String getLocalNameWithPrefix() {
return innerDP.getLocalNameWithPrefix();
}
@Override
public void setLocalNameWithPrefix(String prefixedLocalName) {
innerDP.setLocalNameWithPrefix(prefixedLocalName);
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((faux == null) ? 0 : faux.hashCode());
result = prime * result + ((innerDP == null) ? 0 : innerDP.hashCode());
return Objects.hash(innerDP, faux);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
FauxDataPropertyWrapper that = (FauxDataPropertyWrapper) obj;
return Objects.equals(this.innerDP, that.innerDP)
&& Objects.equals(this.faux, that.faux);
}
@Override
public List<DataPropertyStatement> getDataPropertyStatements() {
return innerDP.getDataPropertyStatements();
}
@Override
public String toString() {
return String.format("FauxDataPropertyWrapper[ %s ==> %s ==> %s, statementCount=%d, group=%s, customEntryForm=%s ]",
localName(getDomainVClassURI()),
localName(getURI()),
localName(getRangeVClassURI()),
(getDataPropertyStatements() == null ? 0: getDataPropertyStatements().size()),
localName(getGroupURI()),
simpleName(getCustomEntryForm()));
}
private Object simpleName(String classname) {
if (classname == null) {
return null;
} else {
return classname.substring(classname.lastIndexOf(".") + 1);
}
}
private Object localName(String uri) {
if (uri == null) {
return null;
} else {
return ResourceFactory.createResource(uri).getLocalName();
}
}
@Override
public FauxProperty getFauxProperty() {
return faux;
}
@Override
public String getContextUri() {
return faux.getContextUri();
}
}

View file

@ -18,7 +18,7 @@ import edu.cornell.mannlib.vitro.webapp.beans.VClass;
* TODO This is a horrible kluge that should be discarded as soon as we can * TODO This is a horrible kluge that should be discarded as soon as we can
* rewrite GroupedPropertyList. * rewrite GroupedPropertyList.
*/ */
public class FauxObjectPropertyWrapper extends ObjectProperty { public class FauxObjectPropertyWrapper extends ObjectProperty implements FauxPropertyWrapper{
private final ObjectProperty innerOP; private final ObjectProperty innerOP;
private final FauxProperty faux; private final FauxProperty faux;
@ -624,8 +624,11 @@ public class FauxObjectPropertyWrapper extends ObjectProperty {
@Override @Override
public String toString() { public String toString() {
return String.format("FauxObjectPropertyWrapper[ %s <==> %s | %s ==> %s ==> %s, statementCount=%d, group=%s, customEntryForm=%s ]", return String.format("FauxObjectPropertyWrapper[ %s <==> %s | %s ==> %s ==> %s, statementCount=%d, group=%s, customEntryForm=%s ]",
getDomainPublic(), getRangePublic(), getDomainPublic(),
localName(getDomainVClassURI()), localName(getURI()), localName(getRangeVClassURI()), getRangePublic(),
localName(getDomainVClassURI()),
localName(getURI()),
localName(getRangeVClassURI()),
(getObjectPropertyStatements() == null ? 0: getObjectPropertyStatements().size()), (getObjectPropertyStatements() == null ? 0: getObjectPropertyStatements().size()),
localName(getGroupURI()), localName(getGroupURI()),
simpleName(getCustomEntryForm())); simpleName(getCustomEntryForm()));
@ -647,4 +650,14 @@ public class FauxObjectPropertyWrapper extends ObjectProperty {
} }
} }
@Override
public FauxProperty getFauxProperty() {
return faux;
}
@Override
public String getContextUri() {
return faux.getContextUri();
}
} }

View file

@ -0,0 +1,10 @@
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
public interface FauxPropertyWrapper {
public FauxProperty getFauxProperty();
public String getContextUri();
}

View file

@ -10,6 +10,8 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@ -17,7 +19,6 @@ import org.apache.commons.logging.LogFactory;
import org.apache.jena.vocabulary.OWL; import org.apache.jena.vocabulary.OWL;
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Individual; 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;
@ -25,7 +26,6 @@ import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstance; import edu.cornell.mannlib.vitro.webapp.beans.PropertyInstance;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey; import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey;
import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao; import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao;
@ -63,53 +63,53 @@ public class GroupedPropertyList extends BaseTemplateModel {
private List<PropertyGroupTemplateModel> groups; private List<PropertyGroupTemplateModel> groups;
GroupedPropertyList(Individual subject, VitroRequest vreq, GroupedPropertyList(Individual subject, VitroRequest vreq, boolean editing) {
boolean editing) {
this.vreq = vreq; this.vreq = vreq;
this.subject = subject; this.subject = subject;
this.wdf = vreq.getWebappDaoFactory(); this.wdf = vreq.getWebappDaoFactory();
// Create the property list for the subject. The properties will be put // Create the property list for the subject. The properties will be put
// into groups later. // into groups later.
List<Property> propertyList = new ArrayList<Property>(); List<Property> allProperties = new ArrayList<Property>();
// First get all the object properties that occur in statements in the // First get all the object properties that occur in statements in the
// db with this subject as subject. // db with this subject as subject.
// This may include properties that are not defined as // This may include properties that are not defined as
// "possible properties" for a subject of this class, // "possible properties" for a subject of this class,
// so we cannot just rely on getting that list. // so we cannot just rely on getting that list.
List<ObjectProperty> populatedObjectPropertyList = subject List<ObjectProperty> populatedOPs = subject.getPopulatedObjectPropertyList();
.getPopulatedObjectPropertyList();
Map<String, List<String>> populatedObjTypes = makePopulatedObjTypeMap( Map<String, List<String>> populatedObjTypes = makePopulatedObjTypeMap(populatedOPs);
populatedObjectPropertyList);
// save applicable ranges before deduping to filter later // save applicable ranges before deduping to filter later
populatedObjectPropertyList = dedupe(populatedObjectPropertyList); populatedOPs = dedupe(populatedOPs);
Collection<ObjectProperty> additions = ApplicationConfigurationOntologyUtils List<FauxObjectPropertyWrapper> populatedFauxOPs = ApplicationConfigurationOntologyUtils.getPopulatedFauxOPs(populatedOPs, subject, vreq);
.getAdditionalFauxSubpropertiesForList(
populatedObjectPropertyList, subject, vreq);
additions = filterAdditions(additions, populatedObjTypes); populatedFauxOPs = filterAdditions(populatedFauxOPs, populatedObjTypes);
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
for (ObjectProperty t : additions) { for (ObjectProperty fauxOP : populatedFauxOPs) {
log.debug("addition: " + t); log.debug("faux object property: " + fauxOP);
} }
log.debug("Added " + additions.size() + log.debug("Added " + populatedFauxOPs.size() + " faux object properties due to application configuration ontology");
" properties due to application configuration ontology");
} }
populatedObjectPropertyList.addAll(additions); if(editing) {
List<Property> possibleFauxProps = ApplicationConfigurationOntologyUtils.getPossibleFauxProps(populatedFauxOPs, subject, vreq, false);
allProperties.addAll(possibleFauxProps);
}
propertyList.addAll(populatedObjectPropertyList); populatedOPs.addAll(populatedFauxOPs);
allProperties.addAll(populatedOPs);
// 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) {
propertyList = mergeAllPossibleObjectProperties(populatedObjectPropertyList, propertyList); List<Property> possibleOPs = getPossibleOPs(populatedOPs, allProperties, subject);
allProperties.addAll(possibleOPs);
} }
// 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
@ -118,25 +118,36 @@ public class GroupedPropertyList extends BaseTemplateModel {
// DataPropertyStatements. Note that this does not apply to object properties, because the queries // DataPropertyStatements. Note that this does not apply to object properties, because the queries
// can be customized and thus differ from property to property. So it's easier for now to keep the // can be customized and thus differ from property to property. So it's easier for now to keep the
// two working in parallel. // two working in parallel.
List<DataProperty> populatedDataPropertyList = subject List<DataProperty> populatedDPs = subject.getPopulatedDataPropertyList();
.getPopulatedDataPropertyList();
propertyList.addAll(populatedDataPropertyList);
if (editing) { if (editing) {
mergeAllPossibleDataProperties(propertyList); List<Property> possibleDPs = getPossibleDPs(populatedDPs, allProperties);
allProperties.addAll(possibleDPs);
} }
sort(propertyList);
List<FauxDataPropertyWrapper> populatedFauxDPs = ApplicationConfigurationOntologyUtils.getPopulatedFauxDPs(populatedDPs, subject, vreq);
if(editing) {
List<Property> possibleFauxProps = ApplicationConfigurationOntologyUtils.getPossibleFauxProps(populatedFauxDPs, subject, vreq, true);
allProperties.addAll(possibleFauxProps);
}
populatedDPs.addAll(populatedFauxDPs);
allProperties.addAll(populatedDPs);
sort(allProperties);
// Put the list into groups // Put the list into groups
List<PropertyGroup> propertyGroupList = addPropertiesToGroups(propertyList); List<PropertyGroup> propertyGroups = addPropertiesToGroups(allProperties);
// Build the template data model from the groupList // Build the template data model from the groupList
groups = new ArrayList<PropertyGroupTemplateModel>( groups = new ArrayList<PropertyGroupTemplateModel>(
propertyGroupList.size()); propertyGroups.size());
for (PropertyGroup propertyGroup : propertyGroupList) { for (PropertyGroup propertyGroup : propertyGroups) {
groups.add(new PropertyGroupTemplateModel(vreq, propertyGroup, groups.add(new PropertyGroupTemplateModel(vreq, propertyGroup,
subject, editing, populatedDataPropertyList, subject, editing, populatedDPs,
populatedObjectPropertyList)); populatedOPs));
} }
if (!editing) { if (!editing) {
@ -160,10 +171,10 @@ public class GroupedPropertyList extends BaseTemplateModel {
return map; return map;
} }
private List<ObjectProperty> filterAdditions(Collection<ObjectProperty> additions, private List<FauxObjectPropertyWrapper> filterAdditions(List<FauxObjectPropertyWrapper> populatedFauxOPs,
Map<String, List<String>> populatedObjTypes) { Map<String, List<String>> populatedObjTypes) {
List<ObjectProperty> filteredAdditions = new ArrayList<ObjectProperty>(); List<FauxObjectPropertyWrapper> filteredAdditions = new ArrayList<FauxObjectPropertyWrapper>();
for (ObjectProperty prop : additions) { for (FauxObjectPropertyWrapper prop : populatedFauxOPs) {
List<String> allowedTypes = populatedObjTypes.get(prop.getURI()); List<String> allowedTypes = populatedObjTypes.get(prop.getURI());
if(allowedTypes != null && (allowedTypes.contains(prop.getRangeVClassURI()) if(allowedTypes != null && (allowedTypes.contains(prop.getRangeVClassURI())
|| allowedTypes.contains(prop.getRangeEntityURI()) ) ) { || allowedTypes.contains(prop.getRangeEntityURI()) ) ) {
@ -223,9 +234,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
} }
} }
private List<Property> mergeAllPossibleObjectProperties( private List<Property> getPossibleOPs(List<ObjectProperty> populatedOPs, List<Property> allProperties, Individual subject) {
List<ObjectProperty> populatedObjectPropertyList,
List<Property> propertyList) {
// There is no ObjectPropertyDao.getAllPossibleObjectPropertiesForIndividual() parallel to // There is no ObjectPropertyDao.getAllPossibleObjectPropertiesForIndividual() parallel to
// DataPropertyDao.getAllPossibleDatapropsForIndividual(). The comparable method for object properties // DataPropertyDao.getAllPossibleDatapropsForIndividual(). The comparable method for object properties
@ -235,27 +244,29 @@ public class GroupedPropertyList extends BaseTemplateModel {
// breaks blank node structures in the restrictions that determine applicable properties. // breaks blank node structures in the restrictions that determine applicable properties.
WebappDaoFactory wadf = vreq.getLanguageNeutralWebappDaoFactory(); WebappDaoFactory wadf = vreq.getLanguageNeutralWebappDaoFactory();
PropertyInstanceDao piDao = wadf.getPropertyInstanceDao(); PropertyInstanceDao piDao = wadf.getPropertyInstanceDao();
ObjectPropertyDao opDao = wadf.getObjectPropertyDao();
Set<String> vClassUris = subject.getVClasses().stream().map(vclass -> vclass.getURI()).collect(Collectors.toSet());
Map<String, Property> possiblePropertiesMap = new HashMap<String,Property>();
Collection<PropertyInstance> allPossiblePI = piDao Collection<PropertyInstance> allPossiblePI = piDao.getAllPossiblePropInstForIndividual(subject.getURI());
.getAllPossiblePropInstForIndividual(subject.getURI());
if (allPossiblePI != null) { if (allPossiblePI != null) {
for (PropertyInstance possiblePI : allPossiblePI) { for (PropertyInstance possiblePI : allPossiblePI) {
if (possiblePI != null) { if (possiblePI != null) {
// use the language-aware wdf because redundancy check // use the language-aware wdf because redundancy check
// for display will depend on public label match // for display will depend on public label match
ObjectProperty possibleOP = assembleObjectProperty(possiblePI); ObjectProperty possibleOP = opDao.getObjectPropertyByURI(possiblePI.getPropertyURI());
if (possibleOP == null) { if (possibleOP == null) {
continue; continue;
} }
boolean addToList = true; for(ObjectProperty populatedOP : populatedOPs) {
for(ObjectProperty populatedOP : populatedObjectPropertyList) {
if (redundant(populatedOP, possibleOP)) { if (redundant(populatedOP, possibleOP)) {
addToList = false; continue;
} }
} }
if(addToList) { if (!vClassUris.contains(possibleOP.getDomainVClassURI())) {
propertyList.add(possibleOP); continue;
} }
possiblePropertiesMap.put(possibleOP.getURI(), possibleOP);
} else { } else {
log.error("a property instance in the Collection created by PropertyInstanceDao.getAllPossiblePropInstForIndividual() is unexpectedly null"); log.error("a property instance in the Collection created by PropertyInstanceDao.getAllPossiblePropInstForIndividual() is unexpectedly null");
} }
@ -267,36 +278,16 @@ public class GroupedPropertyList extends BaseTemplateModel {
// These properties are outside the ontologies (in vitro and vitro public) but need to be added to the list. // These properties are outside the ontologies (in vitro and vitro public) but need to be added to the list.
// In future, vitro ns props will be phased out. Vitro public properties should be changed so they do not // In future, vitro ns props will be phased out. Vitro public properties should be changed so they do not
// constitute a special case (i.e., included in piDao.getAllPossiblePropInstForIndividual()). // constitute a special case (i.e., included in piDao.getAllPossiblePropInstForIndividual()).
ArrayList<Property> possibleProperties = new ArrayList<>(possiblePropertiesMap.values());
for (String propertyUri : VITRO_PROPS_TO_ADD_TO_LIST) { for (String propertyUri : VITRO_PROPS_TO_ADD_TO_LIST) {
if (!alreadyOnPropertyList(propertyList, propertyUri)) { if (!alreadyOnPropertyList(possibleProperties, propertyUri) && !alreadyOnPropertyList(allProperties, propertyUri)) {
addObjectPropertyToPropertyList(propertyUri, null, null, propertyList); addObjectPropertyToPropertyList(propertyUri, null, null, possibleProperties);
} }
} }
return possibleProperties;
return propertyList;
} }
private ObjectProperty assembleObjectProperty(PropertyInstance pi) {
WebappDaoFactory rawWadf = ModelAccess.on(vreq).getWebappDaoFactory();
ObjectPropertyDao opDao = rawWadf.getObjectPropertyDao();
FauxPropertyDao fpDao = rawWadf.getFauxPropertyDao();
String base = pi.getPropertyURI();
String domain = pi.getDomainClassURI();
String range = pi.getRangeClassURI();
ObjectProperty op = opDao.getObjectPropertyByURIs(base, domain, range);
try {
FauxProperty fp = fpDao.getFauxPropertyByUris(domain, base, range);
if (fp != null) {
return new FauxObjectPropertyWrapper(op, fp);
}
} catch (Exception e) {
log.warn("Couldn't look up the faux property", e);
}
return op;
}
/** /**
* Don't know what the real problem is with VIVO-976, but somehow we have the same property * Don't know what the real problem is with VIVO-976, but somehow we have the same property
* showing up once with a blank node as a domain, and once with null or OWL:Thing as a domain. * showing up once with a blank node as a domain, and once with null or OWL:Thing as a domain.
@ -367,19 +358,19 @@ public class GroupedPropertyList extends BaseTemplateModel {
} }
} }
protected void mergeAllPossibleDataProperties(List<Property> propertyList) { protected List<Property> getPossibleDPs(List<DataProperty> populatedDPs, List<Property> allProperties) {
// see comments in mergeAllPossibleObjectProperties() for the reason // see comments in mergeAllPossibleObjectProperties() for the reason
// that we need a neutral WebappDaoFactory here. // that we need a neutral WebappDaoFactory here.
DataPropertyDao dpDao = vreq.getLanguageNeutralWebappDaoFactory().getDataPropertyDao(); DataPropertyDao dpDao = vreq.getLanguageNeutralWebappDaoFactory().getDataPropertyDao();
Collection<DataProperty> allDatapropColl = dpDao List<Property> possibleProperties = new ArrayList<Property>();
.getAllPossibleDatapropsForIndividual(subject.getURI()); Collection<DataProperty> allDatapropColl = dpDao.getAllPossibleDatapropsForIndividual(subject.getURI());
if (allDatapropColl != null) { if (allDatapropColl != null) {
for (DataProperty dp : allDatapropColl) { for (DataProperty dp : allDatapropColl) {
if (dp != null) { if (dp != null) {
if (dp.getURI() == null) { if (dp.getURI() == null) {
log.error("DataProperty dp returned with null propertyURI from dpDao.getAllPossibleDatapropsForIndividual()"); log.error("DataProperty dp returned with null propertyURI from dpDao.getAllPossibleDatapropsForIndividual()");
} else if (!alreadyOnPropertyList(propertyList, dp)) { } else if (!alreadyOnPropertyList(allProperties, dp) && !alreadyOnPropertyList(populatedDPs, dp)) {
propertyList.add(dp); possibleProperties.add(dp);
} }
} else { } else {
log.error("a data property in the Collection created in DataPropertyDao.getAllPossibleDatapropsForIndividual() is unexpectedly null)"); log.error("a data property in the Collection created in DataPropertyDao.getAllPossibleDatapropsForIndividual() is unexpectedly null)");
@ -388,9 +379,10 @@ public class GroupedPropertyList extends BaseTemplateModel {
} else { } else {
log.error("a null Collection is returned from DataPropertyDao.getAllPossibleDatapropsForIndividual())"); log.error("a null Collection is returned from DataPropertyDao.getAllPossibleDatapropsForIndividual())");
} }
return possibleProperties;
} }
private boolean alreadyOnPropertyList(List<Property> propertyList, private boolean alreadyOnPropertyList(List<? extends Property> propertyList,
Property p) { Property p) {
if (p.getURI() == null) { if (p.getURI() == null) {
log.error("Property p has no propertyURI in alreadyOnPropertyList()"); log.error("Property p has no propertyURI in alreadyOnPropertyList()");
@ -399,8 +391,7 @@ public class GroupedPropertyList extends BaseTemplateModel {
return (alreadyOnPropertyList(propertyList, p.getURI())); return (alreadyOnPropertyList(propertyList, p.getURI()));
} }
private boolean alreadyOnPropertyList(List<Property> propertyList, private boolean alreadyOnPropertyList(List<? extends Property> propertyList, String propertyUri) {
String propertyUri) {
for (Property p : propertyList) { for (Property p : propertyList) {
String uri = p.getURI(); String uri = p.getURI();
if (uri != null && uri.equals(propertyUri)) { if (uri != null && uri.equals(propertyUri)) {

View file

@ -17,7 +17,6 @@ import edu.cornell.mannlib.vitro.webapp.beans.Property;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder.Route;
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
@ -40,26 +39,30 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
protected String addUrl; protected String addUrl;
private String name; private String name;
private FauxProperty fauxProperty;
private int displayLimit; private int displayLimit;
PropertyTemplateModel(Property property, Individual subject, VitroRequest vreq, String name) { PropertyTemplateModel(Property property, Individual subject, VitroRequest vreq, String name) {
this.vreq = vreq; this.vreq = vreq;
subjectUri = subject.getURI(); subjectUri = subject.getURI();
this.property = property; this.property = property;
propertyUri = property.getURI(); if (isFauxProperty(property)) {
localName = property.getLocalName(); FauxProperty fauxProperty = getFauxProperty(property);
this.name = name; this.name = fauxProperty.getDisplayName();
addUrl = ""; this.displayLimit = fauxProperty.getDisplayLimit();
propertyUri = fauxProperty.getBaseURI();
fauxProperty = isFauxProperty(property); } else {
if (fauxProperty != null) { propertyUri = property.getURI();
this.name = fauxProperty.getDisplayName(); this.name = name;
this.displayLimit = fauxProperty.getDisplayLimit();
} }
localName = property.getLocalName();
addUrl = "";
setVerboseDisplayValues(property); setVerboseDisplayValues(property);
} }
private FauxProperty getFauxProperty(Property property) {
return ((FauxPropertyWrapper) property).getFauxProperty();
}
protected void setVerboseDisplayValues(Property property) { protected void setVerboseDisplayValues(Property property) {
// No verbose display for vitro and vitro public properties. // No verbose display for vitro and vitro public properties.
@ -104,15 +107,17 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
String editUrl = UrlBuilder.getUrl(getPropertyEditRoute(), "uri", property.getURI()); String editUrl = UrlBuilder.getUrl(getPropertyEditRoute(), "uri", property.getURI());
verboseDisplay.put("propertyEditUrl", editUrl); verboseDisplay.put("propertyEditUrl", editUrl);
if (fauxProperty != null) { if (isFauxProperty(property)) {
verboseDisplay.put("fauxProperty", assembleFauxPropertyValues(fauxProperty)); verboseDisplay.put("fauxProperty", assembleFauxPropertyValues(getFauxProperty(property)));
} }
} }
private FauxProperty isFauxProperty(Property prop) { private boolean isFauxProperty(Property prop) {
FauxPropertyDao fpDao = vreq.getUnfilteredWebappDaoFactory().getFauxPropertyDao(); if (prop instanceof FauxPropertyWrapper) {
return fpDao.getFauxPropertyByUris(prop.getDomainVClassURI(), prop.getURI(), prop.getRangeVClassURI()); return true;
} }
return false;
}
private Map<String, Object> assembleFauxPropertyValues(FauxProperty fp) { private Map<String, Object> assembleFauxPropertyValues(FauxProperty fp) {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
@ -168,10 +173,6 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
return (addUrl != null) ? addUrl : ""; return (addUrl != null) ? addUrl : "";
} }
//check to see whether or not this property represents a faux property
public boolean getIsFauxProperty() {
return (fauxProperty != null);
}
public Map<String, Object> getVerboseDisplay() { public Map<String, Object> getVerboseDisplay() {
return verboseDisplay; return verboseDisplay;
} }

View file

@ -71,6 +71,51 @@
</td> </td>
</tr> </tr>
<tr><td colspan="3"><hr/></td></tr>
<!-- _____________________________________________ faux properties __________________________________________ -->
<tr valign="bottom" align="center">
<td colspan="2" valign="bottom" align="left">
<c:if test="${!empty fauxproperties}">
<c:forEach var="fauxproperty" items="${fauxproperties}">
<ul style="list-style-type:none;">
<li>
<c:choose>
<c:when test="${empty fauxproperty.domainLabel}">
<c:url var="fauxpropertyURL" value="editForm">
<c:param name="controller" value="FauxProperty"/>
<c:param name="baseUri" value="${datatypeProperty.URI}"/>
<c:param name="rangeUri" value="${fauxproperty.rangeURI}" />
</c:url>
<a href="${fauxpropertyURL}">${fauxproperty.pickListName}</a>
no domain,
</c:when>
<c:otherwise>
<c:url var="fauxpropertyURL" value="editForm">
<c:param name="controller" value="FauxProperty"/>
<c:param name="baseUri" value="${datatypeProperty.URI}"/>
<c:param name="domainUri" value="${fauxproperty.domainURI}" />
<c:param name="rangeUri" value="${fauxproperty.rangeURI}" />
</c:url>
<a href="${fauxpropertyURL}">${fauxproperty.pickListName}</a>
domain: ${fauxproperty.domainLabel},
</c:otherwise>
</c:choose>
range: ${fauxproperty.rangeLabel}
</li>
</ul>
</c:forEach>
</c:if>
</td>
<td>
<form action="editForm" method="get">
<input type="hidden" name="create" value="create"/>
<input type="hidden" name="baseUri" value="${datatypeProperty.URI}"/>
<input type="hidden" name="controller" value="FauxProperty"/>
<input type="submit" class="form-button" value="Create New Faux Property"/>
</form>
</td>
</tr>
<tr><td colspan="3"><hr/></td></tr> <tr><td colspan="3"><hr/></td></tr>
<!-- _____________________________________________ superproperties __________________________________________ --> <!-- _____________________________________________ superproperties __________________________________________ -->
<tr valign="bottom" align="center"> <tr valign="bottom" align="center">

View file

@ -40,7 +40,7 @@
<tbody> <tbody>
<tr> <tr>
<td class="classDetail">${i18n().base_property_capitalized}:</td> <td class="classDetail">${i18n().base_property_capitalized}:</td>
<td><a href='propertyEdit?uri=${ks["baseURI"]?url!}'>${ks["base"]!}</a></td> <td><a href='${ks["editUrl"]}?uri=${ks["baseURI"]?url!}'>${ks["base"]!}</a></td>
</tr> </tr>
<tr> <tr>
<td class="classDetail">${i18n().group_capitalized}:</td> <td class="classDetail">${i18n().group_capitalized}:</td>
@ -66,12 +66,13 @@
<#assign baseLabel = key?substring(0,key?index_of("|")) /> <#assign baseLabel = key?substring(0,key?index_of("|")) />
<#assign baseUri = key?substring(key?index_of("|")+1) /> <#assign baseUri = key?substring(key?index_of("|")+1) />
<div> <div>
<a href='propertyEdit?uri=${baseUri?url}'>${baseLabel}</a> <a href='${fauxList["editUrl"]}?uri=${baseUri?url}'>${baseLabel}</a>
</div> </div>
<#assign keysTwo = fauxList?keys /> <#assign keysTwo = fauxList?keys />
<#assign firstLoop = true /> <#assign firstLoop = true />
<#list keysTwo as k2> <#list keysTwo as k2>
<#assign faux = fauxList[k2] /> <#assign faux = fauxList[k2] />
<#if faux?is_hash >
<table id="classHierarchy1" class="classHierarchy" <#if !firstLoop >style="margin-top:-16px"</#if>> <table id="classHierarchy1" class="classHierarchy" <#if !firstLoop >style="margin-top:-16px"</#if>>
<tbody> <tbody>
<tr> <tr>
@ -94,6 +95,7 @@
</tbody> </tbody>
</table> </table>
<#assign firstLoop = false /> <#assign firstLoop = false />
</#if>
</#list> </#list>
</section> </section>
</#list> </#list>