Merge branch 'develop' into feature/elk
This commit is contained in:
commit
dad574d33a
74 changed files with 4069 additions and 1465 deletions
|
@ -35,7 +35,6 @@ log4j.rootLogger=INFO, AllAppender
|
|||
|
||||
# These classes are too chatty to display INFO messages.
|
||||
log4j.logger.edu.cornell.mannlib.vitro.webapp.startup.StartupStatus=WARN
|
||||
log4j.logger.edu.cornell.mannlib.vitro.webapp.dao.jena.pellet.PelletListener=WARN
|
||||
log4j.logger.edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase=DEBUG
|
||||
|
||||
# Spring as a whole is too chatty to display INFO messages.
|
||||
|
|
|
@ -874,4 +874,10 @@ view_labels_for = Ver Etiquetas de
|
|||
select_an_existing_document = Seleccione un documento existente
|
||||
|
||||
datetime_year_required = Intervalos de fecha / hora deben empezar por un año. Ingrese una Fecha de inicio, un fin de año o los dos.
|
||||
select_a_language = Seleccione un idioma
|
||||
select_a_language = Seleccione un idioma
|
||||
|
||||
base_property_capitalized = Base propiedad
|
||||
faux_property_capitalized = Faux propiedad
|
||||
faux_property_listing = Lista de faux propiedades
|
||||
faux_property_by_base = Faux propiedades por base propriedad
|
||||
faux_property_alpha = Faux propiedades en orden alfabético
|
|
@ -6,23 +6,27 @@ import java.lang.reflect.Method;
|
|||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.lang.StringEscapeUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vedit.beans.EditProcessObject;
|
||||
import edu.cornell.mannlib.vedit.beans.FormObject;
|
||||
import edu.cornell.mannlib.vedit.beans.Option;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
|
||||
public class FormUtils {
|
||||
|
@ -247,6 +251,35 @@ public class FormUtils {
|
|||
}
|
||||
return vclassOptionList;
|
||||
}
|
||||
|
||||
public static List<Option> makeOptionListOfSubVClasses(
|
||||
WebappDaoFactory wadf, String parentVClassUri,
|
||||
String selectedVClassURI) {
|
||||
VClassDao vClassDao = wadf.getVClassDao();
|
||||
|
||||
Set<String> uris = new HashSet<>(vClassDao.getAllSubClassURIs(parentVClassUri));
|
||||
uris.add(parentVClassUri);
|
||||
|
||||
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(selectedVClassURI, vclass.getURI())) {
|
||||
option.setSelected(true);
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(options, new Comparator<Option>() {
|
||||
@Override
|
||||
public int compare(Option o1, Option o2) {
|
||||
return o1.getBody().compareTo(o2.getBody());
|
||||
}});
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
public static void beanSet(Object newObj, String field, String value) {
|
||||
beanSet (newObj, field, value, null);
|
||||
|
|
|
@ -2,12 +2,10 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.auth.permissions;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataPropertyStatement;
|
||||
|
@ -30,10 +28,8 @@ public class DisplayByRolePermission extends Permission {
|
|||
|
||||
private final String roleName;
|
||||
private final RoleLevel roleLevel;
|
||||
private final ServletContext ctx;
|
||||
|
||||
public DisplayByRolePermission(String roleName, RoleLevel roleLevel,
|
||||
ServletContext ctx) {
|
||||
public DisplayByRolePermission(String roleName, RoleLevel roleLevel) {
|
||||
super(NAMESPACE + roleName);
|
||||
|
||||
if (roleName == null) {
|
||||
|
@ -42,13 +38,9 @@ public class DisplayByRolePermission extends Permission {
|
|||
if (roleLevel == null) {
|
||||
throw new NullPointerException("roleLevel may not be null.");
|
||||
}
|
||||
if (ctx == null) {
|
||||
throw new NullPointerException("context may not be null.");
|
||||
}
|
||||
|
||||
this.roleName = roleName;
|
||||
this.roleLevel = roleLevel;
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -110,22 +102,21 @@ public class DisplayByRolePermission extends Permission {
|
|||
* subject, its predicate, and its object.
|
||||
*/
|
||||
private boolean isAuthorized(DisplayObjectPropertyStatement action) {
|
||||
String subjectUri = action.getSubjectUri();
|
||||
String subjectUri = action.getSubjectUri();
|
||||
String objectUri = action.getObjectUri();
|
||||
Property op = action.getProperty();
|
||||
return canDisplayResource(subjectUri)
|
||||
&& canDisplayPredicate(op)
|
||||
return canDisplayResource(subjectUri) && canDisplayPredicate(op)
|
||||
&& canDisplayResource(objectUri);
|
||||
}
|
||||
|
||||
private boolean canDisplayResource(String resourceUri) {
|
||||
return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource(
|
||||
return PropertyRestrictionBean.getBean().canDisplayResource(
|
||||
resourceUri, this.roleLevel);
|
||||
}
|
||||
|
||||
private boolean canDisplayPredicate(Property predicate) {
|
||||
return PropertyRestrictionPolicyHelper.getBean(ctx)
|
||||
.canDisplayPredicate(predicate, this.roleLevel);
|
||||
return PropertyRestrictionBean.getBean().canDisplayPredicate(predicate,
|
||||
this.roleLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,12 +2,10 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.auth.permissions;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyStatementAction;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction;
|
||||
|
@ -27,10 +25,8 @@ public class EditByRolePermission extends Permission {
|
|||
|
||||
private final String roleName;
|
||||
private final RoleLevel roleLevel;
|
||||
private final ServletContext ctx;
|
||||
|
||||
public EditByRolePermission(String roleName, RoleLevel roleLevel,
|
||||
ServletContext ctx) {
|
||||
public EditByRolePermission(String roleName, RoleLevel roleLevel) {
|
||||
super(NAMESPACE + roleName);
|
||||
|
||||
if (roleName == null) {
|
||||
|
@ -39,13 +35,9 @@ public class EditByRolePermission extends Permission {
|
|||
if (roleLevel == null) {
|
||||
throw new NullPointerException("roleLevel may not be null.");
|
||||
}
|
||||
if (ctx == null) {
|
||||
throw new NullPointerException("context may not be null.");
|
||||
}
|
||||
|
||||
this.roleName = roleName;
|
||||
this.roleLevel = roleLevel;
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,8 +72,7 @@ public class EditByRolePermission extends Permission {
|
|||
private boolean isAuthorized(AbstractDataPropertyStatementAction action) {
|
||||
String subjectUri = action.getSubjectUri();
|
||||
Property predicate = action.getPredicate();
|
||||
return canModifyResource(subjectUri)
|
||||
&& canModifyPredicate(predicate);
|
||||
return canModifyResource(subjectUri) && canModifyPredicate(predicate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,19 +83,18 @@ public class EditByRolePermission extends Permission {
|
|||
String subjectUri = action.getSubjectUri();
|
||||
Property predicate = action.getPredicate();
|
||||
String objectUri = action.getObjectUri();
|
||||
return canModifyResource(subjectUri)
|
||||
&& canModifyPredicate(predicate)
|
||||
return canModifyResource(subjectUri) && canModifyPredicate(predicate)
|
||||
&& canModifyResource(objectUri);
|
||||
}
|
||||
|
||||
private boolean canModifyResource(String resourceUri) {
|
||||
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource(
|
||||
resourceUri, roleLevel);
|
||||
return PropertyRestrictionBean.getBean().canModifyResource(resourceUri,
|
||||
roleLevel);
|
||||
}
|
||||
|
||||
private boolean canModifyPredicate(Property predicate) {
|
||||
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate(
|
||||
predicate, roleLevel);
|
||||
return PropertyRestrictionBean.getBean().canModifyPredicate(predicate,
|
||||
roleLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -150,9 +150,9 @@ public class PermissionRegistry {
|
|||
List<Permission> permissions = new ArrayList<Permission>();
|
||||
|
||||
permissions.addAll(SimplePermission.getAllInstances());
|
||||
permissions.addAll(createDisplayByRolePermissions(ctx));
|
||||
permissions.addAll(createEditByRolePermissions(ctx));
|
||||
permissions.addAll(createPublishByRolePermissions(ctx));
|
||||
permissions.addAll(createDisplayByRolePermissions());
|
||||
permissions.addAll(createEditByRolePermissions());
|
||||
permissions.addAll(createPublishByRolePermissions());
|
||||
|
||||
PermissionRegistry.createRegistry(ctx, permissions);
|
||||
|
||||
|
@ -169,17 +169,12 @@ public class PermissionRegistry {
|
|||
* same rights as PUBLIC. Other permissions give them their self-editing
|
||||
* privileges.
|
||||
*/
|
||||
private Collection<Permission> createDisplayByRolePermissions(
|
||||
ServletContext ctx) {
|
||||
private Collection<Permission> createDisplayByRolePermissions() {
|
||||
List<Permission> list = new ArrayList<Permission>();
|
||||
list.add(new DisplayByRolePermission("Admin", RoleLevel.DB_ADMIN,
|
||||
ctx));
|
||||
list.add(new DisplayByRolePermission("Curator", RoleLevel.CURATOR,
|
||||
ctx));
|
||||
list.add(new DisplayByRolePermission("Editor", RoleLevel.EDITOR,
|
||||
ctx));
|
||||
list.add(new DisplayByRolePermission("Public", RoleLevel.PUBLIC,
|
||||
ctx));
|
||||
list.add(new DisplayByRolePermission("Admin", RoleLevel.DB_ADMIN));
|
||||
list.add(new DisplayByRolePermission("Curator", RoleLevel.CURATOR));
|
||||
list.add(new DisplayByRolePermission("Editor", RoleLevel.EDITOR));
|
||||
list.add(new DisplayByRolePermission("Public", RoleLevel.PUBLIC));
|
||||
return list;
|
||||
}
|
||||
|
||||
|
@ -191,12 +186,11 @@ public class PermissionRegistry {
|
|||
*
|
||||
* Other permissions give self-editors their editing privileges.
|
||||
*/
|
||||
private Collection<Permission> createEditByRolePermissions(
|
||||
ServletContext ctx) {
|
||||
private Collection<Permission> createEditByRolePermissions() {
|
||||
List<Permission> list = new ArrayList<Permission>();
|
||||
list.add(new EditByRolePermission("Admin", RoleLevel.DB_ADMIN, ctx));
|
||||
list.add(new EditByRolePermission("Curator", RoleLevel.CURATOR, ctx));
|
||||
list.add(new EditByRolePermission("Editor", RoleLevel.EDITOR, ctx));
|
||||
list.add(new EditByRolePermission("Admin", RoleLevel.DB_ADMIN));
|
||||
list.add(new EditByRolePermission("Curator", RoleLevel.CURATOR));
|
||||
list.add(new EditByRolePermission("Editor", RoleLevel.EDITOR));
|
||||
return list;
|
||||
}
|
||||
|
||||
|
@ -210,17 +204,12 @@ public class PermissionRegistry {
|
|||
* same rights as PUBLIC. Other permissions give them their self-editing
|
||||
* privileges.
|
||||
*/
|
||||
private Collection<Permission> createPublishByRolePermissions(
|
||||
ServletContext ctx) {
|
||||
private Collection<Permission> createPublishByRolePermissions() {
|
||||
List<Permission> list = new ArrayList<Permission>();
|
||||
list.add(new PublishByRolePermission("Admin", RoleLevel.DB_ADMIN,
|
||||
ctx));
|
||||
list.add(new PublishByRolePermission("Curator", RoleLevel.CURATOR,
|
||||
ctx));
|
||||
list.add(new PublishByRolePermission("Editor", RoleLevel.EDITOR,
|
||||
ctx));
|
||||
list.add(new PublishByRolePermission("Public", RoleLevel.PUBLIC,
|
||||
ctx));
|
||||
list.add(new PublishByRolePermission("Admin", RoleLevel.DB_ADMIN));
|
||||
list.add(new PublishByRolePermission("Curator", RoleLevel.CURATOR));
|
||||
list.add(new PublishByRolePermission("Editor", RoleLevel.EDITOR));
|
||||
list.add(new PublishByRolePermission("Public", RoleLevel.PUBLIC));
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,10 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.auth.permissions;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishDataProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishDataPropertyStatement;
|
||||
|
@ -29,10 +27,8 @@ public class PublishByRolePermission extends Permission {
|
|||
|
||||
private final String roleName;
|
||||
private final RoleLevel roleLevel;
|
||||
private final ServletContext ctx;
|
||||
|
||||
public PublishByRolePermission(String roleName, RoleLevel roleLevel,
|
||||
ServletContext ctx) {
|
||||
public PublishByRolePermission(String roleName, RoleLevel roleLevel) {
|
||||
super(NAMESPACE + roleName);
|
||||
|
||||
if (roleName == null) {
|
||||
|
@ -41,13 +37,9 @@ public class PublishByRolePermission extends Permission {
|
|||
if (roleLevel == null) {
|
||||
throw new NullPointerException("roleLevel may not be null.");
|
||||
}
|
||||
if (ctx == null) {
|
||||
throw new NullPointerException("context may not be null.");
|
||||
}
|
||||
|
||||
this.roleName = roleName;
|
||||
this.roleLevel = roleLevel;
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -116,13 +108,13 @@ public class PublishByRolePermission extends Permission {
|
|||
}
|
||||
|
||||
private boolean canPublishResource(String resourceUri) {
|
||||
return PropertyRestrictionPolicyHelper.getBean(ctx).canPublishResource(
|
||||
return PropertyRestrictionBean.getBean().canPublishResource(
|
||||
resourceUri, this.roleLevel);
|
||||
}
|
||||
|
||||
private boolean canPublishPredicate(Property predicate) {
|
||||
return PropertyRestrictionPolicyHelper.getBean(ctx)
|
||||
.canPublishPredicate(predicate, this.roleLevel);
|
||||
return PropertyRestrictionBean.getBean().canPublishPredicate(predicate,
|
||||
this.roleLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -4,7 +4,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.policy;
|
|||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
|
||||
|
@ -23,13 +23,13 @@ public abstract class BaseSelfEditingPolicy {
|
|||
}
|
||||
|
||||
protected boolean canModifyResource(String uri) {
|
||||
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource(
|
||||
uri, roleLevel);
|
||||
return PropertyRestrictionBean.getBean().canModifyResource(uri,
|
||||
roleLevel);
|
||||
}
|
||||
|
||||
protected boolean canModifyPredicate(Property predicate) {
|
||||
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate(
|
||||
predicate, roleLevel);
|
||||
return PropertyRestrictionBean.getBean().canModifyPredicate(predicate,
|
||||
roleLevel);
|
||||
}
|
||||
|
||||
protected PolicyDecision cantModifyResource(String uri) {
|
||||
|
|
|
@ -11,7 +11,7 @@ import org.apache.commons.logging.LogFactory;
|
|||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasAssociatedIndividual;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
|
||||
|
@ -114,14 +114,18 @@ public class DisplayRestrictedDataToSelfPolicy implements PolicyIface {
|
|||
String subjectUri = action.getSubjectUri();
|
||||
Property predicate = action.getProperty();
|
||||
String objectUri = action.getObjectUri();
|
||||
if (canDisplayResource(subjectUri) && canDisplayPredicate(predicate)
|
||||
if (canDisplayResource(subjectUri)
|
||||
&& canDisplayPredicate(predicate)
|
||||
&& canDisplayResource(objectUri)
|
||||
&& isAboutAssociatedIndividual(individuals, subjectUri, objectUri)) {
|
||||
&& isAboutAssociatedIndividual(individuals, subjectUri,
|
||||
objectUri)) {
|
||||
return authorized("user may view ObjectPropertyStatement "
|
||||
+ subjectUri + " ==> " + predicate.getURI() + " ==> " + objectUri);
|
||||
+ subjectUri + " ==> " + predicate.getURI() + " ==> "
|
||||
+ objectUri);
|
||||
} else {
|
||||
return defaultDecision("user may not view ObjectPropertyStatement "
|
||||
+ subjectUri + " ==> " + predicate.getURI() + " ==> " + objectUri);
|
||||
+ subjectUri + " ==> " + predicate.getURI() + " ==> "
|
||||
+ objectUri);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,13 +142,13 @@ public class DisplayRestrictedDataToSelfPolicy implements PolicyIface {
|
|||
}
|
||||
|
||||
private boolean canDisplayResource(String uri) {
|
||||
return PropertyRestrictionPolicyHelper.getBean(ctx).canDisplayResource(
|
||||
uri, RoleLevel.SELF);
|
||||
return PropertyRestrictionBean.getBean().canDisplayResource(uri,
|
||||
RoleLevel.SELF);
|
||||
}
|
||||
|
||||
private boolean canDisplayPredicate(Property predicate) {
|
||||
return PropertyRestrictionPolicyHelper.getBean(ctx)
|
||||
.canDisplayPredicate(predicate, RoleLevel.SELF);
|
||||
return PropertyRestrictionBean.getBean().canDisplayPredicate(predicate,
|
||||
RoleLevel.SELF);
|
||||
}
|
||||
|
||||
private boolean isAboutAssociatedIndividual(Collection<String> selves,
|
||||
|
|
|
@ -0,0 +1,207 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.auth.policy.bean;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
|
||||
/**
|
||||
* Assists the role-based policies in determining whether a property or resource
|
||||
* may be displayed, modified, or published in linked open data.
|
||||
*
|
||||
* There is a singleton bean that holds the current threshold role levels for
|
||||
* displaying, modifying, or publishing restricted properties.
|
||||
*
|
||||
* Create this bean after the context models are in place.
|
||||
*
|
||||
* Add PropertyRestrictionListener to your EditProcessObject if you are editing
|
||||
* a property, to ensure that the bean stays current.
|
||||
*/
|
||||
public abstract class PropertyRestrictionBean {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(PropertyRestrictionBean.class);
|
||||
|
||||
private static final PropertyRestrictionBean NULL = new PropertyRestrictionBeanNull();
|
||||
|
||||
protected static volatile PropertyRestrictionBean instance = NULL;
|
||||
|
||||
protected static final Collection<String> PROHIBITED_NAMESPACES = Arrays
|
||||
.asList(new String[] { VitroVocabulary.vitroURI, "" });
|
||||
|
||||
protected static final Collection<String> PERMITTED_EXCEPTIONS = Arrays
|
||||
.asList(new String[] { VitroVocabulary.MONIKER,
|
||||
VitroVocabulary.MODTIME, VitroVocabulary.IND_MAIN_IMAGE,
|
||||
VitroVocabulary.LINK, VitroVocabulary.PRIMARY_LINK,
|
||||
VitroVocabulary.ADDITIONAL_LINK,
|
||||
VitroVocabulary.LINK_ANCHOR, VitroVocabulary.LINK_URL });
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// static methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public static PropertyRestrictionBean getBean() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// instance methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Any resource can be displayed.
|
||||
*
|
||||
* (Someday we may want to implement display restrictions based on VClass.)
|
||||
*/
|
||||
public abstract boolean canDisplayResource(String resourceUri,
|
||||
RoleLevel userRole);
|
||||
|
||||
/**
|
||||
* A resource cannot be modified if its namespace is in the prohibited list
|
||||
* (but some exceptions are allowed).
|
||||
*
|
||||
* (Someday we may want to implement modify restrictions based on VClass.)
|
||||
*/
|
||||
public abstract boolean canModifyResource(String resourceUri,
|
||||
RoleLevel userRole);
|
||||
|
||||
/**
|
||||
* Any resource can be published.
|
||||
*
|
||||
* (Someday we may want to implement publish restrictions based on VClass.)
|
||||
*/
|
||||
public abstract boolean canPublishResource(String resourceUri,
|
||||
RoleLevel userRole);
|
||||
|
||||
/**
|
||||
* If display of a predicate is restricted, the user's role must be at least
|
||||
* as high as the restriction level.
|
||||
*/
|
||||
public abstract boolean canDisplayPredicate(Property predicate,
|
||||
RoleLevel userRole);
|
||||
|
||||
/**
|
||||
* A predicate cannot be modified if its namespace is in the prohibited list
|
||||
* (some exceptions are allowed).
|
||||
*
|
||||
* If modification of a predicate is restricted, the user's role must be at
|
||||
* least as high as the restriction level.
|
||||
*/
|
||||
public abstract boolean canModifyPredicate(Property predicate,
|
||||
RoleLevel userRole);
|
||||
|
||||
/**
|
||||
* If publishing of a predicate is restricted, the user's role must be at
|
||||
* least as high as the restriction level.
|
||||
*/
|
||||
public abstract boolean canPublishPredicate(Property predicate,
|
||||
RoleLevel userRole);
|
||||
|
||||
/**
|
||||
* The threshold values for this property may have changed.
|
||||
*/
|
||||
public abstract void updateProperty(PropertyRestrictionLevels levels);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// The null implementation
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A placeholder for when the bean instance is not set.
|
||||
*/
|
||||
private static class PropertyRestrictionBeanNull extends
|
||||
PropertyRestrictionBean {
|
||||
@Override
|
||||
public boolean canDisplayResource(String resourceUri, RoleLevel userRole) {
|
||||
warn();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canModifyResource(String resourceUri, RoleLevel userRole) {
|
||||
warn();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPublishResource(String resourceUri, RoleLevel userRole) {
|
||||
warn();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDisplayPredicate(Property predicate,
|
||||
RoleLevel userRole) {
|
||||
warn();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canModifyPredicate(Property predicate, RoleLevel userRole) {
|
||||
warn();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPublishPredicate(Property predicate,
|
||||
RoleLevel userRole) {
|
||||
warn();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProperty(PropertyRestrictionLevels levels) {
|
||||
warn();
|
||||
}
|
||||
|
||||
private void warn() {
|
||||
try {
|
||||
throw new IllegalStateException();
|
||||
} catch (IllegalStateException e) {
|
||||
log.warn("No PropertyRestrictionBean in place.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Setup class
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create the bean at startup and remove it at shutdown.
|
||||
*/
|
||||
public static class Setup implements ServletContextListener {
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
ServletContext ctx = sce.getServletContext();
|
||||
StartupStatus ss = StartupStatus.getBean(ctx);
|
||||
|
||||
try {
|
||||
instance = new PropertyRestrictionBeanImpl(
|
||||
PROHIBITED_NAMESPACES, PERMITTED_EXCEPTIONS,
|
||||
ModelAccess.on(ctx));
|
||||
} catch (Exception e) {
|
||||
ss.fatal(this,
|
||||
"could not set up PropertyRestrictionBean", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
instance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,252 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.auth.policy.bean;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which.DISPLAY;
|
||||
import static edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which.MODIFY;
|
||||
import static edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which.PUBLISH;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.hp.hpl.jena.rdf.model.impl.Util;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.DataProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess;
|
||||
|
||||
/**
|
||||
* On creation, populate a map of PropertyRestrictionLevels.
|
||||
*
|
||||
* When a change is detected, update the map accordingly.
|
||||
*
|
||||
* ------------------------------
|
||||
*
|
||||
* How is authorization determined?
|
||||
*
|
||||
* Resources are easy. If they aren't in a prohibited namespace, or are an
|
||||
* exception to the prohibition, they are accessible.
|
||||
*
|
||||
* Properties are harder. The prohibited namespace and exceptions still apply,
|
||||
* but if we pass that test, then we check the threshold map.
|
||||
*
|
||||
* When a test is made, we look for thresholds in the map. First we look for the
|
||||
* full key of domain-base-range, in case we are testing a faux property. Faux
|
||||
* properties are recorded in the map with the full key.
|
||||
*
|
||||
* If we don't find the full key, then perhaps we are testing a faux property
|
||||
* that has no settings, or perhaps we are testing an object property. We look
|
||||
* for the partial key of null-base-null, which covers both of these cases,
|
||||
* since object properties (and data properties) are recorded the map with a
|
||||
* partial key.
|
||||
*
|
||||
* Similarly, if we find a null threshold value in the full key, we look back to
|
||||
* the partial key for a threshold.
|
||||
*
|
||||
* If we find no non-null threshold value then the property is unrestricted for
|
||||
* that feature.
|
||||
*
|
||||
* -----------------------------
|
||||
*
|
||||
* It would perhaps be a silly optimization, but if we find a key with 3 null
|
||||
* thresholds, we could remove it from the map without changing the behavior.
|
||||
*/
|
||||
public class PropertyRestrictionBeanImpl extends PropertyRestrictionBean {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(PropertyRestrictionBeanImpl.class);
|
||||
|
||||
private final Set<String> prohibitedNamespaces;
|
||||
private final Set<String> permittedExceptions;
|
||||
|
||||
private final Map<FullPropertyKey, PropertyRestrictionLevels> thresholdMap = new ConcurrentHashMap<>();
|
||||
|
||||
public PropertyRestrictionBeanImpl(Collection<String> prohibitedNamespaces,
|
||||
Collection<String> permittedExceptions, ContextModelAccess models) {
|
||||
Objects.requireNonNull(prohibitedNamespaces,
|
||||
"prohibitedNamespaces may not be null.");
|
||||
this.prohibitedNamespaces = Collections.unmodifiableSet(new TreeSet<>(
|
||||
prohibitedNamespaces));
|
||||
|
||||
Objects.requireNonNull(permittedExceptions,
|
||||
"permittedExceptions may not be null.");
|
||||
this.permittedExceptions = Collections.unmodifiableSet(new TreeSet<>(
|
||||
permittedExceptions));
|
||||
|
||||
Objects.requireNonNull(models, "models may not be null.");
|
||||
populateThresholdMap(models.getWebappDaoFactory());
|
||||
}
|
||||
|
||||
private void populateThresholdMap(WebappDaoFactory wadf) {
|
||||
for (ObjectProperty oProp : wadf.getObjectPropertyDao()
|
||||
.getAllObjectProperties()) {
|
||||
addObjectPropertyToMap(oProp);
|
||||
for (FauxProperty fProp : wadf.getFauxPropertyDao()
|
||||
.getFauxPropertiesForBaseUri(oProp.getURI())) {
|
||||
addFauxPropertyToMap(fProp);
|
||||
}
|
||||
}
|
||||
for (DataProperty dProp : wadf.getDataPropertyDao()
|
||||
.getAllDataProperties()) {
|
||||
addDataPropertyToMap(dProp);
|
||||
}
|
||||
}
|
||||
|
||||
private void addObjectPropertyToMap(ObjectProperty oProp) {
|
||||
FullPropertyKey key = new FullPropertyKey(oProp.getURI());
|
||||
PropertyRestrictionLevels levels = new PropertyRestrictionLevels(key,
|
||||
oProp.getHiddenFromDisplayBelowRoleLevel(),
|
||||
oProp.getProhibitedFromUpdateBelowRoleLevel(),
|
||||
oProp.getHiddenFromPublishBelowRoleLevel());
|
||||
thresholdMap.put(key, levels);
|
||||
}
|
||||
|
||||
private void addFauxPropertyToMap(FauxProperty fProp) {
|
||||
FullPropertyKey key = new FullPropertyKey(fProp.getDomainURI(),
|
||||
fProp.getBaseURI(), fProp.getRangeURI());
|
||||
PropertyRestrictionLevels levels = new PropertyRestrictionLevels(key,
|
||||
fProp.getHiddenFromDisplayBelowRoleLevel(),
|
||||
fProp.getProhibitedFromUpdateBelowRoleLevel(),
|
||||
fProp.getHiddenFromPublishBelowRoleLevel());
|
||||
thresholdMap.put(key, levels);
|
||||
}
|
||||
|
||||
private void addDataPropertyToMap(DataProperty dProp) {
|
||||
FullPropertyKey key = new FullPropertyKey(dProp.getURI());
|
||||
PropertyRestrictionLevels levels = new PropertyRestrictionLevels(key,
|
||||
dProp.getHiddenFromDisplayBelowRoleLevel(),
|
||||
dProp.getProhibitedFromUpdateBelowRoleLevel(),
|
||||
dProp.getHiddenFromPublishBelowRoleLevel());
|
||||
thresholdMap.put(key, levels);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDisplayResource(String resourceUri, RoleLevel userRole) {
|
||||
return (resourceUri != null) && (userRole != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canModifyResource(String resourceUri, RoleLevel userRole) {
|
||||
if (resourceUri == null || userRole == null) {
|
||||
return false;
|
||||
}
|
||||
if (prohibitedNamespaces.contains(namespace(resourceUri))
|
||||
&& !permittedExceptions.contains(resourceUri)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPublishResource(String resourceUri, RoleLevel userRole) {
|
||||
return (resourceUri != null) && (userRole != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDisplayPredicate(Property predicate, RoleLevel userRole) {
|
||||
if (predicate == null || predicate.getURI() == null) {
|
||||
return false;
|
||||
}
|
||||
return isAuthorized(userRole, getThreshold(predicate, DISPLAY));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canModifyPredicate(Property predicate, RoleLevel userRole) {
|
||||
if (predicate == null || predicate.getURI() == null) {
|
||||
return false;
|
||||
}
|
||||
return isAuthorized(userRole, getPropertyModifyThreshold(predicate));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPublishPredicate(Property predicate, RoleLevel userRole) {
|
||||
if (predicate == null || predicate.getURI() == null) {
|
||||
return false;
|
||||
}
|
||||
return isAuthorized(userRole, getThreshold(predicate, PUBLISH));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProperty(PropertyRestrictionLevels levels) {
|
||||
thresholdMap.put(levels.getKey(), levels);
|
||||
}
|
||||
|
||||
private boolean isAuthorized(RoleLevel userRole, RoleLevel thresholdRole) {
|
||||
if (userRole == null) {
|
||||
return false;
|
||||
}
|
||||
if (thresholdRole == null) {
|
||||
return true;
|
||||
}
|
||||
return userRole.compareTo(thresholdRole) >= 0;
|
||||
}
|
||||
|
||||
private RoleLevel getPropertyModifyThreshold(Property p) {
|
||||
if (prohibitedNamespaces.contains(namespace(p.getURI()))
|
||||
&& !permittedExceptions.contains(p.getURI())) {
|
||||
return RoleLevel.NOBODY;
|
||||
}
|
||||
return getThreshold(p, MODIFY);
|
||||
}
|
||||
|
||||
private RoleLevel getThreshold(Property p, Which which) {
|
||||
RoleLevel qualifiedLevel = getThreshold(new FullPropertyKey(p), which);
|
||||
if (qualifiedLevel != null) {
|
||||
return qualifiedLevel;
|
||||
}
|
||||
|
||||
RoleLevel bareLevel = getThreshold(new FullPropertyKey(p.getURI()),
|
||||
which);
|
||||
return bareLevel;
|
||||
}
|
||||
|
||||
private RoleLevel getThreshold(FullPropertyKey key, Which which) {
|
||||
PropertyRestrictionLevels levels = thresholdMap.get(key);
|
||||
if (levels == null) {
|
||||
return null;
|
||||
} else {
|
||||
return levels.getLevel(which);
|
||||
}
|
||||
}
|
||||
|
||||
private String namespace(String uri) {
|
||||
return uri.substring(0, Util.splitNamespace(uri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
SortedSet<FullPropertyKey> keys = new TreeSet<>(
|
||||
new Comparator<FullPropertyKey>() {
|
||||
@Override
|
||||
public int compare(FullPropertyKey o1, FullPropertyKey o2) {
|
||||
return o1.toString().compareTo(o2.toString());
|
||||
}
|
||||
});
|
||||
keys.addAll(thresholdMap.keySet());
|
||||
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
for (FullPropertyKey key : keys) {
|
||||
buffer.append(key + " " + thresholdMap.get(key).getLevel(DISPLAY)
|
||||
+ " " + thresholdMap.get(key).getLevel(MODIFY) + " "
|
||||
+ thresholdMap.get(key).getLevel(PUBLISH) + "\n");
|
||||
}
|
||||
return buffer.toString();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.auth.policy.bean;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey;
|
||||
|
||||
/**
|
||||
* The threshold levels for operations on a given property.
|
||||
*
|
||||
* This is based on the assumption that the FullPropertyKey is sufficient to
|
||||
* distinguish all properties. An object property and a data property may not
|
||||
* share the same key. A faux property must have a different key from any object
|
||||
* property.
|
||||
*/
|
||||
public class PropertyRestrictionLevels {
|
||||
private final FullPropertyKey key;
|
||||
private final RoleLevel displayThreshold;
|
||||
private final RoleLevel modifyThreshold;
|
||||
private final RoleLevel publishThreshold;
|
||||
|
||||
public enum Which {
|
||||
DISPLAY, MODIFY, PUBLISH
|
||||
}
|
||||
|
||||
public PropertyRestrictionLevels(FullPropertyKey key,
|
||||
RoleRestrictedProperty p) {
|
||||
this(key, p.getHiddenFromDisplayBelowRoleLevel(), p
|
||||
.getProhibitedFromUpdateBelowRoleLevel(), p
|
||||
.getHiddenFromPublishBelowRoleLevel());
|
||||
}
|
||||
|
||||
public PropertyRestrictionLevels(FullPropertyKey key,
|
||||
RoleLevel displayThreshold, RoleLevel modifyThreshold,
|
||||
RoleLevel publishThreshold) {
|
||||
this.key = key;
|
||||
this.displayThreshold = displayThreshold;
|
||||
this.modifyThreshold = modifyThreshold;
|
||||
this.publishThreshold = publishThreshold;
|
||||
}
|
||||
|
||||
public FullPropertyKey getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public RoleLevel getLevel(Which which) {
|
||||
if (which == null) {
|
||||
return null;
|
||||
} else {
|
||||
switch (which) {
|
||||
case DISPLAY:
|
||||
return displayThreshold;
|
||||
case MODIFY:
|
||||
return modifyThreshold;
|
||||
default:
|
||||
return publishThreshold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PropertyRestrictionLevels[key=" + key + ", display="
|
||||
+ displayThreshold + ", modify=" + modifyThreshold
|
||||
+ ", publish=" + publishThreshold + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -2,21 +2,12 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.auth.policy.bean;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
|
||||
import edu.cornell.mannlib.vedit.beans.EditProcessObject;
|
||||
import edu.cornell.mannlib.vedit.listener.ChangeListener;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey;
|
||||
|
||||
/**
|
||||
* Add this ChangeListener to your EditProcessObject when modifying the
|
||||
|
@ -27,83 +18,50 @@ public class PropertyRestrictionListener implements ChangeListener {
|
|||
private static final Log log = LogFactory
|
||||
.getLog(PropertyRestrictionListener.class);
|
||||
|
||||
private final ServletContext ctx;
|
||||
|
||||
public PropertyRestrictionListener(ServletContext ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the deleted property had a non-null restriction, rebuild the bean.
|
||||
*/
|
||||
@Override
|
||||
public void doDeleted(Object oldObj, EditProcessObject epo) {
|
||||
Property p = (Property) oldObj;
|
||||
if (anyRoleChanged(p.getHiddenFromDisplayBelowRoleLevel(),
|
||||
p.getProhibitedFromUpdateBelowRoleLevel(),
|
||||
p.getHiddenFromPublishBelowRoleLevel(), null, null, null)) {
|
||||
log.debug("rebuilding the PropertyRestrictionPolicyHelper after deletion");
|
||||
createAndSetBean();
|
||||
if (oldObj instanceof RoleRestrictedProperty) {
|
||||
RoleRestrictedProperty p = (RoleRestrictedProperty) oldObj;
|
||||
FullPropertyKey key = new FullPropertyKey(p);
|
||||
updateLevels(new PropertyRestrictionLevels(key, p));
|
||||
} else {
|
||||
log.warn("Not an instance of RoleRestrictedProperty: " + oldObj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the inserted property has a non-null restriction, rebuild the bean.
|
||||
* Update the inserted property.
|
||||
*/
|
||||
@Override
|
||||
public void doInserted(Object newObj, EditProcessObject epo) {
|
||||
Property p = (Property) newObj;
|
||||
if (anyRoleChanged(null, null, null,
|
||||
p.getHiddenFromDisplayBelowRoleLevel(),
|
||||
p.getProhibitedFromUpdateBelowRoleLevel(),
|
||||
p.getHiddenFromPublishBelowRoleLevel())) {
|
||||
log.debug("rebuilding the PropertyRestrictionPolicyHelper after insertion");
|
||||
createAndSetBean();
|
||||
if (newObj instanceof RoleRestrictedProperty) {
|
||||
RoleRestrictedProperty p = (RoleRestrictedProperty) newObj;
|
||||
FullPropertyKey key = new FullPropertyKey(p);
|
||||
updateLevels(new PropertyRestrictionLevels(key, p));
|
||||
} else {
|
||||
log.warn("Not an instance of RoleRestrictedProperty: " + newObj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the updated property has changed its restrictions, rebuild the bean.
|
||||
* Update the changed property.
|
||||
*/
|
||||
@Override
|
||||
public void doUpdated(Object oldObj, Object newObj, EditProcessObject epo) {
|
||||
Property oldP = (Property) oldObj;
|
||||
Property newP = (Property) newObj;
|
||||
if (anyRoleChanged(oldP.getHiddenFromDisplayBelowRoleLevel(),
|
||||
oldP.getProhibitedFromUpdateBelowRoleLevel(),
|
||||
oldP.getHiddenFromPublishBelowRoleLevel(),
|
||||
newP.getHiddenFromDisplayBelowRoleLevel(),
|
||||
newP.getProhibitedFromUpdateBelowRoleLevel(),
|
||||
newP.getHiddenFromPublishBelowRoleLevel())) {
|
||||
log.debug("rebuilding the PropertyRestrictionPolicyHelper after update");
|
||||
createAndSetBean();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean anyRoleChanged(RoleLevel oldDisplayRole,
|
||||
RoleLevel oldUpdateRole, RoleLevel oldPublishRole,
|
||||
RoleLevel newDisplayRole, RoleLevel newUpdateRole,
|
||||
RoleLevel newPublishRole) {
|
||||
return (!isTheSame(oldDisplayRole, newDisplayRole))
|
||||
|| (!isTheSame(oldUpdateRole, newUpdateRole))
|
||||
|| (!isTheSame(oldPublishRole, newPublishRole));
|
||||
}
|
||||
|
||||
private boolean isTheSame(RoleLevel oldRole, RoleLevel newRole) {
|
||||
if ((oldRole == null) && (newRole == null)) {
|
||||
return true;
|
||||
} else if ((oldRole == null) || (newRole == null)) {
|
||||
return false;
|
||||
if (newObj instanceof RoleRestrictedProperty) {
|
||||
RoleRestrictedProperty newP = (RoleRestrictedProperty) newObj;
|
||||
FullPropertyKey key = new FullPropertyKey(newP);
|
||||
updateLevels(new PropertyRestrictionLevels(key, newP));
|
||||
} else {
|
||||
return oldRole.compareTo(newRole) == 0;
|
||||
log.warn("Not instances of RoleRestrictedProperty: " + oldObj
|
||||
+ ", " + newObj);
|
||||
}
|
||||
}
|
||||
|
||||
private void createAndSetBean() {
|
||||
OntModel model = ModelAccess.on(ctx).getOntModel();
|
||||
Model displayModel = ModelAccess.on(ctx).getOntModel(DISPLAY);
|
||||
PropertyRestrictionPolicyHelper bean = PropertyRestrictionPolicyHelper
|
||||
.createBean(model, displayModel);
|
||||
PropertyRestrictionPolicyHelper.setBean(ctx, bean);
|
||||
private void updateLevels(PropertyRestrictionLevels levels) {
|
||||
PropertyRestrictionBean.getBean().updateProperty(levels);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,498 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.auth.policy.bean;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.DISPLAY;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.ontology.OntModelSpec;
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
||||
import com.hp.hpl.jena.rdf.model.Resource;
|
||||
import com.hp.hpl.jena.rdf.model.Statement;
|
||||
import com.hp.hpl.jena.rdf.model.StmtIterator;
|
||||
import com.hp.hpl.jena.rdf.model.impl.Util;
|
||||
import com.hp.hpl.jena.shared.Lock;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.ApplicationConfigurationOntologyUtils;
|
||||
|
||||
/**
|
||||
* Assists the role-based policies in determining whether a property or resource
|
||||
* may be displayed, modified, or published in linked open data.
|
||||
*
|
||||
* There is a bean in the context that holds the current threshold role levels
|
||||
* for displaying, modifying, or publishing restricted properties.
|
||||
*
|
||||
* Create this bean after the Jena model is in place in the context.
|
||||
*
|
||||
* Add PropertyRestrictionListener to your EditProcessObject if you are editing
|
||||
* a property, to ensure that the bean stays current.
|
||||
*/
|
||||
public class PropertyRestrictionPolicyHelper {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(PropertyRestrictionPolicyHelper.class);
|
||||
|
||||
private static final Collection<String> PROHIBITED_NAMESPACES = Arrays
|
||||
.asList(new String[] { VitroVocabulary.vitroURI, "" });
|
||||
|
||||
private static final Collection<String> PERMITTED_EXCEPTIONS = Arrays
|
||||
.asList(new String[] {
|
||||
VitroVocabulary.MONIKER,
|
||||
VitroVocabulary.MODTIME,
|
||||
|
||||
VitroVocabulary.IND_MAIN_IMAGE,
|
||||
|
||||
VitroVocabulary.LINK,
|
||||
VitroVocabulary.PRIMARY_LINK,
|
||||
VitroVocabulary.ADDITIONAL_LINK,
|
||||
VitroVocabulary.LINK_ANCHOR,
|
||||
VitroVocabulary.LINK_URL });
|
||||
|
||||
/**
|
||||
* The bean is attached to the ServletContext using this attribute name.
|
||||
*/
|
||||
private static final String ATTRIBUTE_NAME = PropertyRestrictionPolicyHelper.class
|
||||
.getName();
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// static methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public static PropertyRestrictionPolicyHelper getBean(ServletContext ctx) {
|
||||
Object attribute = ctx.getAttribute(ATTRIBUTE_NAME);
|
||||
if (!(attribute instanceof PropertyRestrictionPolicyHelper)) {
|
||||
throw new IllegalStateException(
|
||||
"PropertyRestrictionPolicyHelper has not been initialized.");
|
||||
}
|
||||
return (PropertyRestrictionPolicyHelper) attribute;
|
||||
}
|
||||
|
||||
private static void removeBean(ServletContext ctx) {
|
||||
ctx.removeAttribute(ATTRIBUTE_NAME);
|
||||
}
|
||||
|
||||
public static void setBean(ServletContext ctx,
|
||||
PropertyRestrictionPolicyHelper bean) {
|
||||
if (bean == null) {
|
||||
throw new NullPointerException("bean may not be null.");
|
||||
}
|
||||
ctx.setAttribute(ATTRIBUTE_NAME, bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the bean with the standard prohibitions and exceptions, and
|
||||
* with the thresholds obtained from the model.
|
||||
*/
|
||||
public static PropertyRestrictionPolicyHelper createBean(OntModel model,
|
||||
Model displayModel) {
|
||||
|
||||
|
||||
Map<FullPropertyKey, RoleLevel> displayThresholdMap =
|
||||
new HashMap<FullPropertyKey, RoleLevel>();
|
||||
Map<FullPropertyKey, RoleLevel> modifyThresholdMap =
|
||||
new HashMap<FullPropertyKey, RoleLevel>();
|
||||
Map<FullPropertyKey, RoleLevel> publishThresholdMap =
|
||||
new HashMap<FullPropertyKey, RoleLevel>();
|
||||
|
||||
OntModel union = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM,
|
||||
ModelFactory.createUnion(displayModel, model));
|
||||
|
||||
|
||||
populateThresholdMap(union, displayThresholdMap,
|
||||
VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT);
|
||||
populateThresholdMap(union, modifyThresholdMap,
|
||||
VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT);
|
||||
populateThresholdMap(union, publishThresholdMap,
|
||||
VitroVocabulary.HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT);
|
||||
|
||||
PropertyRestrictionPolicyHelper bean = new PropertyRestrictionPolicyHelper(
|
||||
PROHIBITED_NAMESPACES, PERMITTED_EXCEPTIONS,
|
||||
displayThresholdMap, modifyThresholdMap, publishThresholdMap);
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
private RoleLevel getModifyThreshold(Property property) {
|
||||
return getThreshold(property, modifyThresholdMap);
|
||||
}
|
||||
|
||||
private RoleLevel getThreshold(Property property,
|
||||
Map<FullPropertyKey, RoleLevel> thresholdMap) {
|
||||
if (property.getURI() == null) {
|
||||
return RoleLevel.NOBODY;
|
||||
}
|
||||
RoleLevel roleLevel = thresholdMap.get(new FullPropertyKey(property));
|
||||
if (roleLevel == null) {
|
||||
roleLevel = thresholdMap
|
||||
.get(new FullPropertyKey(property.getURI()));
|
||||
}
|
||||
return roleLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all the resources that possess this property, and map the resource
|
||||
* URI to the required RoleLevel.
|
||||
*/
|
||||
private static void populateThresholdMap(OntModel model,
|
||||
Map<FullPropertyKey, RoleLevel> map, String propertyUri) {
|
||||
model.enterCriticalSection(Lock.READ);
|
||||
try {
|
||||
com.hp.hpl.jena.rdf.model.Property property = model.getProperty(propertyUri);
|
||||
StmtIterator stmts = model.listStatements((Resource) null,
|
||||
property, (Resource) null);
|
||||
try {
|
||||
while (stmts.hasNext()) {
|
||||
Statement stmt = stmts.next();
|
||||
Resource subject = stmt.getSubject();
|
||||
RDFNode objectNode = stmt.getObject();
|
||||
if ((subject == null) || (!(objectNode instanceof Resource))) {
|
||||
continue;
|
||||
}
|
||||
Resource object = (Resource) objectNode;
|
||||
RoleLevel role = RoleLevel.getRoleByUri(object.getURI());
|
||||
map.put(new FullPropertyKey(subject.getURI()), role);
|
||||
}
|
||||
} finally {
|
||||
stmts.close();
|
||||
}
|
||||
List<ObjectProperty> fauxOps = ApplicationConfigurationOntologyUtils
|
||||
.getAdditionalFauxSubproperties(null, null, model, model);
|
||||
for (ObjectProperty faux : fauxOps) {
|
||||
RoleLevel role = null;
|
||||
if(VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT
|
||||
.equals(propertyUri)) {
|
||||
role = faux.getProhibitedFromUpdateBelowRoleLevel();
|
||||
} else if (VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT
|
||||
.equals(propertyUri)) {
|
||||
role = faux.getHiddenFromDisplayBelowRoleLevel();
|
||||
} else if (VitroVocabulary.HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT
|
||||
.equals(propertyUri)) {
|
||||
role = faux.getHiddenFromPublishBelowRoleLevel();
|
||||
}
|
||||
if (role != null) {
|
||||
FullPropertyKey key = new FullPropertyKey(faux);
|
||||
map.put(key, role);
|
||||
log.debug("Putting key: " + key + " ==> L:" + role);
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
model.leaveCriticalSection();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// the bean
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* URIs in these namespaces can't be modified, unless they are listed in the
|
||||
* exceptions.
|
||||
*/
|
||||
private final Collection<String> modifyProhibitedNamespaces;
|
||||
|
||||
/**
|
||||
* These URIs can be modified, even if they are in the prohibited
|
||||
* namespaces.
|
||||
*/
|
||||
private final Collection<String> modifyExceptionsAllowedUris;
|
||||
|
||||
/**
|
||||
* These URIs can be displayed only if the user's role is at least as high
|
||||
* as the threshold role.
|
||||
*/
|
||||
private final Map<FullPropertyKey, RoleLevel> displayThresholdMap;
|
||||
|
||||
/**
|
||||
* These URIs can be modified only if the user's role is at least as high as
|
||||
* the threshold role.
|
||||
*/
|
||||
private final Map<FullPropertyKey, RoleLevel> modifyThresholdMap;
|
||||
|
||||
/**
|
||||
* These URIs can be published only if the user's role is at least as high as
|
||||
* the threshold role.
|
||||
*/
|
||||
private final Map<FullPropertyKey, RoleLevel> publishThresholdMap;
|
||||
|
||||
|
||||
/**
|
||||
* Store unmodifiable versions of the inputs.
|
||||
*
|
||||
* Protected access: the bean should only be created by the static methods,
|
||||
* or by unit tests.
|
||||
*/
|
||||
protected PropertyRestrictionPolicyHelper(
|
||||
Collection<String> modifyProhibitedNamespaces,
|
||||
Collection<String> modifyExceptionsAllowedUris,
|
||||
Map<FullPropertyKey, RoleLevel> displayThresholdMap,
|
||||
Map<FullPropertyKey, RoleLevel> modifyThresholdMap,
|
||||
Map<FullPropertyKey, RoleLevel> publishThresholdMap) {
|
||||
this.modifyProhibitedNamespaces = unmodifiable(modifyProhibitedNamespaces);
|
||||
this.modifyExceptionsAllowedUris = unmodifiable(modifyExceptionsAllowedUris);
|
||||
this.displayThresholdMap = displayThresholdMap;
|
||||
this.modifyThresholdMap = modifyThresholdMap;
|
||||
this.publishThresholdMap = publishThresholdMap;
|
||||
// TODO: why are these no longer unmodifiable? Brian changed during the
|
||||
// TODO: ISF integration.
|
||||
// this.displayThresholdMap = unmodifiable(displayThresholdMap);
|
||||
// this.modifyThresholdMap = unmodifiable(modifyThresholdMap);
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("prohibited: " + this.modifyProhibitedNamespaces);
|
||||
log.debug("exceptions: " + this.modifyExceptionsAllowedUris);
|
||||
log.debug("display thresholds: " + this.displayThresholdMap);
|
||||
log.debug("modify thresholds: " + this.modifyThresholdMap);
|
||||
log.debug("publish thresholds: " + this.publishThresholdMap);
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<String> unmodifiable(Collection<String> raw) {
|
||||
if (raw == null) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
return Collections.unmodifiableCollection(new HashSet<String>(raw));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private Map<String, RoleLevel> unmodifiable(Map<String, RoleLevel> raw) {
|
||||
if (raw == null) {
|
||||
return Collections.emptyMap();
|
||||
} else {
|
||||
return Collections.unmodifiableMap(new HashMap<String, RoleLevel>(
|
||||
raw));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Any resource can be displayed.
|
||||
*
|
||||
* (Someday we may want to implement display restrictions based on VClass.)
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public boolean canDisplayResource(String resourceUri, RoleLevel userRole) {
|
||||
if (resourceUri == null) {
|
||||
log.debug("can't display resource: resourceUri was null");
|
||||
return false;
|
||||
}
|
||||
|
||||
log.debug("can display resource '" + resourceUri + "'");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* A resource cannot be modified if its namespace is in the prohibited list
|
||||
* (but some exceptions are allowed).
|
||||
*
|
||||
* (Someday we may want to implement modify restrictions based on VClass.)
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public boolean canModifyResource(String resourceUri, RoleLevel userRole) {
|
||||
if (resourceUri == null) {
|
||||
log.debug("can't modify resource: resourceUri was null");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (modifyProhibitedNamespaces.contains(namespace(resourceUri))) {
|
||||
if (modifyExceptionsAllowedUris.contains(resourceUri)) {
|
||||
log.debug("'" + resourceUri + "' is a permitted exception");
|
||||
} else {
|
||||
log.debug("can't modify resource '" + resourceUri
|
||||
+ "': prohibited namespace: '" + namespace(resourceUri)
|
||||
+ "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("can modify resource '" + resourceUri + "'");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Any resource can be published.
|
||||
*
|
||||
* (Someday we may want to implement publish restrictions based on VClass.)
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public boolean canPublishResource(String resourceUri, RoleLevel userRole) {
|
||||
if (resourceUri == null) {
|
||||
log.debug("can't publish resource: resourceUri was null");
|
||||
return false;
|
||||
}
|
||||
|
||||
log.debug("can publish resource '" + resourceUri + "'");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If display of a predicate is restricted, the user's role must be at least
|
||||
* as high as the restriction level.
|
||||
*/
|
||||
public boolean canDisplayPredicate(Property predicate, RoleLevel userRole) {
|
||||
if (predicate == null) {
|
||||
log.debug("can't display predicate: predicate was null");
|
||||
return false;
|
||||
}
|
||||
|
||||
RoleLevel displayThreshold = getThreshold(predicate, displayThresholdMap);
|
||||
|
||||
if (isAuthorized(userRole, displayThreshold)) {
|
||||
log.debug("can display predicate: '" + predicate.getURI() + "', domain="
|
||||
+ predicate.getDomainVClassURI() + ", range="
|
||||
+ predicate.getRangeVClassURI() + ", userRole="
|
||||
+ userRole + ", thresholdRole=" + displayThreshold);
|
||||
return true;
|
||||
}
|
||||
|
||||
log.debug("can't display predicate: '" + predicate.getURI() + "', domain="
|
||||
+ predicate.getDomainVClassURI() + ", range="
|
||||
+ predicate.getRangeVClassURI() + ", userRole="
|
||||
+ userRole + ", thresholdRole=" + displayThreshold);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A predicate cannot be modified if its namespace is in the prohibited list
|
||||
* (some exceptions are allowed).
|
||||
*
|
||||
* If modification of a predicate is restricted, the user's role must be at
|
||||
* least as high as the restriction level.
|
||||
*/
|
||||
public boolean canModifyPredicate(Property predicate, RoleLevel userRole) {
|
||||
if (predicate == null || predicate.getURI() == null) {
|
||||
log.debug("can't modify predicate: predicate was null");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (modifyProhibitedNamespaces.contains(namespace(predicate.getURI()))) {
|
||||
if (modifyExceptionsAllowedUris.contains(predicate.getURI())) {
|
||||
log.debug("'" + predicate.getURI() + "' is a permitted exception");
|
||||
} else {
|
||||
log.debug("can't modify resource '" + predicate.getURI()
|
||||
+ "': prohibited namespace: '"
|
||||
+ namespace(predicate.getURI()) + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
RoleLevel modifyThreshold = getModifyThreshold(predicate);
|
||||
if (isAuthorized(userRole, modifyThreshold)) {
|
||||
log.debug("can modify predicate: '" + predicate.getURI() + "', domain="
|
||||
+ predicate.getDomainVClassURI() + ", range="
|
||||
+ predicate.getRangeVClassURI() + ", userRole="
|
||||
+ userRole + ", thresholdRole=" + modifyThreshold);
|
||||
return true;
|
||||
}
|
||||
|
||||
log.debug("can't modify predicate: '" + predicate.getURI() + "', domain="
|
||||
+ predicate.getDomainVClassURI() + ", range="
|
||||
+ predicate.getRangeVClassURI() + ", userRole="
|
||||
+ userRole + ", thresholdRole=" + modifyThreshold);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If publishing of a predicate is restricted, the user's role must be at least
|
||||
* as high as the restriction level.
|
||||
*/
|
||||
public boolean canPublishPredicate(Property predicate, RoleLevel userRole) {
|
||||
if (predicate == null) {
|
||||
log.debug("can't publish predicate: predicate was null");
|
||||
return false;
|
||||
}
|
||||
|
||||
RoleLevel publishThreshold = getThreshold(predicate, publishThresholdMap);
|
||||
|
||||
if (isAuthorized(userRole, publishThreshold)) {
|
||||
log.debug("can publish predicate: '" + predicate.getURI() + "', domain="
|
||||
+ predicate.getDomainVClassURI() + ", range="
|
||||
+ predicate.getRangeVClassURI() + ", userRole="
|
||||
+ userRole + ", thresholdRole=" + publishThreshold);
|
||||
return true;
|
||||
}
|
||||
|
||||
log.debug("can't publish predicate: '" + predicate.getURI() + "', domain="
|
||||
+ predicate.getDomainVClassURI() + ", range="
|
||||
+ predicate.getRangeVClassURI() + ", userRole="
|
||||
+ userRole + ", thresholdRole=" + publishThreshold);
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isAuthorized(RoleLevel userRole, RoleLevel thresholdRole) {
|
||||
if (userRole == null) {
|
||||
return false;
|
||||
}
|
||||
if (thresholdRole == null) {
|
||||
return true;
|
||||
}
|
||||
return userRole.compareTo(thresholdRole) >= 0;
|
||||
}
|
||||
|
||||
private String namespace(String uri) {
|
||||
return uri.substring(0, Util.splitNamespace(uri));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Setup class
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create the bean at startup and remove it at shutdown.
|
||||
*/
|
||||
public static class Setup implements ServletContextListener {
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
ServletContext ctx = sce.getServletContext();
|
||||
StartupStatus ss = StartupStatus.getBean(ctx);
|
||||
|
||||
try {
|
||||
OntModel model = ModelAccess.on(ctx).getOntModel();
|
||||
if (model == null) {
|
||||
throw new NullPointerException(
|
||||
"jenaOntModel has not been initialized.");
|
||||
}
|
||||
Model displayModel = ModelAccess.on(ctx).getOntModel(DISPLAY);
|
||||
if (displayModel == null) {
|
||||
throw new NullPointerException(
|
||||
"display model has not been initialized.");
|
||||
}
|
||||
|
||||
PropertyRestrictionPolicyHelper bean = PropertyRestrictionPolicyHelper
|
||||
.createBean(model, displayModel);
|
||||
PropertyRestrictionPolicyHelper.setBean(ctx, bean);
|
||||
} catch (Exception e) {
|
||||
ss.fatal(this, "could not set up PropertyRestrictionPolicyHelper", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
removeBean(sce.getServletContext());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.auth.policy.bean;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
|
||||
|
||||
/**
|
||||
* A property or faux property whose usage can be restricted according to the
|
||||
* user's role level.
|
||||
*/
|
||||
public interface RoleRestrictedProperty {
|
||||
String getDomainVClassURI();
|
||||
|
||||
String getRangeVClassURI();
|
||||
|
||||
String getURI();
|
||||
|
||||
RoleLevel getHiddenFromDisplayBelowRoleLevel();
|
||||
|
||||
RoleLevel getProhibitedFromUpdateBelowRoleLevel();
|
||||
|
||||
RoleLevel getHiddenFromPublishBelowRoleLevel();
|
||||
}
|
|
@ -8,7 +8,7 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.BasicPolicyDecision;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
|
||||
|
@ -31,13 +31,13 @@ public abstract class AbstractRelationshipPolicy implements PolicyIface {
|
|||
}
|
||||
|
||||
protected boolean canModifyResource(String uri) {
|
||||
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyResource(
|
||||
uri, RoleLevel.SELF);
|
||||
return PropertyRestrictionBean.getBean().canModifyResource(uri,
|
||||
RoleLevel.SELF);
|
||||
}
|
||||
|
||||
protected boolean canModifyPredicate(Property predicate) {
|
||||
return PropertyRestrictionPolicyHelper.getBean(ctx).canModifyPredicate(
|
||||
predicate, RoleLevel.SELF);
|
||||
return PropertyRestrictionBean.getBean().canModifyPredicate(predicate,
|
||||
RoleLevel.SELF);
|
||||
}
|
||||
|
||||
protected PolicyDecision cantModifyResource(String uri) {
|
||||
|
|
|
@ -78,7 +78,8 @@ public class BaseResourceBean implements ResourceBean {
|
|||
public String getShorthand() {
|
||||
return shorthand;
|
||||
}
|
||||
|
||||
|
||||
// Never returns null.
|
||||
public static RoleLevel getRoleByUri(String uri2) {
|
||||
if (uri2 == null)
|
||||
return RoleLevel.values()[0];
|
||||
|
@ -208,13 +209,13 @@ public class BaseResourceBean implements ResourceBean {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setHiddenFromDisplayBelowRoleLevel(RoleLevel eR) {
|
||||
hiddenFromDisplayBelowRoleLevel = eR;
|
||||
public void setHiddenFromDisplayBelowRoleLevel(RoleLevel level) {
|
||||
hiddenFromDisplayBelowRoleLevel = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHiddenFromDisplayBelowRoleLevelUsingRoleUri(String roleUri) {
|
||||
hiddenFromDisplayBelowRoleLevel = BaseResourceBean.RoleLevel.getRoleByUri(roleUri);
|
||||
hiddenFromDisplayBelowRoleLevel = RoleLevel.getRoleByUri(roleUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -223,13 +224,13 @@ public class BaseResourceBean implements ResourceBean {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setProhibitedFromUpdateBelowRoleLevel(RoleLevel eR) {
|
||||
prohibitedFromUpdateBelowRoleLevel = eR;
|
||||
public void setProhibitedFromUpdateBelowRoleLevel(RoleLevel level) {
|
||||
prohibitedFromUpdateBelowRoleLevel = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProhibitedFromUpdateBelowRoleLevelUsingRoleUri(String roleUri) {
|
||||
prohibitedFromUpdateBelowRoleLevel = BaseResourceBean.RoleLevel.getRoleByUri(roleUri);
|
||||
prohibitedFromUpdateBelowRoleLevel = RoleLevel.getRoleByUri(roleUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -238,8 +239,8 @@ public class BaseResourceBean implements ResourceBean {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setHiddenFromPublishBelowRoleLevel(RoleLevel eR) {
|
||||
hiddenFromPublishBelowRoleLevel = eR;
|
||||
public void setHiddenFromPublishBelowRoleLevel(RoleLevel level) {
|
||||
hiddenFromPublishBelowRoleLevel = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,13 +6,15 @@ import java.text.Collator;
|
|||
import java.util.List;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty;
|
||||
|
||||
/**
|
||||
* class representing a property that relates an entity (object)
|
||||
* to a data literal
|
||||
* @author bjl23
|
||||
*
|
||||
*/
|
||||
public class DataProperty extends Property implements Comparable<DataProperty>, ResourceBean {
|
||||
public class DataProperty extends Property implements Comparable<DataProperty>, ResourceBean, RoleRestrictedProperty {
|
||||
|
||||
private String name = null;
|
||||
private String publicName = null;
|
||||
|
|
|
@ -0,0 +1,250 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.beans;
|
||||
|
||||
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty;
|
||||
|
||||
/**
|
||||
* Represents a specialization on an ObjectProperty, only meaningful for
|
||||
* display.
|
||||
*/
|
||||
public class FauxProperty extends BaseResourceBean implements ResourceBean,
|
||||
RoleRestrictedProperty {
|
||||
// Must be null on insert. Must not be null on update. Ignored on delete.
|
||||
private String contextUri;
|
||||
// Must be null on insert. Must not be null on update. Ignored on delete.
|
||||
private String configUri;
|
||||
|
||||
// Must not be null on insert or update. Partial identifier on delete.
|
||||
private String rangeURI;
|
||||
// May be null. Partial identifier on delete.
|
||||
private String domainURI;
|
||||
|
||||
private String baseLabel;
|
||||
private String rangeLabel;
|
||||
private String domainLabel;
|
||||
|
||||
private String groupURI;
|
||||
|
||||
private String publicDescription;
|
||||
|
||||
private int displayTier;
|
||||
private int displayLimit;
|
||||
|
||||
private boolean collateBySubclass;
|
||||
private boolean selectFromExisting;
|
||||
private boolean offerCreateNewOption;
|
||||
|
||||
private String customEntryForm;
|
||||
private String customListView;
|
||||
|
||||
/**
|
||||
* Arguments are in this order to mimic the relationship: subject ==>
|
||||
* property ==> object
|
||||
*
|
||||
* @param domainURI
|
||||
* URI of the subject class. May be null.
|
||||
* @param baseURI
|
||||
* URI of the property. May not be null.
|
||||
* @param rangeUri
|
||||
* URI of the object class. May be null.
|
||||
*/
|
||||
public FauxProperty(String domainURI, String baseURI, String rangeURI) {
|
||||
super(Objects.requireNonNull(baseURI, "baseURI may not be null"));
|
||||
this.rangeURI = rangeURI;
|
||||
this.domainURI = domainURI;
|
||||
}
|
||||
|
||||
public FauxProperty() {
|
||||
// This is required by OperationUtils.cloneBean()
|
||||
}
|
||||
|
||||
public String getContextUri() {
|
||||
return contextUri;
|
||||
}
|
||||
|
||||
public void setContextUri(String contextUri) {
|
||||
this.contextUri = contextUri;
|
||||
}
|
||||
|
||||
public String getConfigUri() {
|
||||
return configUri;
|
||||
}
|
||||
|
||||
public void setConfigUri(String configUri) {
|
||||
this.configUri = configUri;
|
||||
}
|
||||
|
||||
// BaseURI becomes an alias for URI
|
||||
public String getBaseURI() {
|
||||
return getURI();
|
||||
}
|
||||
|
||||
public void setBaseURI(String baseURI) {
|
||||
setURI(baseURI);
|
||||
}
|
||||
|
||||
public String getRangeURI() {
|
||||
return rangeURI;
|
||||
}
|
||||
|
||||
public void setRangeURI(String rangeURI) {
|
||||
this.rangeURI = rangeURI;
|
||||
}
|
||||
|
||||
public String getBaseLabel() {
|
||||
return (baseLabel == null) ? localName(getBaseURI()) : baseLabel;
|
||||
}
|
||||
|
||||
public void setBaseLabel(String baseLabel) {
|
||||
this.baseLabel = baseLabel;
|
||||
}
|
||||
|
||||
public String getRangeLabel() {
|
||||
return (rangeLabel == null) ? localName(rangeURI) : rangeLabel;
|
||||
}
|
||||
|
||||
public void setRangeLabel(String rangeLabel) {
|
||||
this.rangeLabel = rangeLabel;
|
||||
}
|
||||
|
||||
public String getDomainURI() {
|
||||
return domainURI;
|
||||
}
|
||||
|
||||
public void setDomainURI(String domainURI) {
|
||||
this.domainURI = domainURI;
|
||||
}
|
||||
|
||||
public String getDomainLabel() {
|
||||
return (domainLabel == null) ? (domainURI == null ? "null"
|
||||
: localName(domainURI)) : domainLabel;
|
||||
}
|
||||
|
||||
public void setDomainLabel(String domainLabel) {
|
||||
this.domainLabel = domainLabel;
|
||||
}
|
||||
|
||||
public String getGroupURI() {
|
||||
return groupURI;
|
||||
}
|
||||
|
||||
public void setGroupURI(String groupURI) {
|
||||
this.groupURI = groupURI;
|
||||
}
|
||||
|
||||
// DisplayName becomes an alias for PickListName
|
||||
public String getDisplayName() {
|
||||
return getPickListName();
|
||||
}
|
||||
|
||||
public void setDisplayName(String displayName) {
|
||||
setPickListName(displayName);
|
||||
}
|
||||
|
||||
public String getPublicDescription() {
|
||||
return publicDescription;
|
||||
}
|
||||
|
||||
public void setPublicDescription(String publicDescription) {
|
||||
this.publicDescription = publicDescription;
|
||||
}
|
||||
|
||||
public int getDisplayTier() {
|
||||
return displayTier;
|
||||
}
|
||||
|
||||
public void setDisplayTier(int displayTier) {
|
||||
this.displayTier = displayTier;
|
||||
}
|
||||
|
||||
public int getDisplayLimit() {
|
||||
return displayLimit;
|
||||
}
|
||||
|
||||
public void setDisplayLimit(int displayLimit) {
|
||||
this.displayLimit = displayLimit;
|
||||
}
|
||||
|
||||
public boolean isCollateBySubclass() {
|
||||
return collateBySubclass;
|
||||
}
|
||||
|
||||
public void setCollateBySubclass(boolean collateBySubclass) {
|
||||
this.collateBySubclass = collateBySubclass;
|
||||
}
|
||||
|
||||
public boolean isSelectFromExisting() {
|
||||
return selectFromExisting;
|
||||
}
|
||||
|
||||
public void setSelectFromExisting(boolean selectFromExisting) {
|
||||
this.selectFromExisting = selectFromExisting;
|
||||
}
|
||||
|
||||
public boolean isOfferCreateNewOption() {
|
||||
return offerCreateNewOption;
|
||||
}
|
||||
|
||||
public void setOfferCreateNewOption(boolean offerCreateNewOption) {
|
||||
this.offerCreateNewOption = offerCreateNewOption;
|
||||
}
|
||||
|
||||
public String getCustomEntryForm() {
|
||||
return customEntryForm;
|
||||
}
|
||||
|
||||
public void setCustomEntryForm(String customEntryForm) {
|
||||
this.customEntryForm = customEntryForm;
|
||||
}
|
||||
|
||||
public String getCustomListView() {
|
||||
return customListView;
|
||||
}
|
||||
|
||||
public void setCustomListView(String customListView) {
|
||||
this.customListView = customListView;
|
||||
}
|
||||
|
||||
private String localName(String uriString) {
|
||||
try {
|
||||
return createResource(uriString).getLocalName();
|
||||
} catch (Exception e) {
|
||||
return uriString;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FauxProperty[domainURI=" + domainURI + ", baseUri=" + getURI()
|
||||
+ ", baseLabel=" + baseLabel + ", rangeURI=" + rangeURI
|
||||
+ ", rangeLabel=" + rangeLabel + ", domainLabel=" + domainLabel
|
||||
+ ", pickListName=" + getPickListName() + ", contextUri="
|
||||
+ contextUri + ", configUri=" + configUri + ", groupURI="
|
||||
+ groupURI + "publicDescription=" + publicDescription
|
||||
+ ", displayTier=" + displayTier + ", displayLimit="
|
||||
+ displayLimit + ", collateBySubclass=" + collateBySubclass
|
||||
+ ", selectFromExisting=" + selectFromExisting
|
||||
+ ", offerCreateNewOption=" + offerCreateNewOption
|
||||
+ ", customEntryForm=" + customEntryForm + ", customListView="
|
||||
+ customListView + "]";
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Satisfy the RoleRestrictedProperty interface.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public String getDomainVClassURI() {
|
||||
return getDomainURI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRangeVClassURI() {
|
||||
return getRangeURI();
|
||||
}
|
||||
}
|
|
@ -17,11 +17,13 @@ import org.joda.time.DateTime;
|
|||
|
||||
import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty;
|
||||
|
||||
/**
|
||||
* a class representing an object property
|
||||
*
|
||||
*/
|
||||
public class ObjectProperty extends Property implements Comparable<ObjectProperty>, ResourceBean, Cloneable
|
||||
public class ObjectProperty extends Property implements Comparable<ObjectProperty>, ResourceBean, Cloneable, RoleRestrictedProperty
|
||||
{
|
||||
private static final Log log = LogFactory.getLog(ObjectProperty.class.getName());
|
||||
|
||||
|
|
|
@ -46,6 +46,13 @@ public class VitroApiServlet extends HttpServlet {
|
|||
|
||||
Authenticator auth = Authenticator.getInstance(req);
|
||||
UserAccount account = auth.getAccountForInternalAuth(email);
|
||||
|
||||
if (auth.accountRequiresEditing(account)) {
|
||||
log.debug("Account " + email + " requires editing.");
|
||||
throw new AuthException("user account must include first and "
|
||||
+ "last names and a valid email address.");
|
||||
}
|
||||
|
||||
if (!auth.isCurrentPassword(account, password)) {
|
||||
log.debug("Invalid: '" + email + "'/'" + password + "'");
|
||||
throw new AuthException("email/password combination is not valid");
|
||||
|
@ -57,6 +64,11 @@ public class VitroApiServlet extends HttpServlet {
|
|||
throw new AuthException("Account is not authorized");
|
||||
}
|
||||
|
||||
if (account.isPasswordChangeRequired()) {
|
||||
log.debug("Account " + email + " requires a new password.");
|
||||
throw new AuthException("user account requires a new password.");
|
||||
}
|
||||
|
||||
log.debug("Authorized for '" + email + "'");
|
||||
}
|
||||
|
||||
|
|
|
@ -34,9 +34,9 @@ import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
|||
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.DatatypeDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||
|
||||
|
||||
public class DatapropRetryController extends BaseEditController {
|
||||
|
@ -124,7 +124,7 @@ public class DatapropRetryController extends BaseEditController {
|
|||
|
||||
//set up any listeners
|
||||
List changeListenerList = new ArrayList();
|
||||
changeListenerList.add(new PropertyRestrictionListener(getServletContext()));
|
||||
changeListenerList.add(new PropertyRestrictionListener());
|
||||
epo.setChangeListenerList(changeListenerList);
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.edit;
|
||||
|
||||
import edu.cornell.mannlib.vedit.controller.BaseEditController;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class FauxPropertyEditController extends BaseEditController {
|
||||
|
||||
}
|
|
@ -0,0 +1,353 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.edit;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.POLICY_NEUTRAL;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
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;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vedit.beans.EditProcessObject;
|
||||
import edu.cornell.mannlib.vedit.beans.FormObject;
|
||||
import edu.cornell.mannlib.vedit.beans.Option;
|
||||
import edu.cornell.mannlib.vedit.controller.BaseEditController;
|
||||
import edu.cornell.mannlib.vedit.util.FormUtils;
|
||||
import edu.cornell.mannlib.vedit.validator.Validator;
|
||||
import edu.cornell.mannlib.vedit.validator.impl.RequiredFieldValidator;
|
||||
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.beans.FauxProperty;
|
||||
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.controller.Controllers;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.edit.utils.RoleLevelOptionsSetup;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class FauxPropertyRetryController extends BaseEditController {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(FauxPropertyRetryController.class);
|
||||
|
||||
@Override
|
||||
public void doPost(HttpServletRequest req, HttpServletResponse response) {
|
||||
if (!isAuthorizedToDisplayPage(req, response,
|
||||
SimplePermission.EDIT_ONTOLOGY.ACTION)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// create an EditProcessObject for this and put it in the session
|
||||
EditProcessObject epo = super.createEpo(req);
|
||||
|
||||
// Populate it.
|
||||
EpoPopulator populator = new EpoPopulator(req, epo);
|
||||
populator.populate();
|
||||
|
||||
req.setAttribute("bodyJsp", "/templates/edit/formBasic.jsp");
|
||||
req.setAttribute("colspan", "5");
|
||||
req.setAttribute("formJsp",
|
||||
"/templates/edit/specific/fauxProperty_retry.jsp");
|
||||
req.setAttribute("scripts", "/templates/edit/formBasic.js");
|
||||
req.setAttribute("title", "Faux Property Editing Form");
|
||||
req.setAttribute("_action", epo.getAction());
|
||||
setRequestAttributes(req, epo);
|
||||
|
||||
try {
|
||||
RequestDispatcher rd = req
|
||||
.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||
rd.forward(req, response);
|
||||
} catch (Exception e) {
|
||||
log.error("Could not forward to view.");
|
||||
log.error(e.getMessage());
|
||||
log.error(e.getStackTrace());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doGet(HttpServletRequest request, HttpServletResponse response) {
|
||||
doPost(request, response);
|
||||
}
|
||||
|
||||
private static class EpoPopulator {
|
||||
private final VitroRequest req;
|
||||
private final ServletContext ctx;
|
||||
private final WebappDaoFactory wadf;
|
||||
|
||||
private final EditProcessObject epo;
|
||||
|
||||
private final FauxPropertyDao fpDao;
|
||||
|
||||
private FauxProperty beanForEditing;
|
||||
private Property baseProperty;
|
||||
|
||||
EpoPopulator(HttpServletRequest req, EditProcessObject epo) {
|
||||
this.req = new VitroRequest(req);
|
||||
this.ctx = req.getSession().getServletContext();
|
||||
this.wadf = ModelAccess.on(req).getWebappDaoFactory(POLICY_NEUTRAL);
|
||||
|
||||
this.epo = epo;
|
||||
|
||||
this.fpDao = ModelAccess.on(ctx).getWebappDaoFactory()
|
||||
.getFauxPropertyDao();
|
||||
|
||||
}
|
||||
|
||||
void populate() {
|
||||
epo.setDataAccessObject(fpDao);
|
||||
epo.setAction(determineAction());
|
||||
|
||||
if (epo.getUseRecycledBean()) {
|
||||
beanForEditing = (FauxProperty) epo.getNewBean();
|
||||
} else {
|
||||
beanForEditing = locateBeanForEditing();
|
||||
epo.setOriginalBean(beanForEditing);
|
||||
}
|
||||
|
||||
this.baseProperty = req.getUnfilteredWebappDaoFactory()
|
||||
.getObjectPropertyDao()
|
||||
.getObjectPropertyByURI(beanForEditing.getURI());
|
||||
|
||||
addCheckboxValuesToTheRequest();
|
||||
|
||||
setFieldValidators();
|
||||
setListeners();
|
||||
setForwarders();
|
||||
|
||||
assembleFormObjectAndConnectToEpo();
|
||||
}
|
||||
|
||||
private String determineAction() {
|
||||
return (req.getParameter("create") == null) ? "update" : "insert";
|
||||
}
|
||||
|
||||
private FauxProperty locateBeanForEditing() {
|
||||
String baseUri = req.getParameter("baseUri");
|
||||
String rangeUri = req.getParameter("rangeUri");
|
||||
String domainUri = req.getParameter("domainUri");
|
||||
|
||||
if (epo.getAction().equals("insert")) {
|
||||
return newFauxProperty(baseUri);
|
||||
}
|
||||
|
||||
FauxProperty bean = fpDao.getFauxPropertyByUris(domainUri, baseUri,
|
||||
rangeUri);
|
||||
if (bean == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"FauxProperty does not exist for <" + domainUri
|
||||
+ "> ==> <" + baseUri + "> ==> <" + rangeUri
|
||||
+ ">");
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
ObjectPropertyDao opDao = wadf.getObjectPropertyDao();
|
||||
ObjectProperty base = opDao.getObjectPropertyByURI(baseUri);
|
||||
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.setCustomEntryForm(base.getCustomEntryForm());
|
||||
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());
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
private void setFieldValidators() {
|
||||
epo.getValidatorMap()
|
||||
.put("RangeURI",
|
||||
Arrays.asList(new Validator[] { new RequiredFieldValidator() }));
|
||||
}
|
||||
|
||||
private void setListeners() {
|
||||
epo.setChangeListenerList(Collections
|
||||
.singletonList(new PropertyRestrictionListener()));
|
||||
}
|
||||
|
||||
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()));
|
||||
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", 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;
|
||||
}
|
||||
|
||||
private List<Option> createClassGroupOptionList() {
|
||||
List<Option> groupOptList = getGroupOptList(beanForEditing
|
||||
.getGroupURI());
|
||||
Collections.sort(groupOptList,
|
||||
new OptionsBodyComparator(req.getCollator()));
|
||||
groupOptList.add(0, new Option("", "none"));
|
||||
return groupOptList;
|
||||
}
|
||||
|
||||
private List<Option> getGroupOptList(String currentGroupURI) {
|
||||
List<PropertyGroup> groups = wadf.getPropertyGroupDao()
|
||||
.getPublicGroups(true);
|
||||
if (currentGroupURI == null) {
|
||||
return FormUtils.makeOptionListFromBeans(groups, "URI", "Name",
|
||||
"", null, false);
|
||||
|
||||
} else {
|
||||
return FormUtils.makeOptionListFromBeans(groups, "URI", "Name",
|
||||
currentGroupURI, null, true);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Option> buildDomainOptionList() {
|
||||
List<Option> list = new ArrayList<>();
|
||||
if (baseProperty.getDomainVClassURI() == null) {
|
||||
list.addAll(FormUtils.makeVClassOptionList(wadf,
|
||||
beanForEditing.getDomainURI()));
|
||||
} else {
|
||||
list.addAll(FormUtils.makeOptionListOfSubVClasses(wadf,
|
||||
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;
|
||||
|
||||
public OptionsBodyComparator(Collator collator) {
|
||||
this.collator = collator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(Option o1, Option o2) {
|
||||
return collator.compare(o1.getBody(), o2.getBody());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -17,8 +17,10 @@ import org.apache.commons.logging.LogFactory;
|
|||
|
||||
import edu.cornell.mannlib.vedit.beans.EditProcessObject;
|
||||
import edu.cornell.mannlib.vedit.beans.FormObject;
|
||||
import edu.cornell.mannlib.vedit.beans.Option;
|
||||
import edu.cornell.mannlib.vedit.controller.BaseEditController;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Ontology;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
|
||||
|
@ -33,7 +35,8 @@ public class PropertyEditController extends BaseEditController {
|
|||
|
||||
private static final Log log = LogFactory.getLog(PropertyEditController.class.getName());
|
||||
|
||||
public void doPost (HttpServletRequest request, HttpServletResponse response) {
|
||||
@Override
|
||||
public void doPost (HttpServletRequest request, HttpServletResponse response) {
|
||||
if (!isAuthorizedToDisplayPage(request, response,
|
||||
SimplePermission.EDIT_ONTOLOGY.ACTION)) {
|
||||
return;
|
||||
|
@ -189,11 +192,9 @@ public class PropertyEditController extends BaseEditController {
|
|||
request.setAttribute("suppressquery","true");
|
||||
|
||||
|
||||
boolean FORCE_NEW = true;
|
||||
|
||||
EditProcessObject epo = super.createEpo(request, FORCE_NEW);
|
||||
FormObject foo = new FormObject();
|
||||
HashMap OptionMap = new HashMap();
|
||||
HashMap<String, List<Option>> OptionMap = new HashMap<>();
|
||||
foo.setOptionLists(OptionMap);
|
||||
epo.setFormObject(foo);
|
||||
|
||||
|
@ -210,11 +211,18 @@ public class PropertyEditController extends BaseEditController {
|
|||
sortForPickList(subProps, vreq);
|
||||
request.setAttribute("subproperties", subProps);
|
||||
|
||||
// equivalent properties and faux properties
|
||||
|
||||
List<ObjectProperty> eqProps = getObjectPropertiesForURIList(
|
||||
opDao.getEquivalentPropertyURIs(p.getURI()), opDao);
|
||||
sortForPickList(eqProps, vreq);
|
||||
request.setAttribute("equivalentProperties", eqProps);
|
||||
|
||||
List<FauxProperty> fauxProps = vreq.getUnfilteredAssertionsWebappDaoFactory().getFauxPropertyDao().
|
||||
getFauxPropertiesForBaseUri(p.getURI());
|
||||
sortForPickList(fauxProps, vreq);
|
||||
request.setAttribute("fauxproperties", fauxProps);
|
||||
|
||||
RequestDispatcher rd = request.getRequestDispatcher(Controllers.BASIC_JSP);
|
||||
request.setAttribute("epoKey",epo.getKey());
|
||||
request.setAttribute("propertyWebapp", p);
|
||||
|
@ -232,7 +240,8 @@ public class PropertyEditController extends BaseEditController {
|
|||
|
||||
}
|
||||
|
||||
public void doGet (HttpServletRequest request, HttpServletResponse response) {
|
||||
@Override
|
||||
public void doGet (HttpServletRequest request, HttpServletResponse response) {
|
||||
doPost(request,response);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import edu.cornell.mannlib.vedit.beans.Option;
|
|||
import edu.cornell.mannlib.vedit.controller.BaseEditController;
|
||||
import edu.cornell.mannlib.vedit.forwarder.PageForwarder;
|
||||
import edu.cornell.mannlib.vedit.forwarder.impl.UrlForwarder;
|
||||
import edu.cornell.mannlib.vedit.listener.ChangeListener;
|
||||
import edu.cornell.mannlib.vedit.util.FormUtils;
|
||||
import edu.cornell.mannlib.vedit.validator.Validator;
|
||||
import edu.cornell.mannlib.vedit.validator.impl.IntValidator;
|
||||
|
@ -29,14 +30,12 @@ import edu.cornell.mannlib.vedit.validator.impl.XMLNameValidator;
|
|||
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.beans.ObjectProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.edit.utils.RoleLevelOptionsSetup;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||
|
||||
public class PropertyRetryController extends BaseEditController {
|
||||
|
||||
|
@ -67,10 +66,8 @@ public class PropertyRetryController extends BaseEditController {
|
|||
}
|
||||
|
||||
ObjectPropertyDao propDao = ModelAccess.on(getServletContext()).getWebappDaoFactory().getObjectPropertyDao();
|
||||
//getUnfilteredWebappDaoFactory().getObjectPropertyDao();
|
||||
epo.setDataAccessObject(propDao);
|
||||
OntologyDao ontDao = request.getUnfilteredWebappDaoFactory().getOntologyDao();
|
||||
VClassDao vclassDao = request.getUnfilteredWebappDaoFactory().getVClassDao();
|
||||
|
||||
ObjectProperty propertyForEditing = null;
|
||||
if (!epo.getUseRecycledBean()){
|
||||
|
@ -82,6 +79,7 @@ public class PropertyRetryController extends BaseEditController {
|
|||
epo.setAction("update");
|
||||
} catch (NullPointerException e) {
|
||||
log.error("Need to implement 'record not found' error message.");
|
||||
throw(e);
|
||||
}
|
||||
} else {
|
||||
propertyForEditing = new ObjectProperty();
|
||||
|
@ -105,9 +103,9 @@ public class PropertyRetryController extends BaseEditController {
|
|||
|
||||
|
||||
//set any validators
|
||||
List localNameValidatorList = new ArrayList();
|
||||
List<Validator> localNameValidatorList = new ArrayList<>();
|
||||
localNameValidatorList.add(new XMLNameValidator());
|
||||
List localNameInverseValidatorList = new ArrayList();
|
||||
List<Validator> localNameInverseValidatorList = new ArrayList<>();
|
||||
localNameInverseValidatorList.add(new XMLNameValidator(true));
|
||||
epo.getValidatorMap().put("LocalName", localNameValidatorList);
|
||||
epo.getValidatorMap().put("LocalNameInverse", localNameInverseValidatorList);
|
||||
|
@ -116,8 +114,8 @@ public class PropertyRetryController extends BaseEditController {
|
|||
epo.getValidatorMap().put("DisplayRank", displayRankValidatorList);
|
||||
|
||||
//set up any listeners
|
||||
List changeListenerList = new ArrayList();
|
||||
changeListenerList.add(new PropertyRestrictionListener(getServletContext()));
|
||||
List<ChangeListener> changeListenerList = new ArrayList<>();
|
||||
changeListenerList.add(new PropertyRestrictionListener());
|
||||
epo.setChangeListenerList(changeListenerList);
|
||||
|
||||
//make a postinsert pageforwarder that will send us to a new class's fetch screen
|
||||
|
@ -127,7 +125,7 @@ public class PropertyRetryController extends BaseEditController {
|
|||
|
||||
//set the getMethod so we can retrieve a new bean after we've inserted it
|
||||
try {
|
||||
Class[] args = new Class[1];
|
||||
Class<?>[] args = new Class[1];
|
||||
args[0] = String.class;
|
||||
epo.setGetMethod(propDao.getClass().getDeclaredMethod("getObjectPropertyByURI",args));
|
||||
} catch (NoSuchMethodException e) {
|
||||
|
@ -149,7 +147,7 @@ public class PropertyRetryController extends BaseEditController {
|
|||
optionMap.put("ProhibitedFromUpdateBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getUpdateOptionsList(propertyForEditing));
|
||||
optionMap.put("HiddenFromPublishBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getPublishOptionsList(propertyForEditing));
|
||||
|
||||
List groupOptList = FormUtils.makeOptionListFromBeans(request.getUnfilteredWebappDaoFactory().getPropertyGroupDao().getPublicGroups(true),"URI","Name", ((propertyForEditing.getGroupURI()==null) ? "" : propertyForEditing.getGroupURI()), null, (propertyForEditing.getGroupURI()!=null));
|
||||
List<Option> groupOptList = FormUtils.makeOptionListFromBeans(request.getUnfilteredWebappDaoFactory().getPropertyGroupDao().getPublicGroups(true),"URI","Name", ((propertyForEditing.getGroupURI()==null) ? "" : propertyForEditing.getGroupURI()), null, (propertyForEditing.getGroupURI()!=null));
|
||||
HashMap<String,Option> hashMap = new HashMap<String,Option>();
|
||||
groupOptList = getSortedList(hashMap,groupOptList,request);
|
||||
groupOptList.add(0,new Option("","none"));
|
||||
|
@ -163,7 +161,6 @@ public class PropertyRetryController extends BaseEditController {
|
|||
request.setAttribute("inverseFunctional",propertyForEditing.getInverseFunctional());
|
||||
request.setAttribute("selectFromExisting",propertyForEditing.getSelectFromExisting());
|
||||
request.setAttribute("offerCreateNewOption", propertyForEditing.getOfferCreateNewOption());
|
||||
//request.setAttribute("stubObjectRelation", propertyForEditing.getStubObjectRelation());
|
||||
request.setAttribute("objectIndividualSortPropertyURI", propertyForEditing.getObjectIndividualSortPropertyURI());
|
||||
request.setAttribute("domainEntitySortDirection", propertyForEditing.getDomainEntitySortDirection());
|
||||
request.setAttribute("collateBySubclass", propertyForEditing.getCollateBySubclass());
|
||||
|
@ -203,7 +200,8 @@ public class PropertyRetryController extends BaseEditController {
|
|||
|
||||
}
|
||||
|
||||
public void doGet (HttpServletRequest request, HttpServletResponse response) {
|
||||
@Override
|
||||
public void doGet (HttpServletRequest request, HttpServletResponse response) {
|
||||
doPost(request, response);
|
||||
}
|
||||
|
||||
|
@ -269,21 +267,9 @@ public class PropertyRetryController extends BaseEditController {
|
|||
optionMap.put("RangeVClassURI", rangeOptionList);
|
||||
}
|
||||
|
||||
private List<VClass> makeVClassListForOptions(String VClassURI, List<VClass> allClassBeanList, VClassDao vclassDao) {
|
||||
List<VClass> currentClassList = new ArrayList<VClass>();
|
||||
VClass currentVClass = vclassDao.getVClassByURI(VClassURI);
|
||||
if (currentVClass != null && currentVClass.isAnonymous()) {
|
||||
currentClassList.addAll(allClassBeanList);
|
||||
currentClassList.add(0,currentVClass);
|
||||
} else {
|
||||
currentClassList = allClassBeanList;
|
||||
}
|
||||
return currentClassList;
|
||||
}
|
||||
|
||||
class PropertyInsertPageForwarder implements PageForwarder {
|
||||
|
||||
public void doForward(HttpServletRequest request, HttpServletResponse response, EditProcessObject epo){
|
||||
private static class PropertyInsertPageForwarder implements PageForwarder {
|
||||
@Override
|
||||
public void doForward(HttpServletRequest request, HttpServletResponse response, EditProcessObject epo){
|
||||
String newPropertyUrl = "propertyEdit?uri=";
|
||||
ObjectProperty p = (ObjectProperty) epo.getNewBean();
|
||||
try {
|
||||
|
|
|
@ -185,6 +185,7 @@ public class BaseSiteAdminController extends FreemarkerHttpServlet {
|
|||
urls.put("classHierarchy", UrlBuilder.getUrl("/showClassHierarchy"));
|
||||
urls.put("classGroups", UrlBuilder.getUrl("/listGroups"));
|
||||
urls.put("dataPropertyHierarchy", UrlBuilder.getUrl("/showDataPropertyHierarchy"));
|
||||
urls.put("fauxPropertyList", UrlBuilder.getUrl("/listFauxProperties"));
|
||||
urls.put("propertyGroups", UrlBuilder.getUrl("/listPropertyGroups"));
|
||||
urls.put("objectPropertyHierarchy", UrlBuilder.getUrl("/showObjectPropertyHierarchy", new ParamMap("iffRoot", "true")));
|
||||
map.put("urls", urls);
|
||||
|
|
|
@ -0,0 +1,232 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.freemarker;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.sf.json.util.JSONUtils;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.PropertyGroup;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
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.TemplateResponseValues;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VClassDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.URLEncoder;
|
||||
|
||||
public class ListFauxPropertiesController extends FreemarkerHttpServlet {
|
||||
|
||||
private static final Log log = LogFactory.getLog(ListFauxPropertiesController.class.getName());
|
||||
|
||||
private static final String TEMPLATE_NAME = "siteAdmin-fauxPropertiesList.ftl";
|
||||
|
||||
private ObjectPropertyDao opDao = null;
|
||||
private PropertyGroupDao pgDao = null;
|
||||
private FauxPropertyDao fpDao = null;
|
||||
private String notFoundMessage = "";
|
||||
|
||||
@Override
|
||||
protected AuthorizationRequest requiredActions(VitroRequest vreq) {
|
||||
return SimplePermission.EDIT_ONTOLOGY.ACTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResponseValues processRequest(VitroRequest vreq) {
|
||||
|
||||
Map<String, Object> body = new HashMap<String, Object>();
|
||||
try {
|
||||
|
||||
String displayOption = "";
|
||||
|
||||
if ( vreq.getParameter("displayOption") != null ) {
|
||||
displayOption = vreq.getParameter("displayOption");
|
||||
}
|
||||
else {
|
||||
displayOption = "listing";
|
||||
}
|
||||
body.put("displayOption", displayOption);
|
||||
|
||||
if ( displayOption.equals("listing") ) {
|
||||
body.put("pageTitle", "Faux Property Listing");
|
||||
}
|
||||
else {
|
||||
body.put("pageTitle", "Faux Properties by Base Property");
|
||||
}
|
||||
|
||||
opDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getObjectPropertyDao();
|
||||
fpDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getFauxPropertyDao();
|
||||
pgDao = vreq.getUnfilteredAssertionsWebappDaoFactory().getPropertyGroupDao();
|
||||
|
||||
List<ObjectProperty> objectProps = null;
|
||||
objectProps = opDao.getRootObjectProperties();
|
||||
|
||||
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());
|
||||
|
||||
if ( notFoundMessage.length() == 0 ) {
|
||||
body.put("message", notFoundMessage);
|
||||
}
|
||||
else {
|
||||
body.put("fauxProps", allFauxProps);
|
||||
}
|
||||
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
||||
|
||||
}
|
||||
|
||||
private TreeMap<String, Object> getFauxPropertyList(List<ObjectProperty> objectProps) {
|
||||
List<FauxProperty> fauxProps = null;
|
||||
TreeMap<String, Object> theFauxProps = new TreeMap<String, Object>();
|
||||
if ( objectProps != null ) {
|
||||
Iterator<ObjectProperty> opIt = objectProps.iterator();
|
||||
if ( !opIt.hasNext()) {
|
||||
notFoundMessage = "No object properties found.";
|
||||
}
|
||||
else {
|
||||
while (opIt.hasNext()) {
|
||||
|
||||
ObjectProperty op = opIt.next();
|
||||
String baseURI = op.getURI();
|
||||
fauxProps = fpDao.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 = getDisplayLabel(op) == null ? "(no name)" : getDisplayLabel(op);
|
||||
String baseLocalName = op.getLocalNameWithPrefix();
|
||||
baseLabel = baseLabel.substring(0,baseLabel.indexOf("("));
|
||||
baseLabel += "(" + baseLocalName + ")";
|
||||
// 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 = pgDao.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);
|
||||
// add the faux and its details to the treemap
|
||||
theFauxProps.put(fauxLabel + "@@" + domainLabel, tmpHash);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return theFauxProps;
|
||||
}
|
||||
|
||||
private TreeMap<String, Object> getFauxByBaseList(List<ObjectProperty> objectProps) {
|
||||
List<FauxProperty> fauxProps = null;
|
||||
TreeMap<String, Object> fauxByBaseProps = new TreeMap<String, Object>();
|
||||
if ( objectProps != null ) {
|
||||
Iterator<ObjectProperty> opIt = objectProps.iterator();
|
||||
if ( !opIt.hasNext()) {
|
||||
notFoundMessage = "No object properties found.";
|
||||
}
|
||||
else {
|
||||
while (opIt.hasNext()) {
|
||||
TreeMap<String, Object> fauxForGivenBase = new TreeMap<String, Object>();
|
||||
ObjectProperty op = opIt.next();
|
||||
String baseURI = op.getURI();
|
||||
fauxProps = fpDao.getFauxPropertiesForBaseUri(baseURI);
|
||||
|
||||
if ( fauxProps != null ) {
|
||||
Iterator<FauxProperty> fpIt = fauxProps.iterator();
|
||||
if ( !fpIt.hasNext()) {
|
||||
notFoundMessage = "No faux properties found.";
|
||||
}
|
||||
else {
|
||||
String baseLabel = getDisplayLabel(op) == null ? "(no name)" : getDisplayLabel(op);
|
||||
String baseLocalName = op.getLocalNameWithPrefix();
|
||||
baseLabel = baseLabel.substring(0,baseLabel.indexOf("("));
|
||||
baseLabel += "(" + baseLocalName + ")" + "|" + baseURI;
|
||||
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 = pgDao.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);
|
||||
}
|
||||
fauxByBaseProps.put(baseLabel, fauxForGivenBase);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return fauxByBaseProps;
|
||||
}
|
||||
|
||||
/*
|
||||
* should never be null
|
||||
*/
|
||||
public static String getDisplayLabel(ObjectProperty op) {
|
||||
String displayLabel = op.getPickListName();
|
||||
displayLabel = (displayLabel != null && displayLabel.length() > 0)
|
||||
? displayLabel
|
||||
: op.getLocalName();
|
||||
return (displayLabel != null) ? displayLabel : "[object property]" ;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
||||
|
||||
/**
|
||||
* Utility methods for fetching, storing and manipulating FauxProperty objects.
|
||||
*/
|
||||
public interface FauxPropertyDao {
|
||||
|
||||
/**
|
||||
* Get all of the FauxProperties that are based on this URI.
|
||||
*
|
||||
* @return May return an empty list. Never returns null.
|
||||
*/
|
||||
List<FauxProperty> getFauxPropertiesForBaseUri(String uri);
|
||||
|
||||
/**
|
||||
* If the display model contains a ConfigContext with this URI, get the
|
||||
* FauxProperty that it describes.
|
||||
*
|
||||
* @return May return null.
|
||||
*/
|
||||
FauxProperty getFauxPropertyFromContextUri(String contextUri);
|
||||
|
||||
/**
|
||||
* If the display model contains a ConfigContext based on these URIs, get
|
||||
* the FauxProperty that it describes. May return null.
|
||||
*
|
||||
* @param domainUri
|
||||
* May be null, but then this will only match a ConfigContext
|
||||
* that has no qualifiedByDomain property.
|
||||
* @param baseUri
|
||||
* Object of configContextFor property. May not be null.
|
||||
* @param rangeUri
|
||||
* Object of qualifiedBy property. May not be null.
|
||||
* @return May return null.
|
||||
*/
|
||||
FauxProperty getFauxPropertyByUris(String domainUri, String baseUri,
|
||||
String rangeUri);
|
||||
|
||||
/**
|
||||
* Creates a new FauxProperty in the display model.
|
||||
*
|
||||
* By "a new FauxProperty", we mean a new ConfigContext and a new
|
||||
* ObjectPropertyDisplayConfig linked to it.
|
||||
*
|
||||
* @throws IllegalStateException
|
||||
* if fp does not have null values for contextUri and configUri,
|
||||
* or if a FauxProperty already exists with this combination of
|
||||
* domain, base, and range URIs.
|
||||
* @throws IllegalArgumentException
|
||||
* if fp is not internally consistent.
|
||||
*/
|
||||
void insertFauxProperty(FauxProperty fp);
|
||||
|
||||
/**
|
||||
* Updates the properties of this FauxProperty in the display model.
|
||||
*
|
||||
* By "this FauxProperty", we mean the ConfigContext and
|
||||
* ObjectPropertyDisplayConfig whose URIs are stored in this FauxProperty.
|
||||
*
|
||||
* @throws IllegalStateException
|
||||
* if the display model contains no such individuals. If you
|
||||
* want to create a new FauxProperty instance, you should be
|
||||
* using insertFauxProperty() instead.
|
||||
* @throws IllegalArgumentException
|
||||
* if fp is not internally consistent.
|
||||
*/
|
||||
void updateFauxProperty(FauxProperty fp);
|
||||
|
||||
/**
|
||||
* Delete this FauxProperty from the display model.
|
||||
*
|
||||
* Delete any ConfigContext that is based on the constraints in this
|
||||
* FauxProperty, and any ObjectPropertyDisplayConfigs that depend on that
|
||||
* ConfigContext.
|
||||
*
|
||||
* If no such ConfigContext is found, no error is raised.
|
||||
*
|
||||
* No check is made to see whether the ObjectPropertyDisplayConfig matches
|
||||
* the settings on this FauxProperty.
|
||||
*/
|
||||
void deleteFauxProperty(FauxProperty fp);
|
||||
}
|
|
@ -7,6 +7,7 @@ import java.util.Objects;
|
|||
|
||||
import com.hp.hpl.jena.vocabulary.OWL;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
|
||||
|
@ -72,9 +73,12 @@ public interface PropertyDao {
|
|||
this(OWL_THING, uri, OWL_THING);
|
||||
}
|
||||
|
||||
public FullPropertyKey(Property prop) {
|
||||
this(prop.getDomainVClassURI(), prop.getURI(), prop
|
||||
.getRangeVClassURI());
|
||||
public FullPropertyKey(Property p) {
|
||||
this(p.getDomainVClassURI(), p.getURI(), p.getRangeVClassURI());
|
||||
}
|
||||
|
||||
public FullPropertyKey(RoleRestrictedProperty p) {
|
||||
this(p.getDomainVClassURI(), p.getURI(), p.getRangeVClassURI());
|
||||
}
|
||||
|
||||
public FullPropertyKey(String domainUri, String propertyUri,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -91,6 +91,11 @@ public interface WebappDaoFactory {
|
|||
* returns a Data Access Object for working with ontology class objects
|
||||
*/
|
||||
public VClassDao getVClassDao();
|
||||
|
||||
/**
|
||||
* returns a Data Access Object for working with "faux" ObjectProperties.
|
||||
*/
|
||||
public FauxPropertyDao getFauxPropertyDao();
|
||||
|
||||
|
||||
/* ==================== DAOs for ABox manipulation ===================== */
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.dao.filtering;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.filtering.filters.VitroFilters;
|
||||
|
||||
/**
|
||||
* TODO Find out if this is really necessary. If so, what is filtered?
|
||||
*/
|
||||
public class FauxPropertyDaoFiltering extends BaseFiltering implements FauxPropertyDao {
|
||||
final FauxPropertyDao innerFauxPropertyDao;
|
||||
final VitroFilters filters;
|
||||
|
||||
public FauxPropertyDaoFiltering(FauxPropertyDao fauxPropertyDao,
|
||||
VitroFilters filters) {
|
||||
super();
|
||||
this.innerFauxPropertyDao = fauxPropertyDao;
|
||||
this.filters = filters;
|
||||
}
|
||||
|
||||
/* filtered methods */
|
||||
|
||||
@Override
|
||||
public List<FauxProperty> getFauxPropertiesForBaseUri(String uri) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException(
|
||||
"FauxPropertyDao.getFauxPropertiesForBaseUri() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public FauxProperty getFauxPropertyFromContextUri(String contextUri) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException(
|
||||
"FauxPropertyDaoFiltering.getFauxPropertyFromConfigContextUri() not implemented.");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public FauxProperty getFauxPropertyByUris(String domainUri, String baseUri,
|
||||
String rangeUri) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException(
|
||||
"FauxPropertyDaoFiltering.getFauxPropertyByUris() not implemented.");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFauxProperty(FauxProperty fp) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("FauxPropertyDaoFiltering.updateFauxProperty() not implemented.");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteFauxProperty(FauxProperty fp) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("FauxPropertyDao.deleteFauxProperty() not implemented.");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertFauxProperty(FauxProperty fp) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException("FauxPropertyDao.insertFauxProperty() not implemented.");
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -10,6 +10,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
|||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.DisplayModelDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.MenuDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
||||
|
@ -57,6 +58,7 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory {
|
|||
transient private DataPropertyStatementDao filteringDataPropertyStatementDao=null;
|
||||
transient private IndividualDao filteringIndividualDao=null;
|
||||
transient private ObjectPropertyDao filteringObjectPropertyDao=null;
|
||||
transient private FauxPropertyDao filteringFauxPropertyDao=null;
|
||||
transient private ObjectPropertyStatementDao filteringObjectPropertyStatementDao=null;
|
||||
transient private VClassDao filteringVClassDao=null;
|
||||
|
||||
|
@ -234,6 +236,14 @@ public class WebappDaoFactoryFiltering implements WebappDaoFactory {
|
|||
return filteringObjectPropertyDao;
|
||||
}
|
||||
|
||||
public FauxPropertyDao getFauxPropertyDao() {
|
||||
if (filteringFauxPropertyDao == null ){
|
||||
filteringFauxPropertyDao = new FauxPropertyDaoFiltering(innerWebappDaoFactory.getFauxPropertyDao(),
|
||||
filters);
|
||||
}
|
||||
return filteringFauxPropertyDao;
|
||||
}
|
||||
|
||||
|
||||
public VClassDao getVClassDao() {
|
||||
if (filteringVClassDao == null ){
|
||||
|
|
|
@ -0,0 +1,638 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.dao.jena;
|
||||
|
||||
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.bindValues;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.uriValue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import com.hp.hpl.jena.ontology.ObjectProperty;
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.ontology.OntModelSpec;
|
||||
import com.hp.hpl.jena.ontology.OntResource;
|
||||
import com.hp.hpl.jena.query.QuerySolution;
|
||||
import com.hp.hpl.jena.query.ResultSet;
|
||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||
import com.hp.hpl.jena.rdf.model.ResIterator;
|
||||
import com.hp.hpl.jena.rdf.model.Resource;
|
||||
import com.hp.hpl.jena.vocabulary.OWL;
|
||||
import com.hp.hpl.jena.vocabulary.RDF;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.InsertException;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.QueryParser;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableOntModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableOntModelSelector;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockedOntModel;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class FauxPropertyDaoJena extends JenaBaseDao implements FauxPropertyDao {
|
||||
private static final Log log = LogFactory.getLog(FauxPropertyDaoJena.class);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Constants
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private static final String APPLICATION_CONTEXT_NS = "http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#";
|
||||
private static OntModel _constModel = ModelFactory
|
||||
.createOntologyModel(OntModelSpec.OWL_DL_MEM);
|
||||
|
||||
private static final Resource CONFIG_CONTEXT = createResource(appContext("ConfigContext"));
|
||||
private static final Resource OBJECT_PROPERTY_DISPLAY_CONFIG = createResource(appContext("ObjectPropertyDisplayConfig"));
|
||||
private static final ObjectProperty HAS_CONFIGURATION = createProperty(appContext("hasConfiguration"));
|
||||
private static final ObjectProperty CONFIG_CONTEXT_FOR = createProperty(appContext("configContextFor"));
|
||||
|
||||
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"));
|
||||
|
||||
private static final ObjectProperty RDFS_LABEL = createProperty(VitroVocabulary.LABEL);
|
||||
|
||||
private static final String SITE_CONFIG_NAMESPACE = "http://vitro.mannlib.cornell.edu/ns/vitro/siteConfig/";
|
||||
|
||||
private static String appContext(String localName) {
|
||||
return APPLICATION_CONTEXT_NS + localName;
|
||||
}
|
||||
|
||||
private static ObjectProperty createProperty(String uri) {
|
||||
return _constModel.createObjectProperty(uri);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// The instance
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private final LockableOntModelSelector models;
|
||||
|
||||
public FauxPropertyDaoJena(WebappDaoFactoryJena wadf) {
|
||||
super(wadf);
|
||||
this.models = new LockableOntModelSelector(wadf.getOntModelSelector());
|
||||
}
|
||||
|
||||
/**
|
||||
* Need to override this, so the boolean convenience methods will work off
|
||||
* the correct model.
|
||||
*/
|
||||
@Override
|
||||
protected OntModel getOntModel() {
|
||||
return getOntModelSelector().getDisplayModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FauxProperty> getFauxPropertiesForBaseUri(String uri) {
|
||||
try (LockedOntModel displayModel = models.getDisplayModel().read()) {
|
||||
if (uri == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<String> contextUris = new ArrayList<>();
|
||||
ResIterator contextResources = displayModel
|
||||
.listSubjectsWithProperty(CONFIG_CONTEXT_FOR,
|
||||
createResource(uri));
|
||||
for (Resource context : contextResources.toList()) {
|
||||
if (context.isURIResource()) {
|
||||
contextUris.add(context.asResource().getURI());
|
||||
}
|
||||
}
|
||||
|
||||
List<FauxProperty> fpList = new ArrayList<>();
|
||||
for (String contextUri : contextUris) {
|
||||
FauxProperty fp = getFauxPropertyFromContextUri(contextUri);
|
||||
if (fp != null) {
|
||||
fpList.add(fp);
|
||||
}
|
||||
}
|
||||
log.debug("Located " + fpList.size() + " FauxProperties.");
|
||||
return fpList;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns null if contextUri does not represent a valid CONFIG_CONTEXT.
|
||||
*/
|
||||
@Override
|
||||
public FauxProperty getFauxPropertyFromContextUri(String contextUri) {
|
||||
try (LockedOntModel displayModel = models.getDisplayModel().read()) {
|
||||
if (contextUri == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
OntResource context = displayModel.createOntResource(contextUri);
|
||||
if (!displayModel.contains(context, RDF.type, CONFIG_CONTEXT)) {
|
||||
log.debug("'" + contextUri + "' is not a CONFIG_CONTEXT");
|
||||
return null;
|
||||
}
|
||||
|
||||
Collection<String> baseUris = getPropertyResourceURIValues(context,
|
||||
CONFIG_CONTEXT_FOR);
|
||||
if (baseUris.isEmpty()) {
|
||||
log.debug("'" + contextUri + "' has no value for '"
|
||||
+ CONFIG_CONTEXT_FOR + "'");
|
||||
return null;
|
||||
}
|
||||
String baseUri = baseUris.iterator().next();
|
||||
|
||||
Collection<String> rangeUris = getPropertyResourceURIValues(
|
||||
context, QUALIFIED_BY_RANGE);
|
||||
if (rangeUris.isEmpty()) {
|
||||
log.debug("'" + contextUri + "' has no value for '"
|
||||
+ QUALIFIED_BY_RANGE + "'");
|
||||
return null;
|
||||
}
|
||||
String rangeUri = rangeUris.iterator().next();
|
||||
|
||||
// domainURI is optional.
|
||||
Collection<String> domainUris = getPropertyResourceURIValues(
|
||||
context, QUALIFIED_BY_DOMAIN);
|
||||
String domainUri = domainUris.isEmpty() ? null : domainUris
|
||||
.iterator().next();
|
||||
|
||||
FauxProperty fp = new FauxProperty(domainUri, baseUri, rangeUri);
|
||||
fp.setContextUri(contextUri);
|
||||
populateInstance(fp);
|
||||
log.debug("Loaded FauxProperty: " + fp);
|
||||
return fp;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FauxProperty getFauxPropertyByUris(String domainUri, String baseUri,
|
||||
String rangeUri) {
|
||||
Set<ConfigContext> contexts = ConfigContext.findByQualifiers(
|
||||
models.getDisplayModel(), domainUri, baseUri, rangeUri);
|
||||
if (contexts.isEmpty()) {
|
||||
log.debug("Can't find a FauxProperty for '" + domainUri + "', '"
|
||||
+ baseUri + "', '" + rangeUri + "'");
|
||||
return null;
|
||||
} else {
|
||||
FauxProperty fp = new FauxProperty(domainUri, baseUri, rangeUri);
|
||||
fp.setContextUri(contexts.iterator().next().getContextUri());
|
||||
populateInstance(fp);
|
||||
log.debug("Loaded FauxProperty: " + fp);
|
||||
return fp;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertFauxProperty(FauxProperty fp) {
|
||||
if ((fp.getContextUri() != null) || (fp.getConfigUri() != null)) {
|
||||
throw new IllegalStateException(
|
||||
"ContextUri and ConfigUri must be null on insert: " + fp);
|
||||
}
|
||||
|
||||
Set<ConfigContext> existingcontexts = ConfigContext.findByQualifiers(
|
||||
models.getDisplayModel(), fp.getDomainURI(), fp.getBaseURI(),
|
||||
fp.getRangeURI());
|
||||
if (!existingcontexts.isEmpty()) {
|
||||
throw new IllegalStateException(
|
||||
"FauxProperty with these qualifiers already exists: " + fp);
|
||||
}
|
||||
|
||||
try (LockedOntModel displayModel = models.getDisplayModel().write()) {
|
||||
fp.setContextUri(getUnusedURI());
|
||||
|
||||
OntResource context = displayModel.createOntResource(fp
|
||||
.getContextUri());
|
||||
addPropertyResourceValue(context, RDF.type, CONFIG_CONTEXT);
|
||||
addPropertyResourceURIValue(context, CONFIG_CONTEXT_FOR,
|
||||
fp.getBaseURI());
|
||||
addPropertyResourceURIValue(context, QUALIFIED_BY_RANGE,
|
||||
fp.getRangeURI());
|
||||
addPropertyResourceURINotEmpty(context, QUALIFIED_BY_DOMAIN,
|
||||
fp.getDomainURI());
|
||||
storeQualifiedByRoot(context, fp.getRangeURI());
|
||||
|
||||
fp.setConfigUri(getUnusedURI());
|
||||
addPropertyResourceURIValue(context, HAS_CONFIGURATION,
|
||||
fp.getConfigUri());
|
||||
|
||||
OntResource config = displayModel.createOntResource(fp
|
||||
.getConfigUri());
|
||||
addPropertyResourceValue(config, RDF.type,
|
||||
OBJECT_PROPERTY_DISPLAY_CONFIG);
|
||||
addPropertyResourceURINotEmpty(config, PROPERTY_GROUP,
|
||||
fp.getGroupURI());
|
||||
addPropertyStringValue(config, DISPLAY_NAME, fp.getDisplayName(),
|
||||
displayModel);
|
||||
addPropertyStringValue(config, PUBLIC_DESCRIPTION_ANNOT,
|
||||
fp.getPublicDescription(), displayModel);
|
||||
addPropertyIntValue(config, DISPLAY_RANK_ANNOT,
|
||||
fp.getDisplayTier(), displayModel);
|
||||
addPropertyIntValue(config, DISPLAY_LIMIT, fp.getDisplayLimit(),
|
||||
displayModel);
|
||||
addPropertyBooleanValue(config, PROPERTY_COLLATEBYSUBCLASSANNOT,
|
||||
fp.isCollateBySubclass(), displayModel);
|
||||
addPropertyBooleanValue(config, PROPERTY_SELECTFROMEXISTINGANNOT,
|
||||
fp.isSelectFromExisting(), displayModel);
|
||||
addPropertyBooleanValue(config, PROPERTY_OFFERCREATENEWOPTIONANNOT,
|
||||
fp.isOfferCreateNewOption(), displayModel);
|
||||
addPropertyStringValue(config, PROPERTY_CUSTOMENTRYFORMANNOT,
|
||||
fp.getCustomEntryForm(), displayModel);
|
||||
addPropertyStringValue(config, LIST_VIEW_FILE,
|
||||
fp.getCustomListView(), displayModel);
|
||||
|
||||
updatePropertyResourceURIValue(config,
|
||||
HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT, fp
|
||||
.getHiddenFromDisplayBelowRoleLevel().getURI());
|
||||
updatePropertyResourceURIValue(config,
|
||||
HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT, fp
|
||||
.getHiddenFromPublishBelowRoleLevel().getURI());
|
||||
updatePropertyResourceURIValue(config,
|
||||
PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT, fp
|
||||
.getProhibitedFromUpdateBelowRoleLevel().getURI());
|
||||
|
||||
} catch (InsertException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void addPropertyResourceURINotEmpty(OntResource context,
|
||||
ObjectProperty prop, String uri) {
|
||||
if (uri != null && !uri.isEmpty()) {
|
||||
addPropertyResourceURIValue(context, prop, uri);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
try (LockedOntModel displayModel = models.getDisplayModel().read()) {
|
||||
if (fp.getContextUri() == null) {
|
||||
throw new IllegalStateException("ContextURI may not be null: "
|
||||
+ fp);
|
||||
}
|
||||
Resource context = createResource(fp.getContextUri());
|
||||
|
||||
if (fp.getConfigUri() == null) {
|
||||
throw new IllegalStateException("ConfigURI may not be null: "
|
||||
+ fp);
|
||||
}
|
||||
Resource config = createResource(fp.getConfigUri());
|
||||
|
||||
if (!displayModel.contains(context, RDF.type, CONFIG_CONTEXT)) {
|
||||
throw new IllegalStateException("'" + context + "' is not a '"
|
||||
+ CONFIG_CONTEXT + "'");
|
||||
}
|
||||
if (!displayModel.contains(config, RDF.type,
|
||||
OBJECT_PROPERTY_DISPLAY_CONFIG)) {
|
||||
throw new IllegalStateException("'" + config + "' is not a '"
|
||||
+ OBJECT_PROPERTY_DISPLAY_CONFIG + "'");
|
||||
}
|
||||
if (!displayModel.contains(context, HAS_CONFIGURATION, config)) {
|
||||
throw new IllegalStateException("'" + config
|
||||
+ "' is not a configuration for '" + context + "'");
|
||||
}
|
||||
}
|
||||
|
||||
try (LockedOntModel displayModel = models.getDisplayModel().write()) {
|
||||
OntResource context = displayModel.createOntResource(fp
|
||||
.getContextUri());
|
||||
updatePropertyResourceURIValue(context, QUALIFIED_BY_RANGE,
|
||||
fp.getRangeURI());
|
||||
updatePropertyResourceURIValue(context, QUALIFIED_BY_DOMAIN,
|
||||
fp.getDomainURI());
|
||||
storeQualifiedByRoot(context, fp.getRangeURI());
|
||||
|
||||
OntResource config = displayModel.createOntResource(fp
|
||||
.getConfigUri());
|
||||
updatePropertyResourceURIValue(config, PROPERTY_GROUP,
|
||||
fp.getGroupURI());
|
||||
updatePropertyStringValue(config, DISPLAY_NAME,
|
||||
fp.getDisplayName(), displayModel);
|
||||
updatePropertyStringValue(config, PUBLIC_DESCRIPTION_ANNOT,
|
||||
fp.getPublicDescription(), displayModel);
|
||||
updatePropertyIntValue(config, DISPLAY_RANK_ANNOT,
|
||||
fp.getDisplayTier(), displayModel);
|
||||
updatePropertyIntValue(config, DISPLAY_LIMIT, fp.getDisplayLimit(),
|
||||
displayModel);
|
||||
updatePropertyBooleanValue(config, PROPERTY_COLLATEBYSUBCLASSANNOT,
|
||||
fp.isCollateBySubclass(), displayModel, true);
|
||||
updatePropertyBooleanValue(config,
|
||||
PROPERTY_SELECTFROMEXISTINGANNOT,
|
||||
fp.isSelectFromExisting(), displayModel, true);
|
||||
updatePropertyBooleanValue(config,
|
||||
PROPERTY_OFFERCREATENEWOPTIONANNOT,
|
||||
fp.isOfferCreateNewOption(), displayModel, true);
|
||||
updatePropertyStringValue(config, PROPERTY_CUSTOMENTRYFORMANNOT,
|
||||
fp.getCustomEntryForm(), displayModel);
|
||||
updatePropertyStringValue(config, LIST_VIEW_FILE,
|
||||
fp.getCustomListView(), displayModel);
|
||||
|
||||
updatePropertyResourceURIValue(config,
|
||||
HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT, fp
|
||||
.getHiddenFromDisplayBelowRoleLevel().getURI());
|
||||
updatePropertyResourceURIValue(config,
|
||||
HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT, fp
|
||||
.getHiddenFromPublishBelowRoleLevel().getURI());
|
||||
updatePropertyResourceURIValue(config,
|
||||
PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT, fp
|
||||
.getProhibitedFromUpdateBelowRoleLevel().getURI());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteFauxProperty(FauxProperty fp) {
|
||||
Set<ConfigContext> contexts = ConfigContext.findByQualifiers(
|
||||
models.getDisplayModel(), fp.getDomainURI(), fp.getURI(),
|
||||
fp.getRangeURI());
|
||||
try (LockedOntModel displayModel = models.getDisplayModel().write()) {
|
||||
for (ConfigContext context : contexts) {
|
||||
Resource configResource = createResource(context.getConfigUri());
|
||||
displayModel.removeAll(configResource, null, null);
|
||||
displayModel.removeAll(null, null, configResource);
|
||||
Resource contextResource = createResource(context
|
||||
.getContextUri());
|
||||
displayModel.removeAll(contextResource, null, null);
|
||||
displayModel.removeAll(null, null, contextResource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getUnusedURI() throws InsertException {
|
||||
String errMsg = null;
|
||||
|
||||
String namespace = SITE_CONFIG_NAMESPACE;
|
||||
String uri = null;
|
||||
|
||||
Random random = new Random(System.currentTimeMillis());
|
||||
for (int attempts = 0; attempts < 30; attempts++) {
|
||||
int upperBound = (int) Math.pow(2, attempts + 13);
|
||||
uri = namespace + ("fp" + random.nextInt(upperBound));
|
||||
if (!isUriUsed(uri)) {
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InsertException("Could not create URI for individual: "
|
||||
+ errMsg);
|
||||
}
|
||||
|
||||
private boolean isUriUsed(String uri) {
|
||||
try (LockedOntModel displayModel = models.getDisplayModel().read()) {
|
||||
return (displayModel.getOntResource(uri) != null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add labels, annotations, and whatever else we can find on the
|
||||
* ObjectPropertyDisplayConfig.
|
||||
*/
|
||||
private void populateInstance(FauxProperty fp) {
|
||||
populateLabelsFromTBox(fp);
|
||||
populateFieldsFromDisplayModel(fp);
|
||||
}
|
||||
|
||||
private void populateLabelsFromTBox(FauxProperty fp) {
|
||||
fp.setBaseLabel(findLabelForClass(fp.getBaseURI()));
|
||||
fp.setRangeLabel(findLabelForClass(fp.getRangeURI()));
|
||||
fp.setDomainLabel(findLabelForClass(fp.getDomainURI()));
|
||||
}
|
||||
|
||||
private String findLabelForClass(String classUri) {
|
||||
if (classUri == null) {
|
||||
return null;
|
||||
} else {
|
||||
try (LockedOntModel tboxModel = models.getTBoxModel().read()) {
|
||||
return getPropertyStringValue(
|
||||
tboxModel.createOntResource(classUri), RDFS_LABEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void populateFieldsFromDisplayModel(FauxProperty fp) {
|
||||
String configUri = locateConfigurationFromContext(fp.getContextUri());
|
||||
fp.setConfigUri(configUri);
|
||||
if (configUri != null) {
|
||||
try (LockedOntModel displayModel = models.getDisplayModel().read()) {
|
||||
OntResource config = displayModel.createOntResource(configUri);
|
||||
fp.setDisplayName(getPropertyStringValue(config, DISPLAY_NAME));
|
||||
fp.setPublicDescription(getPropertyStringValue(config,
|
||||
PUBLIC_DESCRIPTION_ANNOT));
|
||||
fp.setGroupURI(getSingleResourceURIValue(config, PROPERTY_GROUP));
|
||||
fp.setCustomListView(getPropertyStringValue(config,
|
||||
LIST_VIEW_FILE));
|
||||
fp.setDisplayTier(getPropertyIntValue(config,
|
||||
DISPLAY_RANK_ANNOT));
|
||||
fp.setDisplayLimit(getPropertyIntValue(config, DISPLAY_LIMIT));
|
||||
fp.setCollateBySubclass(Boolean.TRUE
|
||||
.equals(getPropertyBooleanValue(config,
|
||||
PROPERTY_COLLATEBYSUBCLASSANNOT)));
|
||||
fp.setSelectFromExisting(Boolean.TRUE
|
||||
.equals(getPropertyBooleanValue(config,
|
||||
PROPERTY_SELECTFROMEXISTINGANNOT)));
|
||||
fp.setOfferCreateNewOption(Boolean.TRUE
|
||||
.equals(getPropertyBooleanValue(config,
|
||||
PROPERTY_OFFERCREATENEWOPTIONANNOT)));
|
||||
fp.setCustomEntryForm(getPropertyStringValue(config,
|
||||
PROPERTY_CUSTOMENTRYFORMANNOT));
|
||||
|
||||
fp.setHiddenFromDisplayBelowRoleLevel(getMostRestrictiveRoleLevel(
|
||||
config, HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT));
|
||||
fp.setHiddenFromPublishBelowRoleLevel(getMostRestrictiveRoleLevel(
|
||||
config, HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT));
|
||||
fp.setProhibitedFromUpdateBelowRoleLevel(getMostRestrictiveRoleLevel(
|
||||
config, PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String locateConfigurationFromContext(String contextUri) {
|
||||
try (LockedOntModel displayModel = models.getDisplayModel().read()) {
|
||||
Collection<String> configUris = getPropertyResourceURIValues(
|
||||
displayModel.createOntResource(contextUri),
|
||||
HAS_CONFIGURATION);
|
||||
if (configUris.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return configUris.iterator().next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getSingleResourceURIValue(OntResource config,
|
||||
ObjectProperty prop) {
|
||||
Collection<String> values = getPropertyResourceURIValues(config, prop);
|
||||
if (values.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return values.iterator().next();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// ConfigContext
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private static final String QUERY_LOCATE_CONFIG_CONTEXT_WITH_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" //
|
||||
+ " :qualifiedByDomain ?domainUri ; \n" //
|
||||
+ " :qualifiedBy ?rangeUri ; \n" //
|
||||
+ " :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
|
||||
QueryParser<Set<ConfigContext>> {
|
||||
private final String domainUri;
|
||||
private final String baseUri;
|
||||
private final String rangeUri;
|
||||
|
||||
public ParserLocateConfigContext(String domainUri, String baseUri,
|
||||
String rangeUri) {
|
||||
this.domainUri = domainUri;
|
||||
this.baseUri = baseUri;
|
||||
this.rangeUri = rangeUri;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<ConfigContext> defaultValue() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<ConfigContext> parseResults(String queryStr,
|
||||
ResultSet results) {
|
||||
Set<ConfigContext> set = new HashSet<>();
|
||||
while (results.hasNext()) {
|
||||
QuerySolution row = results.next();
|
||||
String contextUri = ifResourcePresent(row, "context", null);
|
||||
String configUri = ifResourcePresent(row, "config", null);
|
||||
if (contextUri != null && configUri != null) {
|
||||
set.add(new ConfigContext(contextUri, configUri, domainUri,
|
||||
baseUri, rangeUri));
|
||||
}
|
||||
}
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ConfigContext {
|
||||
public static Set<ConfigContext> findByQualifiers(
|
||||
LockableOntModel lockableDisplayModel, String domainUri,
|
||||
String baseUri, String rangeUri) {
|
||||
try (LockedOntModel displayModel = lockableDisplayModel.read()) {
|
||||
String queryString;
|
||||
if (domainUri == null || domainUri.trim().isEmpty()
|
||||
|| domainUri.equals(OWL.Thing.getURI())) {
|
||||
queryString = bindValues(
|
||||
QUERY_LOCATE_CONFIG_CONTEXT_WITH_NO_DOMAIN,
|
||||
uriValue("baseUri", baseUri),
|
||||
uriValue("rangeUri", rangeUri));
|
||||
} else {
|
||||
queryString = bindValues(
|
||||
QUERY_LOCATE_CONFIG_CONTEXT_WITH_DOMAIN,
|
||||
uriValue("baseUri", baseUri),
|
||||
uriValue("rangeUri", rangeUri),
|
||||
uriValue("domainUri", domainUri));
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("domainUri=" + domainUri + ", baseUri=" + baseUri
|
||||
+ ", rangeUri=" + rangeUri + ", queryString="
|
||||
+ queryString);
|
||||
}
|
||||
|
||||
ParserLocateConfigContext parser = new ParserLocateConfigContext(
|
||||
domainUri, baseUri, rangeUri);
|
||||
Set<ConfigContext> contexts = new SparqlQueryRunner(
|
||||
displayModel).executeSelect(parser, queryString);
|
||||
|
||||
log.debug("found " + contexts.size() + " contexts: " + contexts);
|
||||
return contexts;
|
||||
}
|
||||
}
|
||||
|
||||
private final String contextUri;
|
||||
private final String configUri;
|
||||
private final String domainUri;
|
||||
private final String baseUri;
|
||||
private final String rangeUri;
|
||||
|
||||
public ConfigContext(String contextUri, String configUri,
|
||||
String domainUri, String baseUri, String rangeUri) {
|
||||
this.contextUri = contextUri;
|
||||
this.configUri = configUri;
|
||||
this.domainUri = domainUri;
|
||||
this.baseUri = baseUri;
|
||||
this.rangeUri = rangeUri;
|
||||
}
|
||||
|
||||
public String getContextUri() {
|
||||
return contextUri;
|
||||
}
|
||||
|
||||
public String getConfigUri() {
|
||||
return configUri;
|
||||
}
|
||||
|
||||
public String getDomainUri() {
|
||||
return domainUri;
|
||||
}
|
||||
|
||||
public String getBaseUri() {
|
||||
return baseUri;
|
||||
}
|
||||
|
||||
public String getRangeUri() {
|
||||
return rangeUri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ConfigContext[contextUri=" + contextUri + ", configUri="
|
||||
+ configUri + ", domainUri=" + domainUri + ", baseUri="
|
||||
+ baseUri + ", rangeUri=" + rangeUri + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -47,6 +47,7 @@ import com.hp.hpl.jena.util.iterator.ClosableIterator;
|
|||
import com.hp.hpl.jena.vocabulary.RDF;
|
||||
import com.hp.hpl.jena.vocabulary.RDFS;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
|
||||
public class JenaBaseDao extends JenaBaseDaoCon {
|
||||
|
@ -574,6 +575,20 @@ public class JenaBaseDao extends JenaBaseDaoCon {
|
|||
return list;
|
||||
}
|
||||
|
||||
protected RoleLevel getMostRestrictiveRoleLevel(Resource res, Property prop) {
|
||||
RoleLevel level = RoleLevel.getRoleByUri(null);
|
||||
for (Statement stmt : res.listProperties(prop).toList()) {
|
||||
if (stmt.getObject().isURIResource()) {
|
||||
RoleLevel roleFromModel = RoleLevel.getRoleByUri(stmt
|
||||
.getObject().as(Resource.class).getURI());
|
||||
if (roleFromModel.compareTo(level) > 0) {
|
||||
level = roleFromModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* convenience method for use with functional object properties
|
||||
*/
|
||||
|
|
|
@ -42,6 +42,7 @@ import com.hp.hpl.jena.vocabulary.OWL;
|
|||
import com.hp.hpl.jena.vocabulary.RDF;
|
||||
import com.hp.hpl.jena.vocabulary.RDFS;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Individual;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||
|
@ -1137,7 +1138,7 @@ public class ObjectPropertyDaoJena extends PropertyDaoJena implements ObjectProp
|
|||
}
|
||||
qexec.close();
|
||||
}
|
||||
FullPropertyKey key = new FullPropertyKey(op);
|
||||
FullPropertyKey key = new FullPropertyKey((RoleRestrictedProperty)op);
|
||||
String customListViewConfigFileName = customListViewConfigFileMap.get(key);
|
||||
if (customListViewConfigFileName == null) {
|
||||
log.debug("no list view found for " + key);
|
||||
|
|
|
@ -564,26 +564,36 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
|
|||
|
||||
}
|
||||
|
||||
/*
|
||||
/* Removed: see VIVO-766.
|
||||
* sorts VClasses so that subclasses come before superclasses
|
||||
*
|
||||
* Because subclass/superclass is only a partial ordering, this breaks the
|
||||
* contract for Comparator, and throws an IllegalArgumentException under Java 8.
|
||||
* In particular, for classes sub, super and other, we have sub=other, sub<super,
|
||||
* which should imply other<super, but that is not true.
|
||||
*
|
||||
* As far as I can determine, this sort is never relied on anyway, so there
|
||||
* should be no impact in removing it. Note that PropertyInstanceDaoJena re-sorts
|
||||
* thes results before using them, so this sort was irrelevant for any calls
|
||||
* through that path.
|
||||
*/
|
||||
private class VClassHierarchyRanker implements Comparator<VClass> {
|
||||
private VClassDao vcDao;
|
||||
public VClassHierarchyRanker(VClassDao vcDao) {
|
||||
this.vcDao = vcDao;
|
||||
}
|
||||
@Override
|
||||
public int compare(VClass vc1, VClass vc2) {
|
||||
if (vcDao.isSubClassOf(vc1, vc2)) {
|
||||
return -1;
|
||||
} else if (vcDao.isSubClassOf(vc2, vc1)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// private class VClassHierarchyRanker implements Comparator<VClass> {
|
||||
// private VClassDao vcDao;
|
||||
// public VClassHierarchyRanker(VClassDao vcDao) {
|
||||
// this.vcDao = vcDao;
|
||||
// }
|
||||
// @Override
|
||||
// public int compare(VClass vc1, VClass vc2) {
|
||||
// if (vcDao.isSubClassOf(vc1, vc2)) {
|
||||
// return -1;
|
||||
// } else if (vcDao.isSubClassOf(vc2, vc1)) {
|
||||
// return 1;
|
||||
// } else {
|
||||
// return 0;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
|
||||
public List<PropertyInstance> getAllPropInstByVClass(String classURI) {
|
||||
if (classURI==null || classURI.length()<1) {
|
||||
|
@ -708,7 +718,8 @@ public class PropertyDaoJena extends JenaBaseDao implements PropertyDao {
|
|||
return propInsts;
|
||||
}
|
||||
|
||||
Collections.sort(vclasses, new VClassHierarchyRanker(this.getWebappDaoFactory().getVClassDao()));
|
||||
// Removed: see VIVO-766.
|
||||
// Collections.sort(vclasses, new VClassHierarchyRanker(this.getWebappDaoFactory().getVClassDao()));
|
||||
|
||||
OntModel ontModel = getOntModelSelector().getTBoxModel();
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
|||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.DisplayModelDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.MenuDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
||||
|
@ -360,6 +361,15 @@ public class WebappDaoFactoryJena implements WebappDaoFactory {
|
|||
return objectPropertyDao;
|
||||
}
|
||||
|
||||
private FauxPropertyDao fauxPropertyDao = null;
|
||||
@Override
|
||||
public FauxPropertyDao getFauxPropertyDao() {
|
||||
if( fauxPropertyDao == null ) {
|
||||
fauxPropertyDao = new FauxPropertyDaoJena(this);
|
||||
}
|
||||
return fauxPropertyDao;
|
||||
}
|
||||
|
||||
private PropertyInstanceDao propertyInstanceDao = null;
|
||||
@Override
|
||||
public PropertyInstanceDao getPropertyInstanceDao() {
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.migration;
|
||||
|
||||
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createPlainLiteral;
|
||||
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty;
|
||||
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
|
||||
import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.vitroURI;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
import com.hp.hpl.jena.rdf.model.Literal;
|
||||
import com.hp.hpl.jena.rdf.model.Property;
|
||||
import com.hp.hpl.jena.rdf.model.Resource;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
|
||||
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockableOntModel;
|
||||
import edu.cornell.mannlib.vitro.webapp.utils.jena.criticalsection.LockedOntModel;
|
||||
|
||||
/**
|
||||
* PropertyConfig.n3 has moved to rdf/display/firsttime, so it is only pulled in
|
||||
* if the display model is empty.
|
||||
*
|
||||
* Let's pull it in one time, anyway.
|
||||
*
|
||||
* Check askUpdated.sparql for an example of how we know that it is necessary.
|
||||
* Also check success.n3
|
||||
*
|
||||
* If a special triple is not found in the display model, read the file from
|
||||
* firsttime. If we can't find the file, warn
|
||||
*/
|
||||
public class FauxPropertiesUpdater {
|
||||
private static final String[] PATH_TO_PROPERTY_CONFIG = { "rdf", "display",
|
||||
"firsttime", "PropertyConfig.n3" };
|
||||
|
||||
private static final Resource DISPLAY_MODEL = createResource(ModelNames.DISPLAY);
|
||||
private static final Property UPDATED_DISPLAY_MODEL = createProperty(vitroURI
|
||||
+ "updatedDisplayModel");
|
||||
private static final Literal VERSION_1_8 = createPlainLiteral("1.8");
|
||||
|
||||
private final ServletContextListener parent;
|
||||
private final StartupStatus ss;
|
||||
private final LockableOntModel lockableDisplayModel;
|
||||
|
||||
private Path propertyConfigPath;
|
||||
|
||||
public FauxPropertiesUpdater(ServletContext ctx,
|
||||
ServletContextListener parent) {
|
||||
this.parent = parent;
|
||||
this.ss = StartupStatus.getBean(ctx);
|
||||
this.lockableDisplayModel = new LockableOntModel(ModelAccess.on(ctx)
|
||||
.getOntModel(ModelNames.DISPLAY));
|
||||
}
|
||||
|
||||
public void migrate() {
|
||||
if (!isAlreadyUpdated()) {
|
||||
if (locateFile()) {
|
||||
if (loadFile()) {
|
||||
writeSuccess();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAlreadyUpdated() {
|
||||
try (LockedOntModel m = lockableDisplayModel.read()) {
|
||||
return m.contains(DISPLAY_MODEL, UPDATED_DISPLAY_MODEL, VERSION_1_8);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean locateFile() {
|
||||
String homePath = ApplicationUtils.instance().getHomeDirectory()
|
||||
.getPath().toString();
|
||||
propertyConfigPath = Paths.get(homePath, PATH_TO_PROPERTY_CONFIG);
|
||||
if (Files.exists(propertyConfigPath)) {
|
||||
return true;
|
||||
} else {
|
||||
ss.warning(parent, "Could not find attributes "
|
||||
+ "for faux properties at " + propertyConfigPath);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean loadFile() {
|
||||
try (LockedOntModel m = lockableDisplayModel.write()) {
|
||||
m.read(new FileInputStream(propertyConfigPath.toFile()), null, "N3");
|
||||
ss.info(parent, "Read " + propertyConfigPath
|
||||
+ " into display model: "
|
||||
+ "attributes for faux properties.");
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
ss.warning(parent,
|
||||
"Failed to read attributes for faux properties.", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void writeSuccess() {
|
||||
try (LockedOntModel m = lockableDisplayModel.write()) {
|
||||
m.add(DISPLAY_MODEL, UPDATED_DISPLAY_MODEL, VERSION_1_8);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.migration;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
/**
|
||||
* Handle the tasks that move an installation from 1.7 to 1.8.
|
||||
*/
|
||||
public class Release18Migrator implements ServletContextListener {
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
ServletContext ctx = sce.getServletContext();
|
||||
|
||||
new FauxPropertiesUpdater(ctx, this).migrate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
// Nothing to tear down.
|
||||
}
|
||||
|
||||
}
|
|
@ -34,8 +34,8 @@ public class ContextNodeFields implements DocumentModifier, ContextModelsUser{
|
|||
protected List<String> queries = new ArrayList<String>();
|
||||
protected boolean shutdown = false;
|
||||
protected Log log = LogFactory.getLog(ContextNodeFields.class);
|
||||
|
||||
private RDFService rdfService;
|
||||
//Subclasses may want to utilize rdfService directly (for example, to execute queries that yielding multiple variables mapped to different fields)
|
||||
protected RDFService rdfService;
|
||||
|
||||
@Override
|
||||
public void setContextModels(ContextModelAccess models) {
|
||||
|
|
|
@ -1,117 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.servlet.setup;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||
import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus;
|
||||
|
||||
/**
|
||||
* If there are RDB tables in the database that have not been converted to TDB,
|
||||
* throw an error.
|
||||
*
|
||||
* The ConfigurationPropertiesSmokeTests has already run, so we know we can
|
||||
* access the database. A table named "jena_graph", means that the database
|
||||
* contains RDB. A table named "vivo_rdb_migrated" means that the conversion
|
||||
* utility has been run.
|
||||
*/
|
||||
public class GuardAgainstUnmigratedRDB implements ServletContextListener {
|
||||
private static final String PROPERTY_DB_URL = "VitroConnection.DataSource.url";
|
||||
private static final String PROPERTY_DB_USERNAME = "VitroConnection.DataSource.username";
|
||||
private static final String PROPERTY_DB_PASSWORD = "VitroConnection.DataSource.password";
|
||||
private static final String PROPERTY_DB_DRIVER_CLASS_NAME = "VitroConnection.DataSource.driver";
|
||||
|
||||
private static final String DEFAULT_DRIVER_CLASS = "com.mysql.jdbc.Driver";
|
||||
|
||||
private static final String TABLE_NAME_RDB = "jena_graph";
|
||||
private static final String TABLE_NAME_CONVERSION = "vivo_rdb_migrated";
|
||||
|
||||
private static final String MESSAGE_PROBLEM = "The database at %s"
|
||||
+ " contains data from an earlier VIVO (before 1.7). "
|
||||
+ "It does not appear that this data has been migrated. "
|
||||
+ "The upgrade guide has instructions on migrating "
|
||||
+ "this data to the current VIVO.";
|
||||
private static final String MESSAGE_TECHNICAL = "More technically: "
|
||||
+ "the database contains tables used by Jena RDB ('jena_graph' and "
|
||||
+ "others). It does not contain the table 'vivo_rdb_migrated', "
|
||||
+ "which is created when the data is migrated to Jena TDB files.";
|
||||
private static final String MESSAGE_WHAT_NOW = "You must either migrate "
|
||||
+ "the obsolete RDB data or remove it from your database.";
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
ServletContext ctx = sce.getServletContext();
|
||||
ConfigurationProperties props = ConfigurationProperties.getBean(ctx);
|
||||
StartupStatus ss = StartupStatus.getBean(ctx);
|
||||
|
||||
String url = props.getProperty(PROPERTY_DB_URL);
|
||||
String username = props.getProperty(PROPERTY_DB_USERNAME);
|
||||
String password = props.getProperty(PROPERTY_DB_PASSWORD);
|
||||
String driverClassName = props.getProperty(
|
||||
PROPERTY_DB_DRIVER_CLASS_NAME, DEFAULT_DRIVER_CLASS);
|
||||
|
||||
try {
|
||||
Class.forName(driverClassName).newInstance();
|
||||
|
||||
Properties connectionProps = new Properties();
|
||||
connectionProps.put("user", username);
|
||||
connectionProps.put("password", password);
|
||||
|
||||
try (Connection conn = DriverManager.getConnection(url,
|
||||
connectionProps)) {
|
||||
boolean hasRdb = checkForRdbTables(conn);
|
||||
boolean hasBeenConverted = checkForConversionTable(conn);
|
||||
if (hasRdb && !hasBeenConverted) {
|
||||
ss.fatal(this, String.format(MESSAGE_PROBLEM, url));
|
||||
ss.fatal(this, String.format(MESSAGE_TECHNICAL, url));
|
||||
ss.fatal(this, String.format(MESSAGE_WHAT_NOW, url));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
ss.fatal(this, "Can't connect to the database: "
|
||||
+ PROPERTY_DB_URL + "='" + url + "', "
|
||||
+ PROPERTY_DB_USERNAME + "='" + username + "'", e);
|
||||
}
|
||||
} catch (InstantiationException | IllegalAccessException
|
||||
| ClassNotFoundException e) {
|
||||
ss.fatal(this, "Can't load the database driver: " + driverClassName);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkForRdbTables(Connection conn) throws SQLException {
|
||||
DatabaseMetaData md = conn.getMetaData();
|
||||
try (ResultSet rs = md.getTables(null, null, TABLE_NAME_RDB, null);) {
|
||||
while (rs.next()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean checkForConversionTable(Connection conn)
|
||||
throws SQLException {
|
||||
DatabaseMetaData md = conn.getMetaData();
|
||||
try (ResultSet rs = md.getTables(null, null, TABLE_NAME_CONVERSION,
|
||||
null);) {
|
||||
while (rs.next()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce) {
|
||||
// Nothing to tear down.
|
||||
}
|
||||
|
||||
}
|
|
@ -15,6 +15,7 @@ import com.hp.hpl.jena.query.Syntax;
|
|||
import com.hp.hpl.jena.rdf.model.Literal;
|
||||
import com.hp.hpl.jena.rdf.model.Model;
|
||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||
import com.hp.hpl.jena.rdf.model.RDFNode;
|
||||
|
||||
/**
|
||||
* Execute SPARQL queries against a model.
|
||||
|
@ -95,6 +96,15 @@ public class SparqlQueryRunner {
|
|||
|
||||
protected abstract T defaultValue();
|
||||
|
||||
protected String ifResourcePresent(QuerySolution solution,
|
||||
String variableName, String defaultValue) {
|
||||
RDFNode node = solution.get(variableName);
|
||||
if (node == null || !node.isURIResource()) {
|
||||
return defaultValue;
|
||||
}
|
||||
return node.asResource().getURI();
|
||||
}
|
||||
|
||||
protected String ifLiteralPresent(QuerySolution solution,
|
||||
String variableName, String defaultValue) {
|
||||
Literal literal = solution.getLiteral(variableName);
|
||||
|
@ -126,5 +136,36 @@ public class SparqlQueryRunner {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
public static String bindValues(String rawString, VariableValue... values) {
|
||||
String queryString = rawString;
|
||||
for (VariableValue value: values) {
|
||||
queryString = value.bind(queryString);
|
||||
}
|
||||
return queryString;
|
||||
}
|
||||
|
||||
public static UriValue uriValue(String name, String uri) {
|
||||
return new UriValue(name, uri);
|
||||
}
|
||||
|
||||
public interface VariableValue {
|
||||
String bind(String rawString);
|
||||
}
|
||||
|
||||
private static class UriValue implements VariableValue {
|
||||
private final String name;
|
||||
private final String uri;
|
||||
|
||||
public UriValue(String name, String uri) {
|
||||
this.name = name;
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String bind(String rawString) {
|
||||
return rawString.replaceAll("\\?" + name + "\\b", "<" + uri + ">");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector;
|
|||
* LockableOntModels.
|
||||
*
|
||||
* <pre>
|
||||
* LockableOntModelSelector lockableOms = new LockingOntModelSelector(oms);
|
||||
* LockableOntModelSelector lockableOms = new LockableOntModelSelector(oms);
|
||||
*
|
||||
* try (LockedOntModel m = lockableOms.getDisplayModel.read()) {
|
||||
* ...
|
||||
|
|
|
@ -69,8 +69,7 @@ public class DataPropertyTemplateModel extends PropertyTemplateModel {
|
|||
DataPropertyTemplateModel(DataProperty dp, Individual subject, VitroRequest vreq,
|
||||
boolean editing, List<DataProperty> populatedDataPropertyList) {
|
||||
|
||||
super(dp, subject, vreq);
|
||||
setName(dp.getPublicName());
|
||||
super(dp, subject, vreq, dp.getPublicName());
|
||||
|
||||
// Get the config for this data property
|
||||
try {
|
||||
|
|
|
@ -20,10 +20,10 @@ 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.PropertyInstance;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.VClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.PropertyGroupDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.PropertyInstanceDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
|
@ -42,7 +42,6 @@ import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
|
|||
*/
|
||||
public class GroupedPropertyList extends BaseTemplateModel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Log log = LogFactory.getLog(GroupedPropertyList.class);
|
||||
private static final int MAX_GROUP_DISPLAY_RANK = 99;
|
||||
|
||||
|
@ -247,16 +246,9 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
|||
}
|
||||
boolean addToList = true;
|
||||
for(ObjectProperty op : populatedObjectPropertyList) {
|
||||
RedundancyReason reason = redundant(op, piOp);
|
||||
if(reason != null) {
|
||||
addToList = false;
|
||||
if (reason == RedundancyReason.LABEL_AND_URI_MATCH
|
||||
&& moreRestrictiveRange(piOp, op, wadf)) {
|
||||
op.setRangeVClassURI(piOp.getRangeVClassURI());
|
||||
op.setRangeVClass(piOp.getRangeVClass());
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (redundant(op, piOp)) {
|
||||
addToList = false;
|
||||
}
|
||||
}
|
||||
if(addToList) {
|
||||
propertyList.add(piOp);
|
||||
|
@ -281,67 +273,8 @@ public class GroupedPropertyList extends BaseTemplateModel {
|
|||
return propertyList;
|
||||
}
|
||||
|
||||
private enum RedundancyReason {
|
||||
LABEL_AND_URI_MATCH, LABEL_URI_DOMAIN_AND_RANGE_MATCH
|
||||
}
|
||||
|
||||
private boolean moreRestrictiveRange(ObjectProperty piOp, ObjectProperty op,
|
||||
WebappDaoFactory wadf) {
|
||||
if(piOp.getRangeVClassURI() == null) {
|
||||
return false;
|
||||
} else if (op.getRangeVClassURI() == null) {
|
||||
return (piOp.getRangeVClassURI() != null);
|
||||
} else {
|
||||
//Check and see if the range vclass exists for the possible piOp and populated op properties,
|
||||
//because for populated properties, if the range class is a union,
|
||||
//blank nodes will be broken and the code should instead use the existing or piOp range class uri
|
||||
VClass piOpRangeClass = wadf.getVClassDao().getVClassByURI(piOp.getRangeVClassURI());
|
||||
VClass opRangeClass = wadf.getVClassDao().getVClassByURI(op.getRangeVClassURI());
|
||||
//if the possible range class exists but the populated one does not, then return true to allow the possible
|
||||
//class to be utilized
|
||||
if(piOpRangeClass != null && opRangeClass == null) return true;
|
||||
return (wadf.getVClassDao().isSubClassOf(
|
||||
piOp.getRangeVClassURI(), op.getRangeVClassURI()));
|
||||
}
|
||||
}
|
||||
|
||||
private RedundancyReason redundant(ObjectProperty op, ObjectProperty op2) {
|
||||
if (op2.getURI() == null) {
|
||||
return null;
|
||||
}
|
||||
boolean uriMatches = (op.getURI() != null
|
||||
&& op.getURI().equals(op2.getURI()));
|
||||
boolean domainMatches = false;
|
||||
boolean rangeMatches = false;
|
||||
boolean labelMatches = false;
|
||||
if(op.getDomainPublic() == null) {
|
||||
if(op2.getDomainPublic() == null) {
|
||||
labelMatches = true;
|
||||
}
|
||||
} else if (op.getDomainPublic().equals(op2.getDomainPublic())) {
|
||||
labelMatches = true;
|
||||
}
|
||||
if(uriMatches && labelMatches) {
|
||||
return RedundancyReason.LABEL_AND_URI_MATCH;
|
||||
}
|
||||
if(op.getDomainVClassURI() == null) {
|
||||
if(op2.getDomainVClassURI() == null) {
|
||||
domainMatches = true;
|
||||
}
|
||||
} else if (op.getDomainVClassURI().equals(op2.getDomainVClassURI())) {
|
||||
domainMatches = true;
|
||||
}
|
||||
if(op.getRangeVClassURI() == null) {
|
||||
if (op2.getRangeVClassURI() == null) {
|
||||
rangeMatches = true;
|
||||
}
|
||||
} else if (op.getRangeVClassURI().equals(op2.getRangeVClassURI())) {
|
||||
rangeMatches = true;
|
||||
}
|
||||
if (uriMatches && domainMatches && rangeMatches) {
|
||||
return RedundancyReason.LABEL_URI_DOMAIN_AND_RANGE_MATCH;
|
||||
}
|
||||
return null;
|
||||
private boolean redundant(ObjectProperty op, ObjectProperty op2) {
|
||||
return new FullPropertyKey((Property)op).equals(new FullPropertyKey((Property)op2));
|
||||
}
|
||||
|
||||
private void addObjectPropertyToPropertyList(String propertyUri, String domainUri, String rangeUri,
|
||||
|
|
|
@ -86,8 +86,7 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
|
|||
boolean editing)
|
||||
throws InvalidConfigurationException {
|
||||
|
||||
super(op, subject, vreq);
|
||||
setName(op.getDomainPublic());
|
||||
super(op, subject, vreq, op.getDomainPublic());
|
||||
|
||||
sortDirection = op.getDomainEntitySortDirection();
|
||||
domainUri = op.getDomainVClassURI();
|
||||
|
@ -232,7 +231,6 @@ public abstract class ObjectPropertyTemplateModel extends PropertyTemplateModel
|
|||
public static ObjectPropertyTemplateModel getObjectPropertyTemplateModel(ObjectProperty op,
|
||||
Individual subject, VitroRequest vreq, boolean editing,
|
||||
List<ObjectProperty> populatedObjectPropertyList) {
|
||||
|
||||
if (op.getCollateBySubclass()) {
|
||||
try {
|
||||
return new CollatedObjectPropertyTemplateModel(op, subject, vreq, editing, populatedObjectPropertyList);
|
||||
|
|
|
@ -11,13 +11,13 @@ 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.ObjectPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
import edu.cornell.mannlib.vitro.webapp.web.templatemodels.BaseTemplateModel;
|
||||
|
||||
|
@ -40,21 +40,23 @@ public abstract class PropertyTemplateModel extends BaseTemplateModel {
|
|||
protected String addUrl;
|
||||
|
||||
private String name;
|
||||
|
||||
|
||||
private FauxProperty fauxProperty;
|
||||
|
||||
PropertyTemplateModel(Property property, Individual subject, VitroRequest vreq) {
|
||||
PropertyTemplateModel(Property property, Individual subject, VitroRequest vreq, String name) {
|
||||
this.vreq = vreq;
|
||||
subjectUri = subject.getURI();
|
||||
this.property = property;
|
||||
propertyUri = property.getURI();
|
||||
localName = property.getLocalName();
|
||||
setVerboseDisplayValues(property);
|
||||
this.name = name;
|
||||
addUrl = "";
|
||||
|
||||
// Do in subclass constructor. The label has not been set on the property, and the
|
||||
// means of getting the label differs between object and data properties.
|
||||
// this.name = property.getLabel();
|
||||
fauxProperty = isFauxProperty(property);
|
||||
if (fauxProperty != null) {
|
||||
this.name = fauxProperty.getDisplayName();
|
||||
}
|
||||
|
||||
setVerboseDisplayValues(property);
|
||||
}
|
||||
|
||||
protected void setVerboseDisplayValues(Property property) {
|
||||
|
@ -101,35 +103,31 @@ 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");
|
||||
if (fauxProperty != null) {
|
||||
verboseDisplay.put("fauxProperty", assembleFauxPropertyValues(fauxProperty));
|
||||
}
|
||||
}
|
||||
|
||||
private FauxProperty isFauxProperty(Property prop) {
|
||||
FauxPropertyDao fpDao = vreq.getUnfilteredWebappDaoFactory().getFauxPropertyDao();
|
||||
return fpDao.getFauxPropertyByUris(prop.getDomainVClassURI(), prop.getURI(), prop.getRangeVClassURI());
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.format("%s on %s",
|
||||
propertyUri != null ? propertyUri : "null Prop URI",
|
||||
|
|
|
@ -12,7 +12,7 @@ import static org.junit.Assert.assertNull;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelperStub;
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBeanStub;
|
||||
import stubs.javax.servlet.ServletContextStub;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
|
@ -23,7 +23,6 @@ import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
|||
import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasProfile;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction;
|
||||
|
@ -71,9 +70,8 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
|
|||
public void setUp() throws Exception {
|
||||
ctx = new ServletContextStub();
|
||||
|
||||
PropertyRestrictionPolicyHelper prph = PropertyRestrictionPolicyHelperStub
|
||||
PropertyRestrictionBeanStub
|
||||
.getInstance(new String[] { UNSAFE_NS });
|
||||
PropertyRestrictionPolicyHelper.setBean(ctx, prph);
|
||||
|
||||
policy = new SelfEditingPolicy(ctx);
|
||||
|
||||
|
@ -87,14 +85,13 @@ public class SelfEditingPolicyTest extends AbstractTestClass {
|
|||
|
||||
@Test
|
||||
public void testProhibitedProperties() {
|
||||
PropertyRestrictionPolicyHelper prph = PropertyRestrictionPolicyHelperStub
|
||||
PropertyRestrictionBeanStub
|
||||
.getInstance(new String[] { UNSAFE_NS }, new String[] {
|
||||
"http://mannlib.cornell.edu/bad#prp234",
|
||||
"http://mannlib.cornell.edu/bad#prp999",
|
||||
"http://mannlib.cornell.edu/bad#prp333",
|
||||
"http://mannlib.cornell.edu/bad#prp777",
|
||||
"http://mannlib.cornell.edu/bad#prp0020" });
|
||||
PropertyRestrictionPolicyHelper.setBean(ctx, prph);
|
||||
|
||||
whatToAuth = new AddObjectPropertyStatement(ontModel, SELFEDITOR_URI,
|
||||
new Property("http://mannlib.cornell.edu/bad#prp234"), SAFE_RESOURCE);
|
||||
|
|
|
@ -10,7 +10,7 @@ import org.junit.Assert;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelperStub;
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBeanStub;
|
||||
import stubs.javax.servlet.ServletContextStub;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
|
@ -22,7 +22,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle;
|
|||
import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasProfile;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement;
|
||||
|
@ -78,9 +77,7 @@ public class SelfEditingPolicy_2_Test extends AbstractTestClass {
|
|||
@Before
|
||||
public void setUp() throws Exception {
|
||||
ServletContextStub ctx = new ServletContextStub();
|
||||
PropertyRestrictionPolicyHelper.setBean(ctx,
|
||||
PropertyRestrictionPolicyHelperStub
|
||||
.getInstance(new String[] { ADMIN_NS }));
|
||||
PropertyRestrictionBeanStub.getInstance(new String[] { ADMIN_NS });
|
||||
|
||||
policy = new SelfEditingPolicy(ctx);
|
||||
Assert.assertNotNull(policy);
|
||||
|
|
|
@ -0,0 +1,511 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.auth.policy.bean;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which.DISPLAY;
|
||||
import static edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which.MODIFY;
|
||||
import static edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which.PUBLISH;
|
||||
import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.CURATOR;
|
||||
import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.DB_ADMIN;
|
||||
import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.EDITOR;
|
||||
import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.NOBODY;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDaoStub;
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDaoStub;
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDaoStub;
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub;
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccessStub;
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey;
|
||||
|
||||
/**
|
||||
* If we believe that authorization will succeed regardless of user role, check
|
||||
* that it succeeds with the lowest role.
|
||||
*
|
||||
* If we believe that authorization will fail regardless of user role, check
|
||||
* that it fails with the highest role.
|
||||
*
|
||||
* If we believe that authorization depends on the user role, it should pass if
|
||||
* the user role is higher than or equal to the threshold, and fail if the user
|
||||
* role is less than the threshold.
|
||||
*
|
||||
* Note that we can't set a threshold to be tested to either the lowest or
|
||||
* highest role, or the attempt to test with higher or lower role will throw an
|
||||
* exception.
|
||||
*/
|
||||
public class PropertyRestrictionBeanImplTest extends AbstractTestClass {
|
||||
private static final String NS_PROHIBITED = "http://prbi.prohibited/";
|
||||
private static final String URI_RESOURCE_EXCEPTIONAL = NS_PROHIBITED
|
||||
+ "exceptionalResource";
|
||||
private static final String URI_PREDICATE_EXCEPTIONAL = NS_PROHIBITED
|
||||
+ "exceptionalPredicate";
|
||||
|
||||
private static final List<String> PROHIBITED_NAMESPACES = Arrays
|
||||
.asList(new String[] { NS_PROHIBITED });
|
||||
private static final List<String> PERMITTED_EXCEPTIONS = Arrays
|
||||
.asList(new String[] { URI_RESOURCE_EXCEPTIONAL,
|
||||
URI_PREDICATE_EXCEPTIONAL });
|
||||
|
||||
private static final String URI_RESOURCE_ANY = "http://prbi.test/anyResource";
|
||||
private static final String URI_RESOURCE_PROHIBITED = NS_PROHIBITED
|
||||
+ "resource";
|
||||
|
||||
private static final String URI_PREDICATE_BARE = "http://prbi.test/barePredicate";
|
||||
private static final String URI_PREDICATE_PROHIBITED = NS_PROHIBITED
|
||||
+ "predicate";
|
||||
private static final String URI_PREDICATE_UNKNOWN = "http://prbi.test/unknownPredicate";
|
||||
|
||||
private static final String URI_DOMAIN_1 = "http://prbi.test/domain1";
|
||||
private static final String URI_RANGE_1 = "http://prbi.test/range1";
|
||||
private static final String URI_DOMAIN_2 = "http://prbi.test/domain2";
|
||||
private static final String URI_RANGE_2 = "http://prbi.test/range2";
|
||||
|
||||
private PropertyRestrictionBeanImpl bean;
|
||||
|
||||
private ObjectProperty barePredicate;
|
||||
private ObjectProperty prohibitedPredicate;
|
||||
private ObjectProperty exceptionalPredicate;
|
||||
private ObjectProperty unknownPredicate;
|
||||
|
||||
private FauxProperty emptyFaux;
|
||||
private FauxProperty restrictedFaux;
|
||||
private FauxProperty unknownFaux;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
barePredicate = createObjectProperty(null, URI_PREDICATE_BARE, null,
|
||||
EDITOR, CURATOR, DB_ADMIN);
|
||||
unknownPredicate = createObjectProperty(null, URI_PREDICATE_UNKNOWN,
|
||||
null, null, null, null);
|
||||
prohibitedPredicate = createObjectProperty(null,
|
||||
URI_PREDICATE_PROHIBITED, null, null, null, null);
|
||||
exceptionalPredicate = createObjectProperty(null,
|
||||
URI_PREDICATE_EXCEPTIONAL, null, CURATOR, EDITOR, EDITOR);
|
||||
|
||||
emptyFaux = createFauxProperty(URI_DOMAIN_1, URI_PREDICATE_BARE,
|
||||
URI_RANGE_1, null, null, null);
|
||||
restrictedFaux = createFauxProperty(URI_DOMAIN_2, URI_PREDICATE_BARE,
|
||||
URI_RANGE_2, EDITOR, DB_ADMIN, CURATOR);
|
||||
unknownFaux = createFauxProperty(URI_DOMAIN_1, URI_PREDICATE_UNKNOWN,
|
||||
URI_RANGE_1, NOBODY, NOBODY, NOBODY);
|
||||
|
||||
ObjectPropertyDaoStub opDao = new ObjectPropertyDaoStub();
|
||||
opDao.addObjectProperty(barePredicate);
|
||||
opDao.addObjectProperty(prohibitedPredicate);
|
||||
opDao.addObjectProperty(exceptionalPredicate);
|
||||
|
||||
DataPropertyDaoStub dpDao = new DataPropertyDaoStub();
|
||||
|
||||
FauxPropertyDaoStub fpDao = new FauxPropertyDaoStub();
|
||||
fpDao.insertFauxProperty(emptyFaux);
|
||||
fpDao.insertFauxProperty(restrictedFaux);
|
||||
|
||||
WebappDaoFactoryStub wadf = new WebappDaoFactoryStub();
|
||||
wadf.setObjectPropertyDao(opDao);
|
||||
wadf.setDataPropertyDao(dpDao);
|
||||
wadf.setFauxPropertyDao(fpDao);
|
||||
|
||||
ContextModelAccessStub models = new ContextModelAccessStub();
|
||||
models.setWebappDaoFactory(wadf);
|
||||
|
||||
bean = new PropertyRestrictionBeanImpl(PROHIBITED_NAMESPACES,
|
||||
PERMITTED_EXCEPTIONS, models);
|
||||
}
|
||||
|
||||
private ObjectProperty createObjectProperty(String domainUri, String uri,
|
||||
String rangeUri, RoleLevel displayThreshold,
|
||||
RoleLevel modifyThreshold, RoleLevel publishThreshold) {
|
||||
ObjectProperty op = new ObjectProperty();
|
||||
op.setURI(uri);
|
||||
op.setDomainVClassURI(domainUri);
|
||||
op.setRangeVClassURI(rangeUri);
|
||||
op.setHiddenFromDisplayBelowRoleLevel(displayThreshold);
|
||||
op.setProhibitedFromUpdateBelowRoleLevel(modifyThreshold);
|
||||
op.setHiddenFromPublishBelowRoleLevel(publishThreshold);
|
||||
return op;
|
||||
}
|
||||
|
||||
private FauxProperty createFauxProperty(String domainUri, String uri,
|
||||
String rangeUri, RoleLevel displayThreshold,
|
||||
RoleLevel modifyThreshold, RoleLevel publishThreshold) {
|
||||
FauxProperty fp = new FauxProperty(domainUri, uri, rangeUri);
|
||||
fp.setHiddenFromDisplayBelowRoleLevel(displayThreshold);
|
||||
fp.setProhibitedFromUpdateBelowRoleLevel(modifyThreshold);
|
||||
fp.setHiddenFromPublishBelowRoleLevel(publishThreshold);
|
||||
return fp;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Resources
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void nullResource_display_false() {
|
||||
assertFalse(bean.canDisplayResource(null, highestRole()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void anyResource_display_true() {
|
||||
assertTrue(bean.canDisplayResource(URI_RESOURCE_ANY, lowestRole()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void anyResource_nullUserRole_display_false() {
|
||||
assertFalse(bean.canDisplayResource(URI_RESOURCE_ANY, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullResource_modify_false() {
|
||||
assertFalse(bean.canModifyResource(null, highestRole()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prohibitedResource_modify_false() {
|
||||
assertFalse(bean.canModifyResource(URI_RESOURCE_PROHIBITED,
|
||||
highestRole()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exceptionalResource_modify_true() {
|
||||
assertTrue(bean.canModifyResource(URI_RESOURCE_EXCEPTIONAL,
|
||||
lowestRole()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unremarkableResource_modify_true() {
|
||||
assertTrue(bean.canModifyResource(URI_RESOURCE_ANY, lowestRole()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unremarkableResource_nullUserRole_modify_false() {
|
||||
assertFalse(bean.canModifyResource(URI_RESOURCE_ANY, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullResource_publish_false() {
|
||||
assertFalse(bean.canPublishResource(null, highestRole()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void anyResource_publish_true() {
|
||||
assertTrue(bean.canPublishResource(URI_RESOURCE_ANY, lowestRole()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void anyResource_nullUserRole_publish_false() {
|
||||
assertFalse(bean.canPublishResource(URI_RESOURCE_ANY, null));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Predicates
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
// ----- display
|
||||
|
||||
@Test
|
||||
public void nullPredicate_display_false() {
|
||||
assertFalse(bean.canDisplayPredicate(null, highestRole()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void barePredicate_display_byRole() {
|
||||
assertTrue(bean.canDisplayPredicate(barePredicate,
|
||||
higherRole(barePredicate, DISPLAY)));
|
||||
assertTrue(bean.canDisplayPredicate(barePredicate,
|
||||
sameRole(barePredicate, DISPLAY)));
|
||||
assertFalse(bean.canDisplayPredicate(barePredicate,
|
||||
lowerRole(barePredicate, DISPLAY)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unknownBarePredicate_display_true() {
|
||||
assertTrue(bean.canDisplayPredicate(unknownPredicate, lowestRole()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyQualifiedPredicate_display_byBareRole() {
|
||||
assertTrue(bean.canDisplayPredicate(asProperty(emptyFaux),
|
||||
higherRole(barePredicate, DISPLAY)));
|
||||
assertTrue(bean.canDisplayPredicate(asProperty(emptyFaux),
|
||||
sameRole(barePredicate, DISPLAY)));
|
||||
assertFalse(bean.canDisplayPredicate(asProperty(emptyFaux),
|
||||
lowerRole(barePredicate, DISPLAY)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void restrictedQualifiedPredicate_display_byRole() {
|
||||
assertTrue(bean.canDisplayPredicate(asProperty(restrictedFaux),
|
||||
higherRole(restrictedFaux, DISPLAY)));
|
||||
assertTrue(bean.canDisplayPredicate(asProperty(restrictedFaux),
|
||||
sameRole(restrictedFaux, DISPLAY)));
|
||||
assertFalse(bean.canDisplayPredicate(asProperty(restrictedFaux),
|
||||
lowerRole(restrictedFaux, DISPLAY)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unknownQualifiedPredicate_display_true() {
|
||||
assertTrue(bean.canDisplayPredicate(asProperty(unknownFaux),
|
||||
lowestRole()));
|
||||
}
|
||||
|
||||
// ----- modify
|
||||
|
||||
@Test
|
||||
public void nullPredicate_modify_false() {
|
||||
assertFalse(bean.canModifyPredicate(null, highestRole()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void prohibitedPredicate_modify_false() {
|
||||
assertFalse(bean.canModifyPredicate(prohibitedPredicate, lowestRole()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exceptionalPredicate_modify_byRole() {
|
||||
assertTrue(bean.canModifyPredicate(exceptionalPredicate,
|
||||
higherRole(exceptionalPredicate, MODIFY)));
|
||||
assertTrue(bean.canModifyPredicate(exceptionalPredicate,
|
||||
sameRole(exceptionalPredicate, MODIFY)));
|
||||
assertFalse(bean.canModifyPredicate(exceptionalPredicate,
|
||||
lowerRole(exceptionalPredicate, MODIFY)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void barePredicate_modify_byRole() {
|
||||
assertTrue(bean.canModifyPredicate(barePredicate,
|
||||
higherRole(barePredicate, MODIFY)));
|
||||
assertTrue(bean.canModifyPredicate(barePredicate,
|
||||
sameRole(barePredicate, MODIFY)));
|
||||
assertFalse(bean.canModifyPredicate(barePredicate,
|
||||
lowerRole(barePredicate, MODIFY)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unknownBarePredicate_modify_true() {
|
||||
assertTrue(bean.canModifyPredicate(unknownPredicate, lowestRole()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyQualifiedPredicate_modify_byBareRole() {
|
||||
assertTrue(bean.canModifyPredicate(asProperty(emptyFaux),
|
||||
higherRole(barePredicate, MODIFY)));
|
||||
assertTrue(bean.canModifyPredicate(asProperty(emptyFaux),
|
||||
sameRole(barePredicate, MODIFY)));
|
||||
assertFalse(bean.canModifyPredicate(asProperty(emptyFaux),
|
||||
lowerRole(barePredicate, MODIFY)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void restrictedQualifiedPredicate_modify_byRole() {
|
||||
assertTrue(bean.canModifyPredicate(asProperty(restrictedFaux),
|
||||
higherRole(restrictedFaux, MODIFY)));
|
||||
assertTrue(bean.canModifyPredicate(asProperty(restrictedFaux),
|
||||
sameRole(restrictedFaux, MODIFY)));
|
||||
assertFalse(bean.canModifyPredicate(asProperty(restrictedFaux),
|
||||
lowerRole(restrictedFaux, MODIFY)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unknownQualifiedPredicate_modify_true() {
|
||||
assertTrue(bean.canModifyPredicate(asProperty(unknownFaux),
|
||||
lowestRole()));
|
||||
}
|
||||
|
||||
// ----- publish
|
||||
|
||||
@Test
|
||||
public void nullPredicate_publish_false() {
|
||||
assertFalse(bean.canPublishPredicate(null, highestRole()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void barePredicate_publish_byRole() {
|
||||
assertTrue(bean.canPublishPredicate(barePredicate,
|
||||
higherRole(barePredicate, PUBLISH)));
|
||||
assertTrue(bean.canPublishPredicate(barePredicate,
|
||||
sameRole(barePredicate, PUBLISH)));
|
||||
assertFalse(bean.canPublishPredicate(barePredicate,
|
||||
lowerRole(barePredicate, PUBLISH)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unknownBarePredicate_publish_true() {
|
||||
assertTrue(bean.canPublishPredicate(unknownPredicate, lowestRole()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyQualifiedPredicate_publish_byBareRole() {
|
||||
assertTrue(bean.canPublishPredicate(asProperty(emptyFaux),
|
||||
higherRole(barePredicate, PUBLISH)));
|
||||
assertTrue(bean.canPublishPredicate(asProperty(emptyFaux),
|
||||
sameRole(barePredicate, PUBLISH)));
|
||||
assertFalse(bean.canPublishPredicate(asProperty(emptyFaux),
|
||||
lowerRole(barePredicate, PUBLISH)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void restrictedQualifiedPredicate_publish_byRole() {
|
||||
assertTrue(bean.canPublishPredicate(asProperty(restrictedFaux),
|
||||
higherRole(restrictedFaux, PUBLISH)));
|
||||
assertTrue(bean.canPublishPredicate(asProperty(restrictedFaux),
|
||||
sameRole(restrictedFaux, PUBLISH)));
|
||||
assertFalse(bean.canPublishPredicate(asProperty(restrictedFaux),
|
||||
lowerRole(restrictedFaux, PUBLISH)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unknownQualifiedPredicate_publish_true() {
|
||||
assertTrue(bean.canPublishPredicate(asProperty(unknownFaux),
|
||||
lowestRole()));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// update permissions
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void updateToAllowDisplay() {
|
||||
RoleLevel desiredDisplayLevel = lowerRole(barePredicate, DISPLAY);
|
||||
|
||||
assertFalse(bean
|
||||
.canDisplayPredicate(barePredicate, desiredDisplayLevel));
|
||||
|
||||
bean.updateProperty(updatedLevels(barePredicate, desiredDisplayLevel,
|
||||
sameRole(barePredicate, MODIFY),
|
||||
sameRole(barePredicate, PUBLISH)));
|
||||
|
||||
assertTrue(bean.canDisplayPredicate(barePredicate, desiredDisplayLevel));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateToAllowModify() {
|
||||
RoleLevel desiredModifyLevel = lowerRole(barePredicate, MODIFY);
|
||||
|
||||
assertFalse(bean.canModifyPredicate(barePredicate, desiredModifyLevel));
|
||||
|
||||
bean.updateProperty(updatedLevels(barePredicate,
|
||||
sameRole(barePredicate, DISPLAY), desiredModifyLevel,
|
||||
sameRole(barePredicate, PUBLISH)));
|
||||
|
||||
assertTrue(bean.canModifyPredicate(barePredicate, desiredModifyLevel));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateToAllowPublish() {
|
||||
RoleLevel desiredPublishLevel = lowerRole(barePredicate, PUBLISH);
|
||||
|
||||
assertFalse(bean
|
||||
.canPublishPredicate(barePredicate, desiredPublishLevel));
|
||||
|
||||
bean.updateProperty(updatedLevels(barePredicate,
|
||||
sameRole(barePredicate, DISPLAY),
|
||||
sameRole(barePredicate, MODIFY), desiredPublishLevel));
|
||||
|
||||
assertTrue(bean.canPublishPredicate(barePredicate, desiredPublishLevel));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateToDisallowDisplay() {
|
||||
RoleLevel desiredDisplayLevel = sameRole(barePredicate, DISPLAY);
|
||||
|
||||
assertTrue(bean.canDisplayPredicate(barePredicate, desiredDisplayLevel));
|
||||
|
||||
bean.updateProperty(updatedLevels(barePredicate,
|
||||
higherRole(barePredicate, DISPLAY),
|
||||
sameRole(barePredicate, MODIFY),
|
||||
sameRole(barePredicate, PUBLISH)));
|
||||
|
||||
assertFalse(bean
|
||||
.canDisplayPredicate(barePredicate, desiredDisplayLevel));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateToDisallowModify() {
|
||||
RoleLevel desiredModifyLevel = sameRole(barePredicate, MODIFY);
|
||||
|
||||
assertTrue(bean.canModifyPredicate(barePredicate, desiredModifyLevel));
|
||||
|
||||
bean.updateProperty(updatedLevels(barePredicate,
|
||||
sameRole(barePredicate, DISPLAY),
|
||||
higherRole(barePredicate, MODIFY),
|
||||
sameRole(barePredicate, PUBLISH)));
|
||||
|
||||
assertFalse(bean.canModifyPredicate(barePredicate, desiredModifyLevel));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateToDisallowPublish() {
|
||||
RoleLevel desiredPublishLevel = sameRole(barePredicate, PUBLISH);
|
||||
|
||||
assertTrue(bean.canPublishPredicate(barePredicate, desiredPublishLevel));
|
||||
|
||||
bean.updateProperty(updatedLevels(barePredicate,
|
||||
sameRole(barePredicate, DISPLAY),
|
||||
sameRole(barePredicate, MODIFY),
|
||||
higherRole(barePredicate, PUBLISH)));
|
||||
|
||||
assertFalse(bean
|
||||
.canPublishPredicate(barePredicate, desiredPublishLevel));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Helper methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private RoleLevel lowestRole() {
|
||||
return RoleLevel.values()[0];
|
||||
}
|
||||
|
||||
private RoleLevel highestRole() {
|
||||
RoleLevel[] values = RoleLevel.values();
|
||||
return values[values.length - 1];
|
||||
}
|
||||
|
||||
private RoleLevel sameRole(RoleRestrictedProperty p, Which which) {
|
||||
switch (which) {
|
||||
case DISPLAY:
|
||||
return p.getHiddenFromDisplayBelowRoleLevel();
|
||||
case MODIFY:
|
||||
return p.getProhibitedFromUpdateBelowRoleLevel();
|
||||
default: // PUBLISH
|
||||
return p.getHiddenFromPublishBelowRoleLevel();
|
||||
}
|
||||
}
|
||||
|
||||
private RoleLevel lowerRole(RoleRestrictedProperty p, Which which) {
|
||||
return RoleLevel.values()[sameRole(p, which).ordinal() - 1];
|
||||
}
|
||||
|
||||
private RoleLevel higherRole(RoleRestrictedProperty p, Which which) {
|
||||
return RoleLevel.values()[sameRole(p, which).ordinal() + 1];
|
||||
}
|
||||
|
||||
private Property asProperty(FauxProperty fp) {
|
||||
Property p = new Property();
|
||||
p.setURI(fp.getBaseURI());
|
||||
p.setDomainVClassURI(fp.getDomainURI());
|
||||
p.setRangeVClassURI(fp.getRangeURI());
|
||||
return p;
|
||||
}
|
||||
|
||||
private PropertyRestrictionLevels updatedLevels(RoleRestrictedProperty p,
|
||||
RoleLevel displayLevel, RoleLevel modifyLevel,
|
||||
RoleLevel publishLevel) {
|
||||
return new PropertyRestrictionLevels(new FullPropertyKey(p),
|
||||
displayLevel, modifyLevel, publishLevel);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,331 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.auth.policy.bean;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.CURATOR;
|
||||
import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.DB_ADMIN;
|
||||
import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.EDITOR;
|
||||
import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.NOBODY;
|
||||
import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.PUBLIC;
|
||||
import static edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel.SELF;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.hp.hpl.jena.ontology.OntModel;
|
||||
import com.hp.hpl.jena.ontology.OntModelSpec;
|
||||
import com.hp.hpl.jena.rdf.model.ModelFactory;
|
||||
import com.hp.hpl.jena.rdf.model.Property;
|
||||
import com.hp.hpl.jena.rdf.model.Resource;
|
||||
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
|
||||
|
||||
/**
|
||||
* Check that the bean gets built properly, and check that the bean works
|
||||
* properly.
|
||||
*/
|
||||
public class PropertyRestrictionPolicyHelperTest extends AbstractTestClass {
|
||||
private static final Log log = LogFactory
|
||||
.getLog(PropertyRestrictionPolicyHelperTest.class);
|
||||
|
||||
private static final String PROPERTY_DISPLAY_THRESHOLD = VitroVocabulary.HIDDEN_FROM_DISPLAY_BELOW_ROLE_LEVEL_ANNOT;
|
||||
private static final String PROPERTY_MODIFY_THRESHOLD = VitroVocabulary.PROHIBITED_FROM_UPDATE_BELOW_ROLE_LEVEL_ANNOT;
|
||||
private static final String PROPERTY_PUBLISH_THRESHOLD = VitroVocabulary.HIDDEN_FROM_PUBLISH_BELOW_ROLE_LEVEL_ANNOT;
|
||||
|
||||
private static final String[] PROHIBITED_NAMESPACES = new String[] {
|
||||
VitroVocabulary.vitroURI, "" };
|
||||
|
||||
private static final String[] PERMITTED_EXCEPTIONS = new String[] { VitroVocabulary.MONIKER };
|
||||
|
||||
private OntModel ontModel;
|
||||
private ModelWrapper wrapper;
|
||||
private PropertyRestrictionPolicyHelper bean;
|
||||
|
||||
@Before
|
||||
public void setLoggingLevel() {
|
||||
// setLoggerLevel(PropertyRestrictionPolicyHelper.class, Level.DEBUG);
|
||||
}
|
||||
|
||||
private FullPropertyKey key(String predicateURI) {
|
||||
return new FullPropertyKey(predicateURI);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void createTheBean() {
|
||||
Map<FullPropertyKey, RoleLevel> displayLevels = new HashMap<>();
|
||||
displayLevels.put(key("http://predicates#display_curator"), CURATOR);
|
||||
displayLevels.put(key("http://predicates#display_hidden"), NOBODY);
|
||||
|
||||
Map<FullPropertyKey, RoleLevel> modifyLevels = new HashMap<>();
|
||||
modifyLevels.put(key("http://predicates#modify_self"), SELF);
|
||||
modifyLevels.put(key("http://predicates#modify_curator"), CURATOR);
|
||||
modifyLevels.put(key("http://predicates#modify_hidden"), NOBODY);
|
||||
|
||||
Map<FullPropertyKey, RoleLevel> publishLevels = new HashMap<>();
|
||||
publishLevels.put(key("http://predicates#publish_curator"), CURATOR);
|
||||
publishLevels.put(key("http://predicates#publish_hidden"), NOBODY);
|
||||
|
||||
bean = new PropertyRestrictionPolicyHelper(
|
||||
Arrays.asList(PROHIBITED_NAMESPACES),
|
||||
Arrays.asList(PERMITTED_EXCEPTIONS), displayLevels,
|
||||
modifyLevels, publishLevels);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void createTheModel() {
|
||||
ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_DL_MEM);
|
||||
|
||||
wrapper = new ModelWrapper(ontModel);
|
||||
|
||||
wrapper.add("http://thresholds#display_public",
|
||||
PROPERTY_DISPLAY_THRESHOLD, PUBLIC.getURI());
|
||||
wrapper.add("http://thresholds#display_hidden",
|
||||
PROPERTY_DISPLAY_THRESHOLD, NOBODY.getURI());
|
||||
|
||||
wrapper.add("http://thresholds#modify_editor",
|
||||
PROPERTY_MODIFY_THRESHOLD, EDITOR.getURI());
|
||||
wrapper.add("http://thresholds#modify_curator",
|
||||
PROPERTY_MODIFY_THRESHOLD, CURATOR.getURI());
|
||||
|
||||
wrapper.add("http://thresholds#publish_public",
|
||||
PROPERTY_PUBLISH_THRESHOLD, PUBLIC.getURI());
|
||||
wrapper.add("http://thresholds#publish_hidden",
|
||||
PROPERTY_PUBLISH_THRESHOLD, NOBODY.getURI());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// test the bean
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void displayResource() {
|
||||
assertEquals("display a random resource", true,
|
||||
bean.canDisplayResource("http://someRandom#string", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyResourceNoRestriction() {
|
||||
assertEquals("modify a random resource", true,
|
||||
bean.canModifyResource("http://someRandom#string", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyResourceProhibitedNamespace() {
|
||||
assertEquals("modify a prohibited resource", false,
|
||||
bean.canModifyResource(PROHIBITED_NAMESPACES[0] + "random",
|
||||
null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void publishResource() {
|
||||
assertEquals("publish a random resource", true,
|
||||
bean.canPublishResource("http://someRandom#string", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyResourcePermittedException() {
|
||||
assertEquals("modify a exception resource", true,
|
||||
bean.canModifyResource(PERMITTED_EXCEPTIONS[0], null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPredicateNoRestriction() {
|
||||
assertEquals("displayPredicate: open", true, bean.canDisplayPredicate(
|
||||
createVitroProperty("http://predicates#open"), PUBLIC));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPredicateRestrictionLower() {
|
||||
assertEquals("displayPredicate: lower restriction", true,
|
||||
bean.canDisplayPredicate(
|
||||
createVitroProperty("http://predicates#display_self"),
|
||||
CURATOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPredicateRestrictionEqual() {
|
||||
assertEquals(
|
||||
"displayPredicate: equal restriction",
|
||||
true,
|
||||
bean.canDisplayPredicate(
|
||||
createVitroProperty("http://predicates#display_curator"),
|
||||
CURATOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPredicateRestrictionHigher() {
|
||||
assertEquals(
|
||||
"displayPredicate: higher restriction",
|
||||
false,
|
||||
bean.canDisplayPredicate(
|
||||
createVitroProperty("http://predicates#display_hidden"),
|
||||
CURATOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyPredicateNoRestriction() {
|
||||
assertEquals("modifyPredicate: open", true, bean.canModifyPredicate(
|
||||
new edu.cornell.mannlib.vitro.webapp.beans.Property(
|
||||
"http://predicates#open"), PUBLIC));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyPredicateRestrictionLower() {
|
||||
assertEquals("modifyPredicate: lower restriction", true,
|
||||
bean.canModifyPredicate(
|
||||
new edu.cornell.mannlib.vitro.webapp.beans.Property(
|
||||
"http://predicates#modify_self"), CURATOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyPredicateRestrictionEqual() {
|
||||
assertEquals("modifyPredicate: equal restriction", true,
|
||||
bean.canModifyPredicate(
|
||||
new edu.cornell.mannlib.vitro.webapp.beans.Property(
|
||||
"http://predicates#modify_curator"), CURATOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyPredicateRestrictionHigher() {
|
||||
assertEquals("modifyPredicate: higher restriction", false,
|
||||
bean.canModifyPredicate(
|
||||
new edu.cornell.mannlib.vitro.webapp.beans.Property(
|
||||
"http://predicates#modify_hidden"), CURATOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyPredicateProhibitedNamespace() {
|
||||
assertEquals(
|
||||
"modifyPredicate: prohibited namespace",
|
||||
false,
|
||||
bean.canModifyPredicate(
|
||||
new edu.cornell.mannlib.vitro.webapp.beans.Property(
|
||||
PROHIBITED_NAMESPACES[0] + "randoom"), DB_ADMIN));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyPredicatePermittedException() {
|
||||
assertEquals("modifyPredicate: permitted exception", true,
|
||||
bean.canModifyPredicate(
|
||||
new edu.cornell.mannlib.vitro.webapp.beans.Property(
|
||||
PERMITTED_EXCEPTIONS[0]), DB_ADMIN));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void publishPredicateNoRestriction() {
|
||||
assertEquals("publishPredicate: open", true, bean.canPublishPredicate(
|
||||
createVitroProperty("http://predicates#open"), PUBLIC));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void publishPredicateRestrictionLower() {
|
||||
assertEquals("publishPredicate: lower restriction", true,
|
||||
bean.canPublishPredicate(
|
||||
createVitroProperty("http://predicates#publish_self"),
|
||||
CURATOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void publishPredicateRestrictionEqual() {
|
||||
assertEquals(
|
||||
"publishPredicate: equal restriction",
|
||||
true,
|
||||
bean.canPublishPredicate(
|
||||
createVitroProperty("http://predicates#publish_curator"),
|
||||
CURATOR));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void publishPredicateRestrictionHigher() {
|
||||
assertEquals(
|
||||
"publishPredicate: higher restriction",
|
||||
false,
|
||||
bean.canPublishPredicate(
|
||||
createVitroProperty("http://predicates#publish_hidden"),
|
||||
CURATOR));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// test the bean builder
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void buildDisplayThresholds() {
|
||||
Map<FullPropertyKey, BaseResourceBean.RoleLevel> expectedMap = new HashMap<>();
|
||||
expectedMap.put(key("http://thresholds#display_public"), PUBLIC);
|
||||
expectedMap.put(key("http://thresholds#display_hidden"), NOBODY);
|
||||
|
||||
Map<String, RoleLevel> actualMap = populateThresholdMap(PROPERTY_DISPLAY_THRESHOLD);
|
||||
assertEquals("display thresholds", expectedMap, actualMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildModifyThresholds() {
|
||||
Map<FullPropertyKey, BaseResourceBean.RoleLevel> expectedMap = new HashMap<>();
|
||||
expectedMap.put(key("http://thresholds#modify_editor"), EDITOR);
|
||||
expectedMap.put(key("http://thresholds#modify_curator"), CURATOR);
|
||||
|
||||
Map<String, RoleLevel> actualMap = populateThresholdMap(PROPERTY_MODIFY_THRESHOLD);
|
||||
assertEquals("modify thresholds", expectedMap, actualMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildPublishThresholds() {
|
||||
Map<FullPropertyKey, BaseResourceBean.RoleLevel> expectedMap = new HashMap<>();
|
||||
expectedMap.put(key("http://thresholds#publish_public"), PUBLIC);
|
||||
expectedMap.put(key("http://thresholds#publish_hidden"), NOBODY);
|
||||
|
||||
Map<String, RoleLevel> actualMap = populateThresholdMap(PROPERTY_PUBLISH_THRESHOLD);
|
||||
assertEquals("publish thresholds", expectedMap, actualMap);
|
||||
}
|
||||
|
||||
/** Invoke the private static method "populateThresholdMap" */
|
||||
private Map<String, RoleLevel> populateThresholdMap(String propertyUri) {
|
||||
Map<String, RoleLevel> map = new HashMap<String, BaseResourceBean.RoleLevel>();
|
||||
try {
|
||||
Class<?> clazz = PropertyRestrictionPolicyHelper.class;
|
||||
Method method = clazz.getDeclaredMethod("populateThresholdMap",
|
||||
OntModel.class, Map.class, String.class);
|
||||
method.setAccessible(true);
|
||||
method.invoke(null, ontModel, map, propertyUri);
|
||||
return map;
|
||||
} catch (Exception e) {
|
||||
fail("failed to populate the map: propertyUri='" + propertyUri
|
||||
+ "', " + e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ModelWrapper {
|
||||
private final OntModel model;
|
||||
|
||||
public ModelWrapper(OntModel model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public void add(String subjectUri, String propertyUri, String objectUri) {
|
||||
Resource subject = model.getResource(subjectUri);
|
||||
Property property = model.getProperty(propertyUri);
|
||||
Resource object = model.getResource(objectUri);
|
||||
model.add(subject, property, object);
|
||||
}
|
||||
}
|
||||
|
||||
private edu.cornell.mannlib.vitro.webapp.beans.Property createVitroProperty(
|
||||
String propertyURI) {
|
||||
return new edu.cornell.mannlib.vitro.webapp.beans.Property(propertyURI);
|
||||
}
|
||||
}
|
|
@ -2,11 +2,19 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -25,6 +33,20 @@ import edu.cornell.mannlib.vitro.webapp.utils.http.NotAcceptableException;
|
|||
* formats.
|
||||
*/
|
||||
public class SparqlQueryApiExecutorTest extends AbstractTestClass {
|
||||
|
||||
/* SPARQL response types */
|
||||
private static final String ACCEPT_TEXT = "text/plain";
|
||||
private static final String ACCEPT_CSV = "text/csv";
|
||||
private static final String ACCEPT_TSV = "text/tab-separated-values";
|
||||
private static final String ACCEPT_SPARQL_XML = "application/sparql-results+xml";
|
||||
private static final String ACCEPT_SPARQL_JSON = "application/sparql-results+json";
|
||||
|
||||
/* RDF result types */
|
||||
private static final String ACCEPT_RDFXML = "application/rdf+xml";
|
||||
private static final String ACCEPT_N3 = "text/n3";
|
||||
private static final String ACCEPT_TURTLE = "text/turtle";
|
||||
private static final String ACCEPT_JSON = "application/json";
|
||||
|
||||
private static final String MODEL_CONTENTS_N3 = "" //
|
||||
+ "<http://here.edu/subject> \n"
|
||||
+ " <http://here.edu/predicate> <http://here.edu/object> ."
|
||||
|
@ -201,24 +223,24 @@ public class SparqlQueryApiExecutorTest extends AbstractTestClass {
|
|||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void nullRdfService() throws Exception {
|
||||
SparqlQueryApiExecutor.instance(null, SELECT_ALL_QUERY, "text/plain");
|
||||
SparqlQueryApiExecutor.instance(null, SELECT_ALL_QUERY, ACCEPT_TEXT);
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void nullQuery() throws Exception {
|
||||
SparqlQueryApiExecutor.instance(rdfService, null, "text/plain");
|
||||
SparqlQueryApiExecutor.instance(rdfService, null, ACCEPT_TEXT);
|
||||
fail("nullQuery not implemented");
|
||||
}
|
||||
|
||||
@Test(expected = QueryParseException.class)
|
||||
public void emptyQuery() throws Exception {
|
||||
SparqlQueryApiExecutor.instance(rdfService, "", "text/plain");
|
||||
SparqlQueryApiExecutor.instance(rdfService, "", ACCEPT_TEXT);
|
||||
fail("emptyQuery not implemented");
|
||||
}
|
||||
|
||||
@Test(expected = QueryParseException.class)
|
||||
public void cantParseQuery() throws Exception {
|
||||
SparqlQueryApiExecutor.instance(rdfService, "BOGUS", "text/plain");
|
||||
SparqlQueryApiExecutor.instance(rdfService, "BOGUS", ACCEPT_TEXT);
|
||||
fail("cantParseQuery not implemented");
|
||||
}
|
||||
|
||||
|
@ -237,179 +259,177 @@ public class SparqlQueryApiExecutorTest extends AbstractTestClass {
|
|||
|
||||
@Test
|
||||
public void selectToText() throws Exception {
|
||||
executeQuery("select to text", SELECT_ALL_QUERY, "text/plain",
|
||||
executeQuery("select to text", SELECT_ALL_QUERY, ACCEPT_TEXT,
|
||||
SELECT_RESULT_TEXT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selectToCsv() throws Exception {
|
||||
executeQuery("select to csv", SELECT_ALL_QUERY, "text/csv",
|
||||
executeQuery("select to csv", SELECT_ALL_QUERY, ACCEPT_CSV,
|
||||
SELECT_RESULT_CSV);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selectToTsv() throws Exception {
|
||||
executeQuery("select to tsv", SELECT_ALL_QUERY,
|
||||
"text/tab-separated-values", SELECT_RESULT_TSV);
|
||||
executeQuery("select to tsv", SELECT_ALL_QUERY, ACCEPT_TSV,
|
||||
SELECT_RESULT_TSV);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selectToXml() throws Exception {
|
||||
executeQuery("select to xml", SELECT_ALL_QUERY,
|
||||
"application/sparql-results+xml", SELECT_RESULT_XML);
|
||||
executeQuery("select to xml", SELECT_ALL_QUERY, ACCEPT_SPARQL_XML,
|
||||
SELECT_RESULT_XML);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selectToJson() throws Exception {
|
||||
executeQuery("select to json", SELECT_ALL_QUERY,
|
||||
"application/sparql-results+json", SELECT_RESULT_JSON);
|
||||
executeQuery("select to json", SELECT_ALL_QUERY, ACCEPT_SPARQL_JSON,
|
||||
SELECT_RESULT_JSON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void selectWithInvalidContentType() throws Exception {
|
||||
executeWithInvalidAcceptHeader("select with application/rdf+xml",
|
||||
SELECT_ALL_QUERY, "application/rdf+xml");
|
||||
SELECT_ALL_QUERY, ACCEPT_RDFXML);
|
||||
executeWithInvalidAcceptHeader("select with text/n3", SELECT_ALL_QUERY,
|
||||
"text/n3");
|
||||
ACCEPT_N3);
|
||||
executeWithInvalidAcceptHeader("select with text/turtle",
|
||||
SELECT_ALL_QUERY, "text/turtle");
|
||||
SELECT_ALL_QUERY, ACCEPT_TURTLE);
|
||||
executeWithInvalidAcceptHeader("select with application/json",
|
||||
SELECT_ALL_QUERY, "application/json");
|
||||
SELECT_ALL_QUERY, ACCEPT_JSON);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void askToText() throws Exception {
|
||||
executeQuery("ask to text", ASK_ALL_QUERY, "text/plain",
|
||||
ASK_RESULT_TEXT);
|
||||
executeQuery("ask to text", ASK_ALL_QUERY, ACCEPT_TEXT, ASK_RESULT_TEXT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void askToCsv() throws Exception {
|
||||
executeQuery("ask to csv", ASK_ALL_QUERY, "text/csv", ASK_RESULT_CSV);
|
||||
executeQuery("ask to csv", ASK_ALL_QUERY, ACCEPT_CSV, ASK_RESULT_CSV);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void askToTsv() throws Exception {
|
||||
executeQuery("ask to tsv", ASK_ALL_QUERY, "text/tab-separated-values",
|
||||
ASK_RESULT_TSV);
|
||||
executeQuery("ask to tsv", ASK_ALL_QUERY, ACCEPT_TSV, ASK_RESULT_TSV);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void askToXml() throws Exception {
|
||||
executeQuery("ask to xml", ASK_ALL_QUERY,
|
||||
"application/sparql-results+xml", ASK_RESULT_XML);
|
||||
executeQuery("ask to xml", ASK_ALL_QUERY, ACCEPT_SPARQL_XML,
|
||||
ASK_RESULT_XML);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void askToJson() throws Exception {
|
||||
executeQuery("ask to json", ASK_ALL_QUERY,
|
||||
"application/sparql-results+json", ASK_RESULT_JSON);
|
||||
executeQuery("ask to json", ASK_ALL_QUERY, ACCEPT_SPARQL_JSON,
|
||||
ASK_RESULT_JSON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void askWithInvalidAcceptHeader() throws Exception {
|
||||
executeWithInvalidAcceptHeader("ask with application/rdf+xml",
|
||||
ASK_ALL_QUERY, "application/rdf+xml");
|
||||
ASK_ALL_QUERY, ACCEPT_RDFXML);
|
||||
executeWithInvalidAcceptHeader("ask with text/n3", ASK_ALL_QUERY,
|
||||
"text/n3");
|
||||
ACCEPT_N3);
|
||||
executeWithInvalidAcceptHeader("ask with text/turtle", ASK_ALL_QUERY,
|
||||
"text/turtle");
|
||||
ACCEPT_TURTLE);
|
||||
executeWithInvalidAcceptHeader("ask with application/json",
|
||||
ASK_ALL_QUERY, "application/json");
|
||||
ASK_ALL_QUERY, ACCEPT_JSON);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void constructToText() throws Exception {
|
||||
executeQuery("construct to text", CONSTRUCT_ALL_QUERY, "text/plain",
|
||||
executeQuery("construct to text", CONSTRUCT_ALL_QUERY, ACCEPT_TEXT,
|
||||
CONSTRUCT_RESULT_TEXT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructToRdfXml() throws Exception {
|
||||
executeQuery("construct to rdf/xml", CONSTRUCT_ALL_QUERY,
|
||||
"application/rdf+xml", CONSTRUCT_RESULT_RDFXML);
|
||||
ACCEPT_RDFXML, CONSTRUCT_RESULT_RDFXML);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructToN3() throws Exception {
|
||||
executeQuery("construct to n3", CONSTRUCT_ALL_QUERY, "text/n3",
|
||||
executeQuery("construct to n3", CONSTRUCT_ALL_QUERY, ACCEPT_N3,
|
||||
CONSTRUCT_RESULT_N3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructToTurtle() throws Exception {
|
||||
executeQuery("construct to turtle", CONSTRUCT_ALL_QUERY, "text/turtle",
|
||||
executeQuery("construct to turtle", CONSTRUCT_ALL_QUERY, ACCEPT_TURTLE,
|
||||
CONSTRUCT_RESULT_TURTLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructToJsonld() throws Exception {
|
||||
executeQuery("construct to JSON-LD", CONSTRUCT_ALL_QUERY,
|
||||
"application/json", CONSTRUCT_RESULT_JSONLD);
|
||||
executeQuery("construct to JSON-LD", CONSTRUCT_ALL_QUERY, ACCEPT_JSON,
|
||||
CONSTRUCT_RESULT_JSONLD);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructWithInvalidAcceptHeader() throws Exception {
|
||||
executeWithInvalidAcceptHeader("construct with text/csv",
|
||||
CONSTRUCT_ALL_QUERY, "text/csv");
|
||||
CONSTRUCT_ALL_QUERY, ACCEPT_CSV);
|
||||
executeWithInvalidAcceptHeader("construct with text/tsv",
|
||||
CONSTRUCT_ALL_QUERY, "text/tsv");
|
||||
executeWithInvalidAcceptHeader(
|
||||
"construct with application/sparql-results+xml",
|
||||
CONSTRUCT_ALL_QUERY, "application/sparql-results+xml");
|
||||
CONSTRUCT_ALL_QUERY, ACCEPT_SPARQL_XML);
|
||||
executeWithInvalidAcceptHeader(
|
||||
"construct with application/sparql-results+json",
|
||||
CONSTRUCT_ALL_QUERY, "application/sparql-results+json");
|
||||
CONSTRUCT_ALL_QUERY, ACCEPT_SPARQL_JSON);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void describeToText() throws Exception {
|
||||
executeQuery("describe to text", DESCRIBE_ALL_QUERY, "text/plain",
|
||||
executeQuery("describe to text", DESCRIBE_ALL_QUERY, ACCEPT_TEXT,
|
||||
DESCRIBE_RESULT_TEXT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void describeToRdfXml() throws Exception {
|
||||
executeQuery("describe to rdf/xml", DESCRIBE_ALL_QUERY,
|
||||
"application/rdf+xml", DESCRIBE_RESULT_RDFXML);
|
||||
executeQuery("describe to rdf/xml", DESCRIBE_ALL_QUERY, ACCEPT_RDFXML,
|
||||
DESCRIBE_RESULT_RDFXML);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void describeToN3() throws Exception {
|
||||
executeQuery("describe to n3", DESCRIBE_ALL_QUERY, "text/n3",
|
||||
executeQuery("describe to n3", DESCRIBE_ALL_QUERY, ACCEPT_N3,
|
||||
DESCRIBE_RESULT_N3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void describeToTurtle() throws Exception {
|
||||
executeQuery("describe to turtle", DESCRIBE_ALL_QUERY, "text/turtle",
|
||||
executeQuery("describe to turtle", DESCRIBE_ALL_QUERY, ACCEPT_TURTLE,
|
||||
DESCRIBE_RESULT_TURTLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void describeToJsonld() throws Exception {
|
||||
executeQuery("describe to JSON-LD", DESCRIBE_ALL_QUERY,
|
||||
"application/json", DESCRIBE_RESULT_JSONLD);
|
||||
executeQuery("describe to JSON-LD", DESCRIBE_ALL_QUERY, ACCEPT_JSON,
|
||||
DESCRIBE_RESULT_JSONLD);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void describeWithInvalidAcceptHeader() throws Exception {
|
||||
executeWithInvalidAcceptHeader("describe with text/csv",
|
||||
DESCRIBE_ALL_QUERY, "text/csv");
|
||||
DESCRIBE_ALL_QUERY, ACCEPT_CSV);
|
||||
executeWithInvalidAcceptHeader("describe with text/tsv",
|
||||
DESCRIBE_ALL_QUERY, "text/tsv");
|
||||
executeWithInvalidAcceptHeader(
|
||||
"describe with application/sparql-results+xml",
|
||||
DESCRIBE_ALL_QUERY, "application/sparql-results+xml");
|
||||
DESCRIBE_ALL_QUERY, ACCEPT_SPARQL_XML);
|
||||
executeWithInvalidAcceptHeader(
|
||||
"describe with application/sparql-results+json",
|
||||
DESCRIBE_ALL_QUERY, "application/sparql-results+json");
|
||||
DESCRIBE_ALL_QUERY, ACCEPT_SPARQL_JSON);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
@ -424,7 +444,87 @@ public class SparqlQueryApiExecutorTest extends AbstractTestClass {
|
|||
rdfService, queryString, acceptHeader);
|
||||
executor.executeAndFormat(out);
|
||||
|
||||
assertEquals(message, expected.replaceAll("\\s+", " "), out.toString().replaceAll("\\s+", " "));
|
||||
if (ACCEPT_RDFXML.equals(acceptHeader)) {
|
||||
assertEquivalentRdfxml(message, expected, out.toString());
|
||||
} else if (ACCEPT_TURTLE.equals(acceptHeader)) {
|
||||
assertEquivalentTurtle(message, expected, out.toString());
|
||||
} else if (ACCEPT_N3.equals(acceptHeader)) {
|
||||
assertEquivalentN3(message, expected, out.toString());
|
||||
} else {
|
||||
assertEqualsIgnoreWhiteSpace(message, expected, out.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* RDF/XML namespaces may come in any order, so separate them out and test
|
||||
* accordingly.
|
||||
*/
|
||||
private void assertEquivalentRdfxml(String message, String expected,
|
||||
String actual) {
|
||||
assertEquals(message, getRdfxmlNamespaces(expected),
|
||||
getRdfxmlNamespaces(actual));
|
||||
assertEqualsIgnoreWhiteSpace(message, omitRdfxmlNamespaces(expected),
|
||||
omitRdfxmlNamespaces(actual));
|
||||
}
|
||||
|
||||
private Set<String> getRdfxmlNamespaces(String rdfxml) {
|
||||
Set<String> namespaces = new TreeSet<>();
|
||||
Pattern p = Pattern.compile("xmlns:\\w+=\\\"[^\\\"]*\\\"");
|
||||
Matcher m = p.matcher(rdfxml);
|
||||
while (m.find()) {
|
||||
namespaces.add(m.group());
|
||||
}
|
||||
return namespaces;
|
||||
}
|
||||
|
||||
private String omitRdfxmlNamespaces(String rdfxml) {
|
||||
return rdfxml.replaceAll("xmlns:\\w+=\\\"[^\\\"]*\\\"", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* TTL prefix lines may come in any order, so separate them out and test
|
||||
* accordingly.
|
||||
*/
|
||||
private void assertEquivalentTurtle(String message, String expected,
|
||||
String actual) {
|
||||
assertEquals(message, getTurtlePrefixes(expected),
|
||||
getTurtlePrefixes(actual));
|
||||
assertEqualsIgnoreWhiteSpace(message, getTurtleRemainder(expected),
|
||||
getTurtleRemainder(actual));
|
||||
}
|
||||
|
||||
/**
|
||||
* N3 is like TTL, as far as prefix lines are concerned.
|
||||
*/
|
||||
private void assertEquivalentN3(String message, String expected,
|
||||
String actual) {
|
||||
assertEquivalentTurtle(message, expected, actual);
|
||||
}
|
||||
|
||||
private Set<String> getTurtlePrefixes(String ttl) {
|
||||
Set<String> prefixes = new TreeSet<>();
|
||||
for (String line : ttl.split("[\\n\\r]+")) {
|
||||
if (line.startsWith("@prefix")) {
|
||||
prefixes.add(line.replaceAll("\\s+", " "));
|
||||
}
|
||||
}
|
||||
return prefixes;
|
||||
}
|
||||
|
||||
private String getTurtleRemainder(String ttl) {
|
||||
List<String> remainder = new ArrayList<>();
|
||||
for (String line : ttl.split("[\\n\\r]+")) {
|
||||
if (!line.startsWith("@prefix")) {
|
||||
remainder.add(line);
|
||||
}
|
||||
}
|
||||
return StringUtils.join(remainder, "\n");
|
||||
}
|
||||
|
||||
private void assertEqualsIgnoreWhiteSpace(String message, String expected,
|
||||
String actual) {
|
||||
assertEquals(message, expected.replaceAll("\\s+", " "),
|
||||
actual.replaceAll("\\s+", " "));
|
||||
}
|
||||
|
||||
private void executeWithInvalidAcceptHeader(String message,
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package edu.cornell.mannlib.vitro.webapp.utils;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static edu.cornell.mannlib.vitro.webapp.utils.SparqlQueryRunner.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
|
||||
/**
|
||||
* For now, just test the methods that manipulate the query string.
|
||||
*/
|
||||
public class SparqlQueryRunnerTest extends AbstractTestClass {
|
||||
@Test
|
||||
public void bindValuesNameNotFound() {
|
||||
String raw = "No such name here";
|
||||
String expected = raw;
|
||||
assertEquals(expected, bindValues(raw, uriValue("bogus", "BOGUS")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindOneUri() {
|
||||
String raw = "Replace both ?this and ?this also.";
|
||||
String expected = "Replace both <URI> and <URI> also.";
|
||||
assertEquals(expected, bindValues(raw, uriValue("this", "URI")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindTwoUris() {
|
||||
String raw = "Replace both ?this and ?that also.";
|
||||
String expected = "Replace both <URI> and <ANOTHER> also.";
|
||||
assertEquals(
|
||||
expected,
|
||||
bindValues(raw, uriValue("this", "URI"),
|
||||
uriValue("that", "ANOTHER")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void honorWordBoundary() {
|
||||
String raw = "Replace ?this but not ?thistle.";
|
||||
String expected = "Replace <URI> but not ?thistle.";
|
||||
assertEquals(expected, bindValues(raw, uriValue("this", "URI")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void honorStringLimit() {
|
||||
String raw = "?this";
|
||||
String expected = "<URI>";
|
||||
assertEquals(expected, bindValues(raw, uriValue("this", "URI")));
|
||||
}
|
||||
|
||||
private static final String REAL_WORLD_RAW = "" //
|
||||
+ "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" //
|
||||
+ " :qualifiedByDomain ?domainUri ; \n" //
|
||||
+ " :qualifiedBy ?rangeUri ; \n" //
|
||||
+ " :hasConfiguration ?config . \n" //
|
||||
+ "} \n"; //
|
||||
|
||||
private static final String REAL_WORLD_EXPECTED = "" //
|
||||
+ "PREFIX : <http://vitro.mannlib.cornell.edu/ns/vitro/ApplicationConfiguration#> \n" //
|
||||
+ "\n" //
|
||||
+ "SELECT DISTINCT ?context ?config \n" //
|
||||
+ "WHERE { \n" //
|
||||
+ " ?context a :ConfigContext ; \n" //
|
||||
+ " :configContextFor <http://vivoweb.org/ontology/core#relates> ; \n" //
|
||||
+ " :qualifiedByDomain <http://vivoweb.org/ontology/core#Contract> ; \n" //
|
||||
+ " :qualifiedBy <http://vivoweb.org/ontology/core#ResearcherRole> ; \n" //
|
||||
+ " :hasConfiguration ?config . \n" //
|
||||
+ "} \n"; //
|
||||
|
||||
@Test
|
||||
public void realWorldExample() {
|
||||
assertEquals(
|
||||
REAL_WORLD_EXPECTED,
|
||||
bindValues(
|
||||
REAL_WORLD_RAW,
|
||||
uriValue("baseUri",
|
||||
"http://vivoweb.org/ontology/core#relates"),
|
||||
uriValue("domainUri",
|
||||
"http://vivoweb.org/ontology/core#Contract"),
|
||||
uriValue("rangeUri",
|
||||
"http://vivoweb.org/ontology/core#ResearcherRole")));
|
||||
}
|
||||
|
||||
}
|
|
@ -970,7 +970,7 @@ public class ConfigurationBeanLoaderTest extends AbstractTestClass {
|
|||
// Nothing.
|
||||
}
|
||||
|
||||
public class AGoodApple implements OneBadAppleSpoilsTheBunch {
|
||||
public static class AGoodApple implements OneBadAppleSpoilsTheBunch {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
|
|
|
@ -10,10 +10,10 @@ import java.io.StringReader;
|
|||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.matchers.JUnitMatchers;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||
|
@ -71,7 +71,7 @@ public class CustomListViewConfigFileTest extends AbstractTestClass {
|
|||
@Test
|
||||
public void invalidXml() throws InvalidConfigurationException {
|
||||
suppressSyserr(); // catch the error report from the XML parser
|
||||
expectException(JUnitMatchers
|
||||
expectException(CoreMatchers
|
||||
.containsString("Config file is not valid XML:"));
|
||||
readConfigFile("<unbalancedTag>");
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
package edu.cornell.mannlib.vitro.webapp.web.templatemodels.individual;
|
||||
|
||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.PolicyOption.POLICY_NEUTRAL;
|
||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption.ASSERTIONS_AND_INFERENCES;
|
||||
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames.FULL_UNION;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -27,6 +28,7 @@ import org.junit.Rule;
|
|||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDaoStub;
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDaoStub;
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactoryStub;
|
||||
import stubs.edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccessFactoryStub;
|
||||
|
@ -60,6 +62,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
|||
|
||||
private WebappDaoFactoryStub wadf;
|
||||
private ObjectPropertyDaoStub opDao;
|
||||
private FauxPropertyDaoStub fpDao;
|
||||
|
||||
private ServletContextStub ctx;
|
||||
private HttpSessionStub session;
|
||||
|
@ -117,8 +120,10 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
|||
logMessages = new StringWriter();
|
||||
|
||||
opDao = new ObjectPropertyDaoStub();
|
||||
fpDao = new FauxPropertyDaoStub();
|
||||
wadf = new WebappDaoFactoryStub();
|
||||
wadf.setObjectPropertyDao(opDao);
|
||||
wadf.setFauxPropertyDao(fpDao);
|
||||
|
||||
ctx = new ServletContextStub();
|
||||
// create paths for all of the files in the temporary config directory.
|
||||
|
@ -136,6 +141,7 @@ public class ObjectPropertyTemplateModel_PropertyListConfigTest extends
|
|||
|
||||
mafs = new ModelAccessFactoryStub();
|
||||
mafs.get(vreq).setWebappDaoFactory(wadf, ASSERTIONS_AND_INFERENCES);
|
||||
mafs.get(vreq).setWebappDaoFactory(wadf, POLICY_NEUTRAL);
|
||||
|
||||
subject = new IndividualImpl();
|
||||
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package stubs.edu.cornell.mannlib.vitro.webapp.auth.policy.bean;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.hp.hpl.jena.rdf.model.impl.Util;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean;
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.Property;
|
||||
|
||||
/**
|
||||
* Allow the unit test to specify a variety of restrictions
|
||||
*/
|
||||
public class PropertyRestrictionBeanStub extends PropertyRestrictionBean {
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Stub infrastructure
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
/** Don't prohibit or restrict anything. */
|
||||
public static PropertyRestrictionBean getInstance() {
|
||||
return getInstance(null, null);
|
||||
}
|
||||
|
||||
/** Prohibit some namespaces. */
|
||||
public static PropertyRestrictionBeanStub getInstance(
|
||||
String[] restrictedNamespaces) {
|
||||
return getInstance(restrictedNamespaces, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prohibit some namespaces and restrict some properties from modification
|
||||
* by anybody. They may still be displayed or published.
|
||||
*
|
||||
* We can implement more granular control if we need it.
|
||||
*/
|
||||
public static PropertyRestrictionBeanStub getInstance(
|
||||
String[] restrictedNamespaces, String[] restrictedProperties) {
|
||||
PropertyRestrictionBeanStub stub = new PropertyRestrictionBeanStub(
|
||||
restrictedNamespaces, restrictedProperties);
|
||||
PropertyRestrictionBean.instance = stub;
|
||||
return stub;
|
||||
}
|
||||
|
||||
private final Set<String> restrictedNamespaces;
|
||||
private final Set<String> restrictedProperties;
|
||||
|
||||
private PropertyRestrictionBeanStub(String[] restrictedNamespaces,
|
||||
String[] restrictedProperties) {
|
||||
this.restrictedNamespaces = (restrictedNamespaces == null) ? Collections
|
||||
.<String> emptySet() : new HashSet<>(
|
||||
Arrays.asList(restrictedNamespaces));
|
||||
this.restrictedProperties = (restrictedProperties == null) ? Collections
|
||||
.<String> emptySet() : new HashSet<>(
|
||||
Arrays.asList(restrictedProperties));
|
||||
}
|
||||
|
||||
private boolean isPermittedNamespace(String uri) {
|
||||
return !restrictedNamespaces.contains(namespace(uri));
|
||||
}
|
||||
|
||||
private String namespace(String uri) {
|
||||
return uri.substring(0, Util.splitNamespace(uri));
|
||||
}
|
||||
|
||||
private boolean isPermittedProperty(String uri) {
|
||||
return !restrictedProperties.contains(uri);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Stub methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public boolean canDisplayResource(String resourceUri, RoleLevel userRole) {
|
||||
return isPermittedNamespace(resourceUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canModifyResource(String resourceUri, RoleLevel userRole) {
|
||||
return isPermittedNamespace(resourceUri)
|
||||
&& isPermittedProperty(resourceUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPublishResource(String resourceUri, RoleLevel userRole) {
|
||||
return isPermittedNamespace(resourceUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDisplayPredicate(Property predicate, RoleLevel userRole) {
|
||||
return isPermittedNamespace(predicate.getURI());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canModifyPredicate(Property predicate, RoleLevel userRole) {
|
||||
return isPermittedNamespace(predicate.getURI())
|
||||
&& isPermittedProperty(predicate.getURI());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPublishPredicate(Property predicate, RoleLevel userRole) {
|
||||
return isPermittedNamespace(predicate.getURI());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Un-implemented methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public void updateProperty(PropertyRestrictionLevels levels) {
|
||||
throw new RuntimeException(
|
||||
"PropertyRestrictionBeanStub.updateProperty() not implemented.");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package stubs.edu.cornell.mannlib.vitro.webapp.auth.policy.bean;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper;
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey;
|
||||
|
||||
/**
|
||||
* Allow the unit test to specify a variety of restrictions
|
||||
*/
|
||||
public class PropertyRestrictionPolicyHelperStub extends
|
||||
PropertyRestrictionPolicyHelper {
|
||||
|
||||
/** Don't prohibit or restrict anything. */
|
||||
public static PropertyRestrictionPolicyHelper getInstance() {
|
||||
return getInstance(null, null);
|
||||
}
|
||||
|
||||
/** Prohibit some namespaces. */
|
||||
public static PropertyRestrictionPolicyHelperStub getInstance(
|
||||
String[] restrictedNamespaces) {
|
||||
return getInstance(restrictedNamespaces, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prohibit some namespaces and restrict some properties from modification
|
||||
* by anybody.
|
||||
*/
|
||||
public static PropertyRestrictionPolicyHelperStub getInstance(
|
||||
String[] restrictedNamespaces, String[] restrictedProperties) {
|
||||
Set<String> namespaceSet = new HashSet<String>();
|
||||
if (restrictedNamespaces != null) {
|
||||
namespaceSet.addAll(Arrays.asList(restrictedNamespaces));
|
||||
}
|
||||
|
||||
Map<FullPropertyKey, RoleLevel> thresholdMap = new HashMap<>();
|
||||
if (restrictedProperties != null) {
|
||||
for (String prop : restrictedProperties) {
|
||||
thresholdMap.put(new FullPropertyKey(prop), RoleLevel.NOBODY);
|
||||
}
|
||||
}
|
||||
|
||||
return new PropertyRestrictionPolicyHelperStub(namespaceSet, null,
|
||||
null, thresholdMap, null);
|
||||
}
|
||||
|
||||
private PropertyRestrictionPolicyHelperStub(
|
||||
Set<String> modifyRestrictedNamespaces,
|
||||
Set<String> modifyPermittedExceptions,
|
||||
Map<FullPropertyKey, RoleLevel> displayThresholds,
|
||||
Map<FullPropertyKey, RoleLevel> modifyThresholds,
|
||||
Map<FullPropertyKey, RoleLevel> publishThresholds) {
|
||||
super(modifyRestrictedNamespaces, modifyPermittedExceptions,
|
||||
displayThresholds, modifyThresholds, publishThresholds);
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
package stubs.edu.cornell.mannlib.vitro.webapp.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -57,6 +58,11 @@ public class DataPropertyDaoStub implements DataPropertyDao {
|
|||
// Stub methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public List<DataProperty> getAllDataProperties() {
|
||||
return new ArrayList<>(dpMap.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataProperty getDataPropertyByURI(String dataPropertyURI) {
|
||||
return dpMap.get(dataPropertyURI);
|
||||
|
@ -189,12 +195,6 @@ public class DataPropertyDaoStub implements DataPropertyDao {
|
|||
"PropertyDao.getClassesWithRestrictionOnProperty() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List getAllDataProperties() {
|
||||
throw new RuntimeException(
|
||||
"DataPropertyDao.getAllDataProperties() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List getAllExternalIdDataProperties() {
|
||||
throw new RuntimeException(
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
package stubs.edu.cornell.mannlib.vitro.webapp.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
public class FauxPropertyDaoStub implements FauxPropertyDao {
|
||||
// ----------------------------------------------------------------------
|
||||
// Stub infrastructure
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private final Map<FullPropertyKey, FauxProperty> props = new HashMap<>();
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Stub methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public FauxProperty getFauxPropertyByUris(String domainUri, String baseUri,
|
||||
String rangeUri) {
|
||||
return props.get(new FullPropertyKey(domainUri, baseUri, rangeUri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FauxProperty> getFauxPropertiesForBaseUri(String uri) {
|
||||
List<FauxProperty> list = new ArrayList<>();
|
||||
for (FauxProperty fp : props.values()) {
|
||||
if (Objects.equals(fp.getBaseURI(), uri)) {
|
||||
list.add(fp);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertFauxProperty(FauxProperty fp) {
|
||||
props.put(new FullPropertyKey(fp), fp);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Un-implemented methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public FauxProperty getFauxPropertyFromContextUri(String contextUri) {
|
||||
throw new RuntimeException(
|
||||
"FauxPropertyDaoStub.getFauxPropertyFromContextUri() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFauxProperty(FauxProperty fp) {
|
||||
throw new RuntimeException(
|
||||
"FauxPropertyDaoStub.updateFauxProperty() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteFauxProperty(FauxProperty fp) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new RuntimeException(
|
||||
"FauxPropertyDaoStub.deleteFauxProperty() not implemented.");
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
package stubs.edu.cornell.mannlib.vitro.webapp.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -40,17 +41,18 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao {
|
|||
|
||||
opMap.put(uri, property);
|
||||
}
|
||||
|
||||
public void setCustomListViewConfigFileName(ObjectProperty property, String filename) {
|
||||
|
||||
public void setCustomListViewConfigFileName(ObjectProperty property,
|
||||
String filename) {
|
||||
if (property == null) {
|
||||
throw new NullPointerException("property may not be null.");
|
||||
}
|
||||
|
||||
|
||||
String uri = property.getURI();
|
||||
if (uri == null) {
|
||||
throw new NullPointerException("uri may not be null.");
|
||||
}
|
||||
|
||||
|
||||
configFilesMap.put(uri, filename);
|
||||
}
|
||||
|
||||
|
@ -58,6 +60,11 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao {
|
|||
// Stub methods
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public List<ObjectProperty> getAllObjectProperties() {
|
||||
return new ArrayList<>(opMap.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectProperty getObjectPropertyByURI(String objectPropertyURI) {
|
||||
if (objectPropertyURI == null) {
|
||||
|
@ -65,18 +72,18 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao {
|
|||
}
|
||||
return opMap.get(objectPropertyURI);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI,
|
||||
String domainURI, String rangeURI) {
|
||||
return getObjectPropertyByURI(objectPropertyURI);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI,
|
||||
String domainURI, String rangeURI, ObjectProperty base) {
|
||||
return getObjectPropertyByURI(objectPropertyURI);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI,
|
||||
String domainURI, String rangeURI) {
|
||||
return getObjectPropertyByURI(objectPropertyURI);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectProperty getObjectPropertyByURIs(String objectPropertyURI,
|
||||
String domainURI, String rangeURI, ObjectProperty base) {
|
||||
return getObjectPropertyByURI(objectPropertyURI);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCustomListViewConfigFileName(ObjectProperty objectProperty) {
|
||||
|
@ -194,12 +201,6 @@ public class ObjectPropertyDaoStub implements ObjectPropertyDao {
|
|||
"ObjectPropertyDaoStub.getClassesWithRestrictionOnProperty() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ObjectProperty> getAllObjectProperties() {
|
||||
throw new RuntimeException(
|
||||
"ObjectPropertyDaoStub.getAllObjectProperties() not implemented.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ObjectProperty> getObjectPropertiesForObjectPropertyStatements(
|
||||
List objectPropertyStatements) {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
package stubs.edu.cornell.mannlib.vitro.webapp.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.ApplicationDao;
|
||||
|
@ -11,6 +10,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao;
|
|||
import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyStatementDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.DisplayModelDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.FauxPropertyDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.MenuDao;
|
||||
import edu.cornell.mannlib.vitro.webapp.dao.ObjectPropertyDao;
|
||||
|
@ -42,6 +42,7 @@ public class WebappDaoFactoryStub implements WebappDaoFactory {
|
|||
private MenuDao menuDao;
|
||||
private ObjectPropertyDao objectPropertyDao;
|
||||
private ObjectPropertyStatementDao objectPropertyStatementDao;
|
||||
private FauxPropertyDao fauxPropertyDao;
|
||||
private OntologyDao ontologyDao;
|
||||
private UserAccountsDao userAccountsDao;
|
||||
private VClassDao vClassDao;
|
||||
|
@ -74,6 +75,10 @@ public class WebappDaoFactoryStub implements WebappDaoFactory {
|
|||
this.objectPropertyStatementDao = objectPropertyStatementDao;
|
||||
}
|
||||
|
||||
public void setFauxPropertyDao(FauxPropertyDao fauxPropertyDao) {
|
||||
this.fauxPropertyDao = fauxPropertyDao;
|
||||
}
|
||||
|
||||
public void setOntologyDao(OntologyDao ontologyDao) {
|
||||
this.ontologyDao = ontologyDao;
|
||||
}
|
||||
|
@ -120,9 +125,15 @@ public class WebappDaoFactoryStub implements WebappDaoFactory {
|
|||
return this.objectPropertyDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FauxPropertyDao getFauxPropertyDao() {
|
||||
return this.fauxPropertyDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectPropertyStatementDao getObjectPropertyStatementDao() {
|
||||
return this.objectPropertyStatementDao; }
|
||||
return this.objectPropertyStatementDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OntologyDao getOntologyDao() {
|
||||
|
|
|
@ -13,9 +13,6 @@ edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSetup
|
|||
|
||||
edu.cornell.mannlib.vitro.webapp.config.ConfigurationPropertiesSmokeTests
|
||||
|
||||
# For the conversion from 1.6 or earlier (RDB) to 1.7 or later (TDB)
|
||||
edu.cornell.mannlib.vitro.webapp.servlet.setup.GuardAgainstUnmigratedRDB
|
||||
|
||||
edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings$Setup
|
||||
|
||||
edu.cornell.mannlib.vitro.webapp.application.ApplicationImpl$ComponentsSetup
|
||||
|
@ -38,6 +35,7 @@ edu.cornell.mannlib.vitro.webapp.application.ApplicationImpl$ReasonersSetup
|
|||
edu.cornell.mannlib.vitro.webapp.servlet.setup.SimpleReasonerSetup
|
||||
|
||||
#edu.cornell.mannlib.vitro.webapp.servlet.setup.UpdateKnowledgeBase
|
||||
edu.cornell.mannlib.vitro.webapp.migration.Release18Migrator
|
||||
|
||||
# Must run after JenaDataSourceSetup
|
||||
edu.cornell.mannlib.vitro.webapp.servlet.setup.ThemeInfoSetup
|
||||
|
@ -46,7 +44,7 @@ edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionRegistry$Setup
|
|||
|
||||
edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSetsSmokeTest
|
||||
|
||||
edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionPolicyHelper$Setup
|
||||
edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean$Setup
|
||||
|
||||
edu.cornell.mannlib.vitro.webapp.auth.policy.setup.CommonPolicyFamilySetup
|
||||
|
||||
|
|
|
@ -762,6 +762,15 @@
|
|||
<url-pattern>/showDataPropertyHierarchy</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>ListFauxPropertiesController</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.ListFauxPropertiesController</servlet-class>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>ListFauxPropertiesController</servlet-name>
|
||||
<url-pattern>/listFauxProperties</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>ListPropertyWebappsController</servlet-name>
|
||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.freemarker.ListPropertyWebappsController</servlet-class>
|
||||
|
|
|
@ -887,4 +887,10 @@ view_labels_for = View Labels for
|
|||
select_an_existing_document = Select an existing document
|
||||
|
||||
datetime_year_required = Date/time intervals must begin with a year. Enter either a Start Year, an End Year or both.
|
||||
select_a_language = Select a language
|
||||
select_a_language = Select a language
|
||||
|
||||
base_property_capitalized = Base Property
|
||||
faux_property_capitalized = Faux Property
|
||||
faux_property_listing = Faux Property Listing
|
||||
faux_property_by_base = faux properties by base property
|
||||
faux_property_alpha = faux properties alphabetically
|
19
webapp/web/js/siteAdmin/fauxPropertiesListingUtils.js
Normal file
19
webapp/web/js/siteAdmin/fauxPropertiesListingUtils.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||
|
||||
var fauxPropertiesListingUtils = {
|
||||
onLoad: function() {
|
||||
this.initObjects();
|
||||
this.bindEventListeners();
|
||||
},
|
||||
|
||||
initObjects: function() {
|
||||
this.select = $('select#displayOption');
|
||||
this.theForm = $('form#fauxListing');
|
||||
},
|
||||
|
||||
bindEventListeners: function() {
|
||||
this.select.change(function() {
|
||||
fauxPropertiesListingUtils.theForm.submit();
|
||||
});
|
||||
}
|
||||
}
|
166
webapp/web/templates/edit/specific/fauxProperty_retry.jsp
Normal file
166
webapp/web/templates/edit/specific/fauxProperty_retry.jsp
Normal file
|
@ -0,0 +1,166 @@
|
|||
<%-- $This file is distributed under the terms of the license in /doc/license.txt$ --%>
|
||||
|
||||
<%@ taglib prefix="form" uri="http://vitro.mannlib.cornell.edu/edit/tags" %>
|
||||
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
|
||||
|
||||
<tr class="editformcell">
|
||||
<td valign="top" colspan="2">
|
||||
<b>Base property</b><br/>
|
||||
<input type="text" class="fullWidthInput" name="Base property" value="<form:value name="BaseLabel"/>" disabled="disabled" /></br>
|
||||
<i>a specification of this property</i></br>
|
||||
</td>
|
||||
<td valign="top" colspan="2">
|
||||
<b>Property group</b><br/>
|
||||
<select name="GroupURI"><form:option name="GroupURI"/></select><br/>
|
||||
<i>for grouping properties on individual pages</i><br/>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="editformcell">
|
||||
<td style="vertical-align:top;" valign="top" colspan="2">
|
||||
<br /><b>Label for public display</b><br/>
|
||||
<input type="text" class="fullWidthInput" name="DisplayName" value="<form:value name="DisplayName"/>" maxlength="80" />
|
||||
<c:set var="DisplayNameError"><form:error name="DisplayName"/></c:set>
|
||||
<c:if test="${!empty DisplayNameError}">
|
||||
<span class="notice"><c:out value="${DisplayNameError}"/></span>
|
||||
</c:if>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td colspan="5"><hr class="formDivider"/></td></tr>
|
||||
|
||||
<tr class="editformcell">
|
||||
<td valign="top" colspan="2">
|
||||
<b>Domain class</b><br />
|
||||
<select name="DomainURI"><form:option name="DomainURI"/></select>
|
||||
</td>
|
||||
<td valign="top" colspan="2">
|
||||
<b>Range class</b><br />
|
||||
<select name="RangeURI" ><form:option name="RangeURI"/></select>
|
||||
<c:set var="RangeURIError"><form:error name="RangeURI"/></c:set>
|
||||
<c:if test="${!empty RangeURIError}">
|
||||
<span class="notice"><c:out value="${RangeURIError}"/></span>
|
||||
</c:if>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td colspan="5"><hr class="formDivider"/></td></tr>
|
||||
|
||||
<tr class="editformcell">
|
||||
<td valign="top" colspan="5">
|
||||
<b>Public Description</b> for front-end users, as it will appear on editing forms<br/>
|
||||
<textarea class="matchingInput" name="PublicDescription"><form:value name="PublicDescription"/></textarea>
|
||||
<c:set var="PublicDescriptionError"><form:error name="PublicDescription"/></c:set>
|
||||
<c:if test="${!empty PublicDescriptionError}">
|
||||
<span class="notice"><c:out value="${PublicDescriptionError}"/></span>
|
||||
</c:if>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td colspan="5"><hr class="formDivider"/></td></tr>
|
||||
|
||||
<tr class="editformcell">
|
||||
<td valign="top" colspan="2">
|
||||
<b>Display level</b><br />
|
||||
<select name="HiddenFromDisplayBelowRoleLevelUsingRoleUri">
|
||||
<form:option name="HiddenFromDisplayBelowRoleLevelUsingRoleUri"/>
|
||||
</select>
|
||||
</td>
|
||||
<td valign="top" colspan="1">
|
||||
<b>Update level</b><br/>
|
||||
<select name="ProhibitedFromUpdateBelowRoleLevelUsingRoleUri">
|
||||
<form:option name="ProhibitedFromUpdateBelowRoleLevelUsingRoleUri"/>
|
||||
</select>
|
||||
</td>
|
||||
<td valign="top" colspan="2">
|
||||
<b>Publish level</b><br />
|
||||
<select name="HiddenFromPublishBelowRoleLevelUsingRoleUri">
|
||||
<form:option name="HiddenFromPublishBelowRoleLevelUsingRoleUri"/>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td colspan="5"><hr class="formDivider"/></td></tr>
|
||||
|
||||
<tr class="editformcell">
|
||||
<td valign="top" colspan="1">
|
||||
<b>Display tier</b> for this property<br/>
|
||||
<input type="text" class="shortInput" name="DisplayTier" value="<form:value name="DisplayTier"/>" /><br/>
|
||||
<i><b>lower</b> numbers display first</i><br/>
|
||||
<c:set var="DisplayTierError"><form:error name="DisplayTier"/></c:set>
|
||||
<c:if test="${!empty DisplayTierError}">
|
||||
<span class="notice"><c:out value="${DisplayTierError}"/></span>
|
||||
</c:if>
|
||||
</td>
|
||||
<td valign="top" colspan="2">
|
||||
<b>Display limit</b> before "more ..." button is displayed<br/>
|
||||
<input type="text" class="shortInput" name="DisplayLimit" value="<form:value name="DisplayLimit"/>"/>
|
||||
<c:set var="DisplayLimitError"><form:error name="DisplayLimit"/></c:set>
|
||||
<c:if test="${!empty DisplayLimitError}">
|
||||
<span class="notice"><c:out value="${DisplayLimitError}"/></span>
|
||||
</c:if>
|
||||
</td>
|
||||
<td valign="top" colspan="2">
|
||||
When displaying related individuals from different classes,<br/>
|
||||
<c:choose>
|
||||
<c:when test="${collateBySubclass}">
|
||||
<input name="CollateBySubclass" type="checkbox" value="TRUE" checked="checked"/>collate by subclass
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<input name="CollateBySubclass" type="checkbox" value="TRUE"/>collate by subclass
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td colspan="5"><hr class="formDivider"/></td></tr>
|
||||
|
||||
<tr class="editformcell">
|
||||
<td valign="top" colspan="2">
|
||||
Select related individuals from existing choices?<br/>
|
||||
<c:choose>
|
||||
<c:when test="${selectFromExisting}">
|
||||
<input name="SelectFromExisting" type="checkbox" value="TRUE" checked="checked"/>provide selection
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<input name="SelectFromExisting" type="checkbox" value="TRUE"/>provide selection
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</td>
|
||||
<td valign="top" colspan="1">
|
||||
Allow creating new related individuals?<br/>
|
||||
<c:choose>
|
||||
<c:when test="${offerCreateNewOption}">
|
||||
<input name="OfferCreateNewOption" type="checkbox" value="TRUE" checked="checked"/>offer create option
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<input name="OfferCreateNewOption" type="checkbox" value="TRUE"/>offer create option
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td colspan="5"><hr class="formDivider"/></td></tr>
|
||||
|
||||
<tr class="editformcell">
|
||||
<td valign="top" colspan="5">
|
||||
<b>Custom entry form</b><br/>
|
||||
<input type="text" class="fullWidthInput" name="CustomEntryForm" value="<form:value name="CustomEntryForm"/>" />
|
||||
<c:set var="CustomEntryFormError"><form:error name="CustomEntryForm"/></c:set>
|
||||
<c:if test="${!empty CustomEntryFormError}">
|
||||
<span class="notice"><c:out value="${CustomEntryFormError}"/></span>
|
||||
</c:if>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="editformcell">
|
||||
<td valign="top" colspan="5">
|
||||
<b>Custom list view</b><br/>
|
||||
<input type="text" class="fullWidthInput" name="CustomListView" value="<form:value name="CustomListView"/>" />
|
||||
<c:set var="CustomListViewError"><form:error name="CustomListView"/></c:set>
|
||||
<c:if test="${!empty CustomListViewError}">
|
||||
<span class="notice"><c:out value="${CustomListViewError}"/></span>
|
||||
</c:if>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td colspan="5"><hr class="formDivider"/></td></tr>
|
|
@ -18,7 +18,7 @@
|
|||
<tr><td colspan="5"><hr class="formDivider"/></td></tr>
|
||||
<tr class="editformcell">
|
||||
<td style="vertical-align:top;" valign="top" colspan="1">
|
||||
<b>Ontology</b><br/><br/>
|
||||
<b>Ontology</b><br/>
|
||||
<c:choose>
|
||||
<c:when test="${_action eq 'update'}">
|
||||
<select name="Namespace" disabled="disabled"><form:option name="Namespace"/></select><br/>
|
||||
|
@ -30,8 +30,7 @@
|
|||
</c:choose>
|
||||
</td>
|
||||
<td style="vertical-align:top;" valign="top" colspan="2">
|
||||
<b>Internal name*</b><br/>
|
||||
(RDF local name)<br/>
|
||||
<b>Internal name*</b> (RDF local name)<br/>
|
||||
<c:choose>
|
||||
<c:when test="${_action eq 'update'}">
|
||||
<input type="text" class="fullWidthInput" disabled="disabled" name="LocalName" value="<form:value name='LocalName'/>" /><br/>
|
||||
|
@ -49,7 +48,7 @@
|
|||
</c:if>
|
||||
</td>
|
||||
<td style="vertical-align:top;" valign="top" colspan="2">
|
||||
<b>Label for public display</b><br/><br/>
|
||||
<b>Label for public display</b><br/>
|
||||
<input type="text" class="fullWidthInput" name="DomainPublic" value="<form:value name="DomainPublic"/>" maxlength="80" />
|
||||
<c:set var="DomainPublicError"><form:error name="DomainPublic"/></c:set>
|
||||
<c:if test="${!empty DomainPublicError}">
|
||||
|
|
|
@ -91,6 +91,53 @@
|
|||
</td>
|
||||
</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="${property.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="${property.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="${property.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>
|
||||
<!-- _____________________________________________ superproperties __________________________________________ -->
|
||||
<tr valign="bottom" align="center">
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||
|
||||
<#--
|
||||
Used to display both the object and data property hierarchies, though there are
|
||||
separate controllers for those. Also used to display lists of "all" object and
|
||||
data properties, though there are separate controllers for those, too.
|
||||
-->
|
||||
<#if propertyType??>
|
||||
<#assign propType = propertyType>
|
||||
<#else>
|
||||
<#assign propType = "group">
|
||||
</#if>
|
||||
|
||||
|
||||
<section role="region">
|
||||
<h2>${pageTitle!}</h2>
|
||||
<#if message?has_content>
|
||||
<p>${message}</p>
|
||||
<#else>
|
||||
<#if !displayOption?has_content>
|
||||
<#assign displayOption = "listing">
|
||||
</#if>
|
||||
<form name="fauxListingForm" id="fauxListing" action="listFauxProperties" method="post" role="classHierarchy">
|
||||
<label id="displayOptionLabel" class="inline">${i18n().display_options}</label>
|
||||
<select id="displayOption" name="displayOption">
|
||||
<option value="listing" <#if displayOption == "listing">selected</#if> >faux properties alphabetically</option>
|
||||
<option value="byBase" <#if displayOption == "byBase">selected</#if> >faux properties by base property</option>
|
||||
</select>
|
||||
</form>
|
||||
<section id="container" style="margin-top:10px">
|
||||
<#if displayOption == "listing" >
|
||||
<#assign keys = fauxProps?keys/>
|
||||
<#list keys as key>
|
||||
<#assign ks = fauxProps[key] />
|
||||
<section id="classContainer1">
|
||||
<div>
|
||||
<a href='editForm?controller=FauxProperty&baseUri=${ks["baseURI"]?url!}&<#if ks["domainURI"]?has_content>domainUri=${ks["domainURI"]?url}&</#if>rangeUri=${ks["rangeURI"]?url!}'>${key?substring(0,key?index_of("@@"))}</a>
|
||||
</div>
|
||||
<table id="classHierarchy1" class="classHierarchy">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="classDetail">${i18n().base_property_capitalized}:</td>
|
||||
<td><a href='propertyEdit?uri=${ks["baseURI"]?url!}'>${ks["base"]!}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="classDetail">${i18n().group_capitalized}:</td>
|
||||
<td>${ks["group"]?capitalize}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="classDetail">${i18n().domain_class}:</td>
|
||||
<td>
|
||||
${ks["domain"]!}
|
||||
<span class="rangeClass">${i18n().range_class}:</span>
|
||||
${ks["range"]!}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
</#list>
|
||||
<#else>
|
||||
<#assign keys = fauxProps?keys />
|
||||
<#list keys as key>
|
||||
<#assign fauxList = fauxProps[key] />
|
||||
<section id="classContainer1">
|
||||
<#assign baseLabel = key?substring(0,key?index_of("|")) />
|
||||
<#assign baseUri = key?substring(key?index_of("|")+1) />
|
||||
<div>
|
||||
<a href='propertyEdit?uri=${baseUri?url}'>${baseLabel}</a>
|
||||
</div>
|
||||
<#assign keysTwo = fauxList?keys />
|
||||
<#assign firstLoop = true />
|
||||
<#list keysTwo as k2>
|
||||
<#assign faux = fauxList[k2] />
|
||||
<table id="classHierarchy1" class="classHierarchy" <#if !firstLoop >style="margin-top:-16px"</#if>>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="classDetail">${i18n().faux_property_capitalized}:</td>
|
||||
<td><a href='editForm?controller=FauxProperty&baseUri=${faux["baseURI"]?url!}&<#if faux["domainURI"]?has_content>domainUri=${faux["domainURI"]?url}&</#if>rangeUri=${faux["rangeURI"]?url!}'>${k2?substring(0,k2?index_of("@@"))}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="classDetail">${i18n().group_capitalized}:</td>
|
||||
<td>${faux["group"]?capitalize}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="classDetail">${i18n().domain_class}:</td>
|
||||
<td>
|
||||
${faux["domain"]!}
|
||||
<span class="rangeClass">${i18n().range_class}:</span>
|
||||
${faux["range"]!}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<#assign firstLoop = false />
|
||||
</#list>
|
||||
</section>
|
||||
</#list>
|
||||
</#if>
|
||||
</section>
|
||||
</#if>
|
||||
</section>
|
||||
|
||||
<script language="javascript" type="text/javascript" >
|
||||
var i18nStrings = {
|
||||
'',
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<script language="javascript" type="text/javascript" >
|
||||
$(document).ready(function() {
|
||||
fauxPropertiesListingUtils.onLoad();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/css/classHierarchy.css" />')}
|
||||
|
||||
${scripts.add('<script type="text/javascript" src="${urls.base}/js/jquery-ui/js/jquery-ui-1.8.9.custom.min.js"></script>',
|
||||
'<script type="text/javascript" src="${urls.base}/js/siteAdmin/fauxPropertiesListingUtils.js"></script>')}
|
||||
|
|
@ -33,6 +33,7 @@
|
|||
<ul role="navigation">
|
||||
<li role="listitem"><a href="${ontologyEditor.urls.objectPropertyHierarchy}" title="${i18n().object_property_hierarchy}">${i18n().object_property_hierarchy}</a></li>
|
||||
<li role="listitem"><a href="${ontologyEditor.urls.dataPropertyHierarchy}" title="${i18n().data_property_hierarchy}">${i18n().data_property_hierarchy}</a></li>
|
||||
<li role="listitem"><a href="${ontologyEditor.urls.fauxPropertyList}" title="${i18n().data_property_hierarchy}">${i18n().faux_property_listing}</a></li>
|
||||
<li role="listitem"><a href="${ontologyEditor.urls.propertyGroups}" title="${i18n().property_groups}">${i18n().property_groups}</a></li>
|
||||
</ul>
|
||||
|
||||
|
|
|
@ -231,14 +231,16 @@ 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>
|
||||
is a faux property of
|
||||
</#if>
|
||||
<a class="propertyLink" href="${verboseDisplay.propertyEditUrl}" title="${i18n().name}">${verboseDisplay.localName}</a>
|
||||
(<span>${property.type?lower_case}</span> property);
|
||||
order in group: <span>${verboseDisplay.displayRank};</span>
|
||||
display level: <span>${verboseDisplay.displayLevel};</span>
|
||||
update level: <span>${verboseDisplay.updateLevel};</span>
|
||||
order in group: <span>${verboseDisplay.displayRank}</span>;
|
||||
display level: <span>${verboseDisplay.displayLevel}</span>;
|
||||
update level: <span>${verboseDisplay.updateLevel}</span>;
|
||||
publish level: <span>${verboseDisplay.publishLevel}</span>
|
||||
</section>
|
||||
</#if>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue