Add link to verbose panel, handle VCard oddities.

This commit is contained in:
Jim Blake 2014-11-07 10:32:33 -05:00
parent 1439c2195d
commit e665b48971
5 changed files with 135 additions and 82 deletions

View file

@ -10,8 +10,10 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
@ -131,12 +133,12 @@ public class FauxPropertyRetryController extends BaseEditController {
addCheckboxValuesToTheRequest();
setFieldValidators();
setListeners();
setForwarders();
doABunchOfOtherJunk();
assembleFormObjectAndConnectToEpo();
}
private String determineAction() {
return (req.getParameter("create") == null) ? "update" : "insert";
}
@ -162,7 +164,8 @@ public class FauxPropertyRetryController extends BaseEditController {
}
/**
* Create a new FauxProperty object and let it inherit some values from its base property.
* Create a new FauxProperty object and let it inherit some values from
* its base property.
*/
private FauxProperty newFauxProperty(String baseUri) {
FauxProperty fp = new FauxProperty(null, baseUri, null);
@ -171,26 +174,32 @@ public class FauxPropertyRetryController extends BaseEditController {
fp.setGroupURI(base.getGroupURI());
fp.setRangeURI(base.getRangeVClassURI());
fp.setDomainURI(base.getDomainVClassURI());
fp.setHiddenFromDisplayBelowRoleLevel(base.getHiddenFromDisplayBelowRoleLevel());
fp.setHiddenFromPublishBelowRoleLevel(base.getHiddenFromPublishBelowRoleLevel());
fp.setProhibitedFromUpdateBelowRoleLevel(base.getProhibitedFromUpdateBelowRoleLevel());
fp.setHiddenFromDisplayBelowRoleLevel(base
.getHiddenFromDisplayBelowRoleLevel());
fp.setHiddenFromPublishBelowRoleLevel(base
.getHiddenFromPublishBelowRoleLevel());
fp.setProhibitedFromUpdateBelowRoleLevel(base
.getProhibitedFromUpdateBelowRoleLevel());
log.debug("Created new FauxProperty: " + fp);
return fp;
}
private void addCheckboxValuesToTheRequest() {
req.setAttribute("selectFromExisting",beanForEditing.isSelectFromExisting());
req.setAttribute("offerCreateNewOption", beanForEditing.isOfferCreateNewOption());
req.setAttribute("collateBySubclass", beanForEditing.isCollateBySubclass());
req.setAttribute("selectFromExisting",
beanForEditing.isSelectFromExisting());
req.setAttribute("offerCreateNewOption",
beanForEditing.isOfferCreateNewOption());
req.setAttribute("collateBySubclass",
beanForEditing.isCollateBySubclass());
// checkboxes on HTML forms are pretty annoying : we don't know if
// someone *unchecked* a box, so we have to default to false on
// updates.
if (beanForEditing.getURI() != null) {
beanForEditing.setSelectFromExisting(false);
beanForEditing.setOfferCreateNewOption(false);
beanForEditing.setCollateBySubclass(false);
}
if (beanForEditing.getURI() != null) {
beanForEditing.setSelectFromExisting(false);
beanForEditing.setOfferCreateNewOption(false);
beanForEditing.setCollateBySubclass(false);
}
}
private void setFieldValidators() {
@ -199,64 +208,39 @@ public class FauxPropertyRetryController extends BaseEditController {
Arrays.asList(new Validator[] { new RequiredFieldValidator() }));
}
private void doABunchOfOtherJunk() {
// set up any listeners
private void setListeners() {
epo.setChangeListenerList(Collections
.singletonList(new PropertyRestrictionListener(ctx)));
}
private void setForwarders() {
// where should the postinsert pageforwarder go?
// TODO
// make a postdelete pageforwarder that will send us to the control
// panel for the base property.
// TODO
}
private void assembleFormObjectAndConnectToEpo() {
FormObject foo = new FormObject();
foo.setErrorMap(epo.getErrMsgMap());
foo.setOptionLists(new HashMap<>(createOptionsMap()));
// We will need to set a lot of option lists and stuff.
// TODO
// Put attributes on the request so the JSP can populate the fields.
// request.setAttribute("transitive",propertyForEditing.getTransitive());
// request.setAttribute("objectIndividualSortPropertyURI",
// propertyForEditing.getObjectIndividualSortPropertyURI());
// TODO
// checkboxes are pretty annoying : we don't know if someone
// *unchecked*
// a box, so we have to default to false on updates.
// propertyForEditing.setSymmetric(false);
// TODO
epo.setFormObject(foo);
FormUtils.populateFormFromBean(beanForEditing, epo.getAction(),
foo, epo.getBadValueMap());
}
private Map<String, List<Option>> createOptionsMap() {
Map<String, List<Option>> map = new HashMap<>();
map.put("GroupURI", createClassGroupOptionList());
map.put("DomainURI",
createRootedVClassOptionList(
baseProperty.getDomainVClassURI(),
beanForEditing.getDomainURI()));
map.put("RangeURI",
createRootedVClassOptionList(
baseProperty.getRangeVClassURI(),
beanForEditing.getRangeURI()));
map.put("DomainURI", buildDomainOptionList());
map.put("RangeURI", buildRangeOptionList());
map.put("HiddenFromDisplayBelowRoleLevelUsingRoleUri",
RoleLevelOptionsSetup.getDisplayOptionsList(beanForEditing));
map.put("ProhibitedFromUpdateBelowRoleLevelUsingRoleUri",
RoleLevelOptionsSetup.getUpdateOptionsList(beanForEditing));
map.put("HiddenFromPublishBelowRoleLevelUsingRoleUri",
RoleLevelOptionsSetup.getPublishOptionsList(beanForEditing));
return map;
}
@ -282,22 +266,73 @@ public class FauxPropertyRetryController extends BaseEditController {
}
}
private List<Option> createRootedVClassOptionList(String rootVClassUri,
String currentSelection) {
private List<Option> buildDomainOptionList() {
List<Option> list = new ArrayList<>();
list.add(new Option("", "(none specified)"));
if (rootVClassUri == null) {
if (baseProperty.getDomainVClassURI() == null) {
list.addAll(FormUtils.makeVClassOptionList(wadf,
currentSelection));
beanForEditing.getDomainURI()));
} else {
list.addAll(FormUtils.makeOptionListOfSubVClasses(wadf,
rootVClassUri, currentSelection));
baseProperty.getDomainVClassURI(),
beanForEditing.getDomainURI()));
}
list.add(0, new Option("", "(none specified)"));
return list;
}
private List<Option> buildRangeOptionList() {
List<Option> list = new ArrayList<>();
if (baseProperty.getRangeVClassURI() == null) {
list.addAll(FormUtils.makeVClassOptionList(wadf,
beanForEditing.getRangeURI()));
} else {
list.addAll(FormUtils.makeOptionListOfSubVClasses(wadf,
baseProperty.getRangeVClassURI(),
beanForEditing.getRangeURI()));
if (containsVCardKind(list)) {
mergeInAllVCardClasses(list);
}
}
list.add(0, new Option("", "(none specified)"));
return list;
}
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 boolean containsVCardKind(List<Option> list) {
for (Option option : list) {
if (VCARD_KIND_URI.equals(option.getValue())) {
return true;
}
}
return false;
}
/**
* Add to the list any class that is in the vCard namespace and is not
* already in the list. Sort the list.
*/
private void mergeInAllVCardClasses(List<Option> list) {
Set<String> existingUrls = new HashSet<>();
for (Option option : list) {
existingUrls.add(option.getValue());
}
for (Option option : FormUtils.makeVClassOptionList(wadf,
beanForEditing.getRangeURI())) {
if (option.getValue().startsWith(VCARD_NAMESPACE)
&& !existingUrls.contains(option.getValue())) {
list.add(option);
}
}
Collections.sort(list, new Comparator<Option>() {
@Override
public int compare(Option o1, Option o2) {
return o1.getBody().compareTo(o2.getBody());
}
});
}
private static class OptionsBodyComparator implements
Comparator<Option> {
private final Collator collator;

View file

@ -91,14 +91,14 @@ public interface VClassDao {
/**
* @param vc1
* @param vc2
* @return true if subClassOf(vc1, vc2)
* @return true if vc1 subClassOf vc2
*/
boolean isSubClassOf(VClass vc1, VClass vc2);
/**
* @param vc1
* @param vc2
* @return true if subClassOf(vc1, vc2)
* @return true if vc1 subClassOf vc2
*/
boolean isSubClassOf(String vclassURI1, String vclassURI2);

View file

@ -59,6 +59,7 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
private static final ObjectProperty QUALIFIED_BY_RANGE = createProperty(appContext("qualifiedBy"));
private static final ObjectProperty QUALIFIED_BY_DOMAIN = createProperty(appContext("qualifiedByDomain"));
private static final ObjectProperty QUALIFIED_BY_ROOT = createProperty(appContext("qualifiedByRoot"));
private static final ObjectProperty LIST_VIEW_FILE = createProperty(appContext("listViewConfigFile"));
private static final ObjectProperty DISPLAY_NAME = createProperty(appContext("displayName"));
private static final ObjectProperty PROPERTY_GROUP = createProperty(appContext("propertyGroup"));
@ -217,6 +218,7 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
fp.getRangeURI());
addPropertyResourceURINotEmpty(context, QUALIFIED_BY_DOMAIN,
fp.getDomainURI());
storeQualifiedByRoot(context, fp.getRangeURI());
fp.setConfigUri(getUnusedURI());
addPropertyResourceURIValue(context, HAS_CONFIGURATION,
@ -269,6 +271,16 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
}
}
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 void storeQualifiedByRoot(OntResource context, String rangeURI) {
if (rangeURI.startsWith(VCARD_NAMESPACE)) {
updatePropertyResourceURIValue(context, QUALIFIED_BY_ROOT, VCARD_KIND_URI);
} else {
updatePropertyResourceURIValue(context, QUALIFIED_BY_ROOT, null);
}
}
@Override
public void updateFauxProperty(FauxProperty fp) {
log.debug("Updating FauxProperty: " + fp);
@ -308,6 +320,7 @@ public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao
fp.getRangeURI());
updatePropertyResourceURIValue(context, QUALIFIED_BY_DOMAIN,
fp.getDomainURI());
storeQualifiedByRoot(context, fp.getRangeURI());
OntResource config = displayModel.createOntResource(fp
.getConfigUri());

View file

@ -11,12 +11,14 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
import edu.cornell.mannlib.vitro.webapp.beans.Property;
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.Route;
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
@ -101,29 +103,30 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
String editUrl = UrlBuilder.getUrl(getPropertyEditRoute(), "uri", property.getURI());
verboseDisplay.put("propertyEditUrl", editUrl);
if(isFauxProperty(property)) {
verboseDisplay.put("fauxProperty", "true");
FauxProperty fauxProperty = isFauxProperty(property);
if (fauxProperty != null) {
verboseDisplay.put("fauxProperty", assembleFauxPropertyValues(fauxProperty));
}
}
private boolean isFauxProperty(Property prop) {
if(!(prop instanceof ObjectProperty)) {
return false;
}
ObjectPropertyDao opDao = vreq.getWebappDaoFactory().getObjectPropertyDao();
ObjectProperty baseProp = opDao.getObjectPropertyByURI(prop.getURI());
if(baseProp == null) {
return false;
}
ObjectProperty possibleFaux = (ObjectProperty) prop;
if (possibleFaux.getDomainPublic() == null) {
return (baseProp.getDomainPublic() != null);
} else {
return !possibleFaux.getDomainPublic().equals(baseProp.getDomainPublic());
}
}
private FauxProperty isFauxProperty(Property prop) {
FauxPropertyDao fpDao = vreq.getUnfilteredWebappDaoFactory().getFauxPropertyDao();
return fpDao.getFauxPropertyByUris(prop.getDomainVClassURI(), prop.getURI(), prop.getRangeVClassURI());
}
protected abstract int getPropertyDisplayTier(Property p);
private Map<String, Object> assembleFauxPropertyValues(FauxProperty fp) {
Map<String, Object> map = new HashMap<>();
String editUrl = UrlBuilder.getUrl("/editForm",
"controller", "FauxProperty",
"baseUri", fp.getBaseURI(),
"domainUri", fp.getDomainURI(),
"rangeUri", fp.getRangeURI());
map.put("propertyEditUrl", editUrl);
map.put("displayName", fp.getDisplayName());
return map;
}
protected abstract int getPropertyDisplayTier(Property p);
protected abstract Route getPropertyEditRoute();
protected void setName(String name) {

View file

@ -231,8 +231,10 @@ name will be used as the label. -->
<#local verboseDisplay = property.verboseDisplay!>
<#if verboseDisplay?has_content>
<section class="verbosePropertyListing">
<#if verboseDisplay.fauxProperty??>
a faux property of
<#if verboseDisplay.fauxProperty?has_content>
<a class="propertyLink" href="${verboseDisplay.fauxProperty.propertyEditUrl}" title="${i18n().name}">
${verboseDisplay.fauxProperty.displayName}
</a>, a faux property of
</#if>
<a class="propertyLink" href="${verboseDisplay.propertyEditUrl}" title="${i18n().name}">${verboseDisplay.localName}</a>
(<span>${property.type?lower_case}</span> property);